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:
- struktur folder
- helllo world
- asset dan static files
- 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/