Traffine I/O

Bahasa Indonesia

2023-03-10

Mesin Templating Jinja dalam Python

Apa Itu Jinja

Jinja adalah mesin templating populer untuk Python, banyak digunakan untuk menghasilkan halaman web dinamis, HTML, XML, dan bahasa markup lainnya.

Ini terinspirasi oleh sistem templating Django, dan menyediakan cara yang cepat dan efisien untuk memisahkan lapisan presentasi dari lapisan logika bisnis aplikasi web Anda. Dengan fitur-fiturnya yang kuat seperti inheritance template, macros, filter, dan kontrol loop, Jinja memungkinkan pengembang untuk membuat template kompleks dan dinamis dengan mudah.

Cara Menggunakan Jinja

Mengatur Jinja di Python adalah proses sederhana yang melibatkan instalasi paket Jinja dan membuat file template. Berikut adalah contoh cara mengatur Jinja di Python:

  1. Pasang paket Jinja menggunakan pip
bash
$ pip install jinja2
  1. Buat file template bernama template.html dengan konten sebagai berikut
template.html
<!DOCTYPE html>
<html>
<head>
	<title>{{ title }}</title>
</head>
<body>
	<h1>{{ heading }}</h1>
	<ul>
	{% for item in items %}
		<li>{{ item }}</li>
	{% endfor %}
	</ul>
</body>
</html>
  1. Dalam skrip Python Anda, impor modul jinja2 dan muat file template
python
from jinja2 import Template, FileSystemLoader, Environment

env = Environment(loader=FileSystemLoader('.'))
template = env.get_template('template.html')
  1. Tentukan variabel yang akan digunakan dalam template
python
title = 'My Template'
heading = 'Welcome to my template'
items = ['item 1', 'item 2', 'item 3']
  1. Render template dengan variabel yang telah didefinisikan.
python
output = template.render(title=title, heading=heading, items=items)
print(output)

Ini akan menghasilkan kode HTML yang sudah di-render dengan variabel-variabel yang telah ditentukan dimasukkan ke dalam template. Anda juga bisa menuliskan output ke dalam sebuah file atau melewatinya ke sebuah kerangka kerja web untuk ditampilkan di sebuah halaman web.

<!DOCTYPE html>
<html>
  <head>
    <title>My Template</title>
  </head>
  <body>
    <h1>Welcome to my template</h1>
    <ul>
      <li>item 1</li>
      <li>item 2</li>
      <li>item 3</li>
    </ul>
  </body>
</html>

Sintaks Jinja

Salah satu keuntungan utama dari Jinja adalah sintaksnya yang mudah digunakan, yang memungkinkan Anda untuk membuat template yang mudah dibaca dan dipahami.

Variabel

Salah satu fitur paling umum dalam Jinja adalah kemampuan untuk memasukkan data dinamis ke dalam sebuah template menggunakan variabel. Variabel didefinisikan menggunakan kurung kurawal ganda {{ nama_variabel }}. Misalnya, jika Anda memiliki variabel bernama nama dengan nilai John, Anda dapat memasukkannya ke dalam sebuah template seperti ini:

html
<p>My name is {{ nama }}.</p>

Loops

Fitur lain dari Jinja yang sangat berguna adalah kemampuan untuk melakukan loop pada struktur data seperti list dan dictionary. Ini sangat berguna ketika Anda perlu menghasilkan markup yang repetitif atau mengulang data. Sintaks untuk loop adalah {% for item in list %} ... {% endfor %}. Misalnya, jika Anda memiliki sebuah list nama, Anda dapat melakukan loop seperti ini:

html
<ul>
  {% for name in names %}
    <li>{{ name }}</li>
  {% endfor %}
</ul>

Variabel Khusus Loop

Dalam Jinja, loop memungkinkan Anda untuk mengulangi sebuah kumpulan item dan melakukan tindakan pada setiap item. Saat mengulang, Jinja menyediakan variabel spesifik yang memberi Anda lebih banyak kendali atas loop dan memungkinkan Anda mengakses informasi spesifik tentang pengulangan. Berikut adalah daftar variabel khusus loop di Jinja:

Variabel Deskripsi
loop.index Variabel ini mewakili indeks iterasi saat ini, dimulai dari 1.
loop.index0 Variabel ini mewakili indeks iterasi saat ini, dimulai dari 0.
loop.revindex Variabel ini mewakili jumlah iterasi dari akhir, dimulai dari 1.
loop.revindex0 Variabel ini mewakili jumlah iterasi dari akhir, dimulai dari 0.
loop.first Variabel ini adalah boolean yang bernilai True pada iterasi pertama dan False pada iterasi selanjutnya.
loop.last Variabel ini adalah boolean yang bernilai True pada iterasi terakhir dan False pada iterasi sebelumnya.
loop.length Variabel ini mewakili jumlah total iterasi.

Berikut adalah contoh yang menunjukkan penggunaan variabel ini dalam Jinja:

html
<ul>
{% for item in items %}
    <li>{{ loop.index }}. {{ item }}</li>
{% endfor %}
</ul>

Dalam contoh ini, kita mengulang koleksi items dan menampilkan setiap item dalam daftar tidak berurutan (<ul>). Kita menggunakan variabel loop.index untuk menampilkan indeks iterasi bersama dengan setiap item.

Jinja juga memungkinkan Anda untuk mengulang di atas daftar kamus menggunakan filter dictsort. Berikut adalah contoh yang menunjukkan hal ini:

html
<ul>
{% for item in items|dictsort(attribute='name') %}
    <li>{{ item.name }} ({{ item.price }})</li>
{% endfor %}
</ul>

Dalam contoh ini, kita mengulang di atas daftar kamus yang berisi kunci name dan price. Kita menggunakan filter dictsort untuk mengurutkan daftar berdasarkan atribut name sebelum mengulanginya. Di dalam loop, kita menggunakan sintaks item.name dan item.price untuk mengakses nilai setiap kamus.

Kondisi

Jinja juga mendukung pernyataan kondisional, yang memungkinkan Anda untuk menampilkan atau menyembunyikan markup berdasarkan kondisi tertentu. Sintaks untuk pernyataan kondisional adalah {% if kondisi %} ... {% endif %}. Misalnya, jika Anda memiliki variabel yang disebut is_logged_in yang menunjukkan apakah pengguna masuk atau tidak, Anda dapat menampilkan konten yang berbeda berdasarkan nilainya:

html
{% if is_logged_in %}
  <p>Welcome back!</p>
{% else %}
  <p>Please log in to continue.</p>
{% endif %}

Fitur Jinja yang Advanced

Selain fitur sintaks dasarnya, Jinja juga menawarkan fitur-fitur canggih seperti macros dan pewarisan template yang dapat lebih meningkatkan fleksibilitas dan efisiensi dari template Anda.

Macros

Salah satu fitur canggihnya adalah kemampuan untuk mendefinisikan potongan kode yang dapat digunakan kembali, yang disebut macros. Macros mirip dengan fungsi dalam bahasa pemrograman, dan mereka memungkinkan Anda untuk menyederhanakan dan mengorganisir template Anda dengan mengelompokkan kode yang sering digunakan.

Untuk mendefinisikan sebuah macro di Jinja, Anda dapat menggunakan tag {% macro %}. Berikut contohnya:

{% macro greeting(name) %}
    Hello, {{ name }}!
{% endmacro %}

Macro ini bernama greeting dan menerima satu argumen, yaitu name. Ini mengembalikan pesan sapaan sederhana dengan menggunakan sintaks {{ name }} untuk menghasilkan nilai dari variabel name.

Untuk menggunakan macro greeting pada template Anda, Anda dapat memanggilnya dengan tag {% call %}, seperti ini:

{% call greeting('Alice') %}
{% endcall %}

Ini akan menghasilkan keluaran berikut:

Hello, Alice!

Anda juga dapat mengirimkan sebuah variabel ke dalam macro, seperti ini:

{% set my_name = 'Bob' %}
{% call greeting(my_name) %}
{% endcall %}

Ini akan menghasilkan keluaran berikut:

Hello, Bob!

Dengan mendefinisikan macro dalam Jinja, Anda dapat menghindari pengulangan kode yang sama di seluruh templat Anda, sehingga membuat mereka lebih modular dan mudah dipelihara.

Warisan Templat

Warisan Templat adalah fitur yang sangat berguna dalam Jinja yang memungkinkan Anda untuk mengulang elemen-elemen umum dari sebuah templat di seluruh halaman. Dengan Warisan Templat, Anda dapat menentukan sebuah templat dasar yang berisi elemen-elemen umum dari situs Anda, seperti header, footer, dan menu navigasi. Anda kemudian dapat membuat templat anak yang mewarisi dari templat dasar tersebut dan menambahkan konten mereka sendiri.

Untuk menentukan sebuah templat dasar dalam Jinja, Anda perlu menggunakan tag {% block %} untuk menentukan blok-blok konten yang dapat diganti oleh templat anak. Berikut adalah contoh sederhana dari sebuah templat dasar:

html
<!DOCTYPE html>
<html>
  <head>
    <title>{% block title %}Default Title{% endblock %}</title>
  </head>
  <body>
    <header>
      {% block header %}
      <nav>
        <ul>
          <li><a href="#">Home</a></li>
          <li><a href="#">About</a></li>
          <li><a href="#">Contact</a></li>
        </ul>
      </nav>
      {% endblock %}
    </header>
    <main>
      {% block content %}{% endblock %}
    </main>
    <footer>
      {% block footer %}
      &copy; 2023 My Site
      {% endblock %}
    </footer>
  </body>
</html>

Pada contoh ini, tag {% block %} mendefinisikan tiga blok konten: title, header, dan footer. Konten dari blok-blok ini dapat ditimpa oleh template anak.

Untuk membuat template anak yang mewarisi dari template dasar, Anda perlu menggunakan tag {% extends %} untuk menentukan nama template dasar, dan kemudian menggunakan tag {% block %} untuk menimpa konten blok. Berikut adalah contoh template anak yang menimpa blok title dan content:

html
{% extends "base.html" %}

{% block title %}My Page Title{% endblock %}

{% block content %}
<h1>Welcome to my page!</h1>
<p>This is some content for my page.</p>
{% endblock %}

Pada contoh ini, tag {% extends %} menentukan bahwa template anak harus mewarisi dari template base.html. Tag {% block %} kemudian menimpa blok title dan content yang didefinisikan pada template dasar.

Ketika Anda merender template anak, Jinja secara otomatis menggunakan template dasar sebagai titik awal dan menyisipkan konten dari blok yang ditimpa. HTML yang dihasilkan akan berisi elemen-elemen umum dari situs yang didefinisikan pada template dasar, serta konten spesifik dari template anak.

SQL dengan Jinja

Berikut adalah contoh-contoh penulisan SQL dengan menggunakan Jinja.

INSERT

Berikut adalah contoh penggunaan Jinja untuk menghasilkan pernyataan SQL insert dengan jumlah baris dan kolom yang sembarang di Python:

python
import jinja2

# define your data
data = [
    ['Alice', 25, 'Female'],
    ['Bob', 30, 'Male'],
    ['Charlie', 40, 'Male'],
]

# define the template
template = """
INSERT INTO my_table (name, age, gender)
VALUES
{% for row in data %}
    (
    {% for col in row %}
        {% if col is string %}
        '{{ col }}' {% if not loop.last %},{% endif %}
        {% else %}
        {{ col }} {% if not loop.last %},{% endif %}
        {% endif %}
    {% endfor %}
    ) {% if not loop.last %},{% endif %}
{% endfor %}
"""

# compile the template
template = jinja2.Template(template)

# render the SQL statement with the data
sql_statement = template.render(data=data)

print(sql_statement)

Pada contoh ini, pertama-tama kita mendefinisikan data kita sebagai daftar dari daftar. Setiap daftar dalamnya mewakili satu baris data yang akan dimasukkan ke dalam tabel.

Kemudian kita mendefinisikan pernyataan SQL insert sebagai template Jinja. Kita menggunakan for loop untuk mengulangi setiap baris dalam daftar data, dan for loop lainnya untuk mengulangi setiap kolom dalam baris. Kita menggunakan variabel loop.last untuk menambahkan koma hanya antara kolom, tetapi tidak setelah kolom terakhir dalam setiap baris atau baris terakhir dalam data.

Kita juga menggunakan pernyataan kondisional untuk memeriksa apakah nilai kolom saat ini adalah string atau tidak. Jika itu adalah string, kita mengapitnya dengan tanda kutip sebelum memasukkannya ke dalam pernyataan SQL.

Akhirnya, kita mengkompilasi template Jinja dan merender pernyataan SQL dengan data menggunakan metode render. Pernyataan SQL yang dihasilkan dapat dieksekusi terhadap database.

UPDATE

Berikut adalah contoh kode untuk memperbarui tabel SQL menggunakan Jinja dan Python:

python
import jinja2

# Define the data for the update
update_data = {
    'column1': 'new_value1',
    'column2': 'new_value2',
    'column3': 'new_value3'
}

# Define the Jinja template for the update query
update_query_template = """
    UPDATE my_table
    SET {% for column, value in update_data.items() %}
        {{ column }} = {{ value }}{% if not loop.last %},{% endif %}
    {% endfor %}
    WHERE id = {{ id }};
"""

# Create the Jinja environment and render the query template
env = jinja2.Environment()
update_query = env.from_string(update_query_template).render(update_data=update_data, id=123)

Pada kode ini, pertama-tama kita mendefinisikan data yang ingin kita gunakan untuk pembaruan, yaitu sebuah kamus yang berisi nama kolom dan nilai baru mereka.

Kemudian kita mendefinisikan template Jinja untuk query pembaruan. Dalam template, kita menggunakan loop for untuk mengulangi nama kolom dan nilai dalam kamus update_data, dan menetapkan setiap kolom dengan nilai baru yang sesuai. Kita menggunakan variabel loop.last untuk memeriksa apakah kita berada pada iterasi terakhir loop, dan menambahkan koma jika tidak, untuk memastikan sintaks SQL benar.

Akhirnya, kita membuat lingkungan Jinja, merender template query dengan kamus update_data dan ID dari baris yang ingin kita perbarui, dan mengeksekusi query yang dihasilkan menggunakan penghubung database kita.

Referensi

https://jinja.palletsprojects.com/en/3.1.x/

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!