5 min read

Django 3 Template dan Layout

Django 3 Template dan Layout

Setahu saya ada dua pendeketan terkait pembuatan template/layout di Django, pada directory “app” atau di level “projek”, di tulisan ini saya berfokus pada pendekatan di level projek. Ada beberapa tahap yang saya bagi seperti berikut:

  1. struktur folder
  2. helllo world
  3. asset dan static files
  4. extending layout

Saya menggunakan Django versi 3

python -m django –version
3.1.1

Struktur Folder

Ini merupakan struktur dari fresh install django dan fress intall app, tanpa menambahkan satu baris kode apapun.

project
    ├── db.sqlite3
    ├── project
    │   ├── asgi.py
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── manage.py
    ├── myapp
    │   ├── admin.py
    │   ├── apps.py
    │   ├── __init__.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py

Selanjutnya saya menambahkan folder “templates” sejajar dengan projek maupun app

├── project
├── myapp
└── templates

Tambahkan index.html (atau apapun nama yang diinginkan) di dalam folder templates seperti berikut

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
    <title>Document</title>
    <style>


html, body {
    background-color: #fff;
    color: #636b6f;
    font-family: 'Nunito', sans-serif;
    font-weight: 200;
    height: 100vh;
    margin: 0;
}

.center {
    align-items: center;
    display: flex;
    justify-content: center;
}

.content {
    text-align: center;
}

    </style>
</head>
<body>
    <div class="center">
        <div class="content">
            <h1>Hello World</h1>
        </div>
    </div>
</body>
</html>

Persiapan template sudah, saatnya daftarkan lokasi template yang tadi dibuat agar django tahu template mana yang akan digunakan. Buka “project/settings.py“, cari “TEMPLATES” dan tambahkan seperti berikut

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'], #tambahkan ini
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Selesai.

 

Hello World

Setelah struktur tersedia dan telah didaftarkan, sekarang di bagian kedua adalah berfikus untuk menampilkan html yang telah tadi dibuat. Skenarionya seperti berikut, saat mengunjungi alamat “localhost:8000/halo” makan akan menampilkan index.html tadi.

Buka “myapp/views.py” lalu isikan seperti berikut

from django.shortcuts import render

# Create your views here.
def hello_world(request):
    return render(request, 'index.html')

Buat berkas baru bernama “urls.py” di dalam folder “myapp” dan tambahkan kode berikut di dalamnya

from django.urls import path

from . import views

urlpatterns = [
    path('halo', views.hello_world)
]

Daftarkan app “myapp” ke dalam “settings.py” yang tadi

INSTALLED_APPS = [
    ... other app
    "myapp"
]

Juga daftark “url” yang ada di “myapp” kedalam url di “project/urls.py”

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('myapp.urls'))
]

Sekarang jika saya akses “localhost:8000/halo” maka akan menampilkan seperti berikut:

Passing parameter

Setelah berhasil menampilkan halaman berikutnya adalah membuat tampilan dinamis, karena pada umumnya konten dalam website bersifat dinamis bukan hardcode di htmlnya. Dalam konteks django, data yang ditampilkan adalah data yang dikirim dari “views.py”, oleh karena itu ubah dulu “myapp/views.py” yang tadi sudah dibuat.

def hello_world(request):
    content = {"body":"Hello World"}
    return render(request, 'index.html', content)

Setelah itu ubah di “index.html” seperti berikut:

<body>
    <div class="center">
        <div class="content">
            <h1>{{ body }}</h1>
        </div>
    </div>
</body>

Kalau diakses kembali tidak akan terlihat perubahan apapun dari depan, yang mebedakan adalah sekarang tulisan “Hello World” bukan lagi dari template tapi sudah dikirim dari views.

Aset dan Static files

Jika diperhatikan, di dalam “index.html” saya mengunakan inline css, tidak salah, tapi pada umumnya dalam sebuah tampilan nantinya akan dibuthkan banyak aset css, javascript dan lainnya. Pada bagian ini saya akan memisahkan inline css tadi menjadi berkas baru bernama “style.css”, dan pastikan django tahu harus mencari kemana asset yang akan digunakan.

Pertama, buat folder sejajar dengan “templates” dan beri nama “static”

project
├── project
├── myapp
├── static
└── templates

Agar lebih rapi, buat lagi folder “css” di dalam “static” dan tambahkan “style.css”

static
└── css
    └── style.css

Pindahkan inline CSS ke dalam style.css

html, body {
    background-color: #fff;
    color: #636b6f;
    font-family: 'Nunito', sans-serif;
    font-weight: 200;
    height: 100vh;
    margin: 0;
}

.center {
    align-items: center;
    display: flex;
    justify-content: center;
}

.content {
    text-align: center;
}

Daftarkan lokasi folder static di “project/settings.py”

STATICFILES_DIRS = [
    BASE_DIR / "static",
]

Daftarkan juga di “projects/urls.py”

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('myapp.urls'))
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

Ubah kembali “index.html” menjadi

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    {% load static %}
    <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
    <link rel="stylesheet" href="{% static "css/style.css" %}" >
    <title>Document</title>
</head>
<body>
    <div class="center">
        <div class="content">
            <h1>{{ body }}</h1>
        </div>
    </div>
</body>
</html>

Kembali akses “localhost:8000/halo”, sekali lagi tidak ada perubahan tapi sekarang halaman ini style nya merujuk kepada “style.css”

Extending layout

Umumnya sebuah halaman website terdiri dari beberapa segmen, seperti header, content, dan footer. Header dan footer umunya bersifat statis, sedangkan content cenderung dinamis. Bagaimana jika kita ingin menampilkan halaman berbeda tapi struktur halamannya sama? Perlukah kita membuat satu berkas lagi misal “another-page.html” dengan struktur dari atas sampai bawah sama? jawabanya bisa iya bisa tidak. Iya, karena dengan cara seperti itu tujuan akan tetap tercapai, dan jawaban tidak juga tepat, karena tidak terlalu efektif. Bayangkan jika kita punya 300 halaman dan masing-masing berkas sama strukturnya dari atas sampai bawah dan tiba-tiba salah satu bagian ada yang diubah maka harus ubah 300 berkas? Maka dari gunakan layout, sehingga untuk struktur yang relatif statis kita bisa pasang di layout, dan yang dinamis tetap di konten.

Pertama buat dulu berkas layout.html di dalam folder “templates”

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    {% load static %}
    <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
    <link rel="stylesheet" href="{% static "css/style.css" %}" >
    <title>Document</title>
</head>
<body>
    <div class="center">
        <div class="content">
            {% block content %}
            {% endblock %}
        </div>
    </div>
</body>
</html>

lalu “index.html” ubah menjadi

{% extends "layout.html" %}

 {% block content %}
     <h1>{{ body }}</h1>
 {% endblock %}

Kembali akses “localhost:8000/halo” dan hasilnya masih akan sama.

 

Referensi:

https://docs.djangoproject.com/en/3.1/howto/static-files/

https://docs.djangoproject.com/en/3.1/topics/templates/

https://docs.djangoproject.com/en/3.1/howto/overriding-templates/