Catatan Belajar Django PART 3: Templates
Saat membuat website pada umumnya selain sistem yang berjalan diperlukan juga tampilan untuk user interfacenya. Di Django ini jadi tanggung jawab templates. Pada dasarnya django secara default memasang templates di direcotry app, jadi struktur app nya seperti berikut
├── admin.py ├── apps.py ├── forms.py ├── __init__.py ├── migrations ├── models.py ├── templates │ └── index.html ├── tests.py ├── urls.py └── views.py
Tapi beberapa orang (termasuk saya) lebih menyukai dibuat sentralisasi untuk templates, apalagi kalau konteknya emang 1 projek keseluruhan, mungkin jika membuat module lebih baik di app, tapi kalau kesatuan projek saya lebih suka dengan sentralisasi
Untuk sentralisasi template saya pernah menulisnya di tulisan berikut [link] tulisan di bawah ini berfokus kepada penggunaan template.
Saya sendiri menggunakan yang sentralisasi templates.
Render
Jika di tulisan sebelumnya hasil dari views langsung dimunculkan sebagai http response, di tulisan ini memperlihatkan bagaiman dari views masuk ke template, buka kode yang kemarin lalu ubah menjadi seperti berikut:
from django.http import HttpResponse from django.shortcuts import render #tambahkan ini from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_http_methods @csrf_exempt @require_http_methods(["GET", "POST"]) def hello_world(request): if request.method == "GET": return render(request, "index.html") #dari httpresponse menjadi render else: return HttpResponse("Insert Hello world")
Lalu isi index.html seperti berikut
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> Halo from template </body> </html>
Sehingga saat akes url tujuan menampilkan sebagai berikut
Halo from template
Passing parameter & Django Template Engine
Hanya menampilkan html tentu tidak berguna karena akan sulit untuk mendapatkan nilai dinamis, untuk menampilkan tampilan dinamis kita bisa mengirimkan nilai dari views ke template dan nanti akan dimunculan dengan django template
Ubah views menjadi seperti berikut:
def hello_world(request): if request.method == "GET": context = {"hello": "hello from views"} #siapkan dictionary return render(request, "index.html", context) #masukan dictionary sebagai parameter tambahan else: return HttpResponse("Insert Hello world")
dan templates menjadi
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> {{ hello }} </body> </html>
Maka saat diakses akan memunculkan “hello from views”.
Untuk print out variable yang dikirimkan menggunakan double kurung kurawan buka `{{` dan double kurung kurawal tutup `}}`
Django template juga tidak hanya untuk printout, untuk proses seperti looping dan conditional juga bisa
Conditional & Looping
Tambahkan dulu kode views menjadi seperti berikut
def hello_world(request): if request.method == "GET": context = { "hello": "hello from views", "groups": ["SHP", "Heart", "Kid"], "age": 25, } return render(request, "index.html", context) else: return HttpResponse("Insert Hello world")
dan template seperti ini
# conditional <hr> {% if age > 25 %} Dewasa {% elif age >= 17 and age < 24 %} Remaja {% else %} Anak-anak {% endif %} # looping <hr> Loop: <hr> <ul> {% for g in groups %} <li> {{ g }}</li> {% endfor %} </ul>
Perintah di atas akan memunculkan list yang ditampilkan dengan tag `<li>`
Kalau diperhatikan ada yang berbeda
untuk printout : `{{ }}`
untuk “fungsi”: `{% %}`
Link and url name
Salah satu yang paling sering digunakan di website adalah link, dan link ini digunakan dari mulai tombol sampai dengan form, basic html seperti berikut
<a href="http://localhost:8000/front/2">ke menu 2</a>
Itu akan menuju ke halaman yang dituju, tapi gak enak kalau harus nulis lengkap, dan dan bisa saja suatu hari nanti alamat webnya bisa berubah asalanya `front/2` jadi `depan/2` misalnya. Akan ribet mengganti target href satu persatu, di sini kita bisa menggunakan name di url
Buka dulu `blog/urls.py` dan ubah sebagai berikut
urlpatterns = [ path("", views.hello_world, name="home"), path("<str:name>", views.hello_segment, name="detail-home"), ]
lalu di template kita bisa gunakan
<a href="{% url "home" %}">ke Depan</a> #ini akan menghasilkan http://localhost:8000/front/ <a href="{% url "detail-home" 2 %}">ke Detail</a> #ini akan meghasilkan http://localhost:8000/front/2
URL Namespace
Di contoh di atas hanya ada app blog, di banyak projek django terdiri banyak app, dan bisa saja di app itu name url nya bisa sama, misal home disitulah fungsinya namespace
ubah `blog/urls.py`
app_name = "blog" urlpatterns = [ path("", views.hello_world, name="home"), path("<str:name>", views.hello_segment, name="detail-home"), ]
Lalu cara manggilnya
<a href="{% url "blog:home" %}">ke Depan</a> <a href="{% url "blog:detail-home" 2 %}">ke Detail</a>
Layout, Page, dan Komponen
Sebenarnya itu istilah favorit saya sih, seringkali saya ketika membuat struktur folder template selalu menerapkan 3 folder tersebut
Layout: Untuk base template, misal layout login, layout dashboard, layout front end
Pages: Untuk lokasi halaman yang ditentukan, biasanya ini menempel ke layout tertentu
Komponen: Lebih bebas, misal bisa saja kita punya komponen table, bisa saja table yang sama kita munculkan baik di dashboard atau di frontend
Mari buat contoh sederhana
Saya akan buat 2 layout (layouts/first.html, layouts/second.html) dan dua halaman yang terikat ke masing-masing layout (pages/page_first.html, pages/page_second.html) dan satu komponen list (components/list.html) yang muncul di dua halaman tadi
struktur templates
├── components │ └── list.html ├── index.html ├── layouts │ ├── first.html │ └── second.html └── pages ├── page_first.html └── page_second.html
Ada dua layout
Layout satu: layout/first.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=<device-width>, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>Ini Layout nomor 1</h1> {% block content %}{% endblock %} </body> </html> Layout dua: layout/second.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=<device-width>, initial-scale=1.0"> <title>Document</title> </head> <body style="background: blue;"> <h1>Ini Layout nomor 2</h1> {% block content %}{% endblock %} </body> </html>
Untuk page
pages/page_first ```html {% extends 'layouts/first.html' %} {% block content %} {% include "components/list.html" with data=categories %} {% endblock %} ``` pages/page_second ```html {% extends 'layouts/second.html' %} {% block content %} {% include "components/list.html" with data=categories %} {% endblock %} ```
Komponen
component/list ```html <ul> {% for d in data %} <li> {{ d.name }}</li> {% endfor %} </ul>
Dan urls
urls from django.urls import path from . import views app_name = "blog" urlpatterns = [ path("layout", views.layout_satu, name="layout"), path("layout2", views.layout_dua, name="layout2"), ] views def layout_satu(request): categories = Category.objects.all() context = {"categories": categories} return render(request, "pages/page_first.html", context) def layout_dua(request): categories = Category.objects.all() context = {"categories": categories} return render(request, "pages/page_second.html", context)
hasilnya
Jika diperhatikan di atas ada 3 template tag yang berperan penting:
extends: untuk menentukan layout yang digunakan
blocks: untuk menandakan lokasi render
includes: untuk memasukan halaman
Tulisan terkait template sepertinya cukup sampai sini, terima kasih.