Jinja2 Template trong Flask

Trong lập trình web với Python, việc tách biệt giữa logic xử lý (Back-end) và giao diện hiển thị (Front-end) là nguyên tắc vàng giúp code dễ bảo trì, mở rộng và làm việc nhóm hiệu quả. Jinja2 Template trong Flask chính là công cụ đắc lực nhất để giải quyết bài toán này.

Bài viết này sẽ giúp bạn:

  • Hiểu rõ Jinja2 Template là gì.
  • Nắm được cách Jinja2 Template hoạt động.
  • Thành thạo cú pháp từ cơ bản đến nâng cao.
  • Biết cách tổ chức template chuyên nghiệp như dự án thực tế.

1. Jinja2 Template là gì?

Jinja2 Template là một templating engine mạnh mẽ cho Python, được sử dụng phổ biến để tạo HTML, XML hoặc các định dạng văn bản khác.
Đây là template engine mặc định của Flask, đóng vai trò trung gian giữa logic Pythongiao diện người dùng.

👉 Hiểu đơn giản:

  • Python: Xử lý dữ liệu, logic nghiệp vụ, truy vấn database.
  • Jinja2 Template: Nhận dữ liệu từ Python và trộn (render) vào khung HTML có sẵn.
  • Trình duyệt: Hiển thị kết quả cuối cùng cho người dùng.

Tóm lại: Jinja2 Template giúp bạn viết code HTML động, thông minh và có thể tái sử dụng thay vì viết HTML tĩnh nhàm chán.

2. Jinja2 Template hoạt động như thế nào?

Jinja2 hoạt động như thế nào
Jinja2 hoạt động như thế nào

Trong một ứng dụng Flask tiêu chuẩn, Jinja2 Template hoạt động theo luồng sau:

  1. Flask route nhận và xử lý request
  2. Controller / Service lấy dữ liệu từ DB hoặc API
  3. Truyền dữ liệu sang template
  4. Jinja2 render HTML
  5. Trả kết quả về trình duyệt

Request → Flask Route → Data → Jinja2 Template → HTML → Browser

Chi tiết:

  1. Người dùng gửi request.
  2. Flask route tiếp nhận & xử lý.
  3. Lấy dữ liệu từ DB / API.
  4. Truyền dữ liệu sang template.
  5. Jinja2 render HTML.
  6. Trả HTML về trình duyệt.

👉 Đây chính là mô hình MVC / MVT rút gọn, rất phù hợp cho:

  • Flask Admin.
  • Dashboard nội bộ.
  • SaaS
  • AI Tool, hệ thống quản trị.

3. Cú pháp cơ bản trong Jinja2 Template

Jinja2 Template sử dụng các ký hiệu đặc biệt để phân biệt code logicnội dung hiển thị:

Ký hiệu Mục đích Ví dụ
{{ ... }} Biểu thức (In giá trị biến ra màn hình) {{ user.name }}
{% ... %} Câu lệnh (Logic, vòng lặp, điều kiện) {% if user.active %}
{# ... #} Chú thích (Không hiển thị khi chạy) {# Đây là comment #}

In biến ({{ }})

<h1>{{ title }}</h1>
<p>{{ user.name }}</p>

Câu điều kiện ({% if %})

{% if user %}
  <p>Xin chào {{ user.name }}</p>
{% else %}
  <p>Vui lòng đăng nhập</p>
{% endif %}

Vòng lặp ({% for %})

<ul>
  {% for product in products %}
    <li>{{ product.name }} - {{ product.price }}</li>
  {% endfor %}
</ul>

Filter (bộ lọc dữ liệu)

{{ content|safe }}
{{ username|upper }}
{{ created_at|date }}

👉 Filter trong Jinja2 Template giúp format dữ liệu ngay trong template, không cần xử lý trước ở Python.

4. Ví dụ thực tế Jinja2 Template

👉 Đây là ví dụ điển hình về cách Flask + Jinja2 Template truyền dữ liệu một chiều, rõ ràng và dễ debug.

Controller (Python)

@app.route('/products')
def products():
    items = [
        {'name': 'Bàn gỗ', 'price': 2000000},
        {'name': 'Ghế sofa', 'price': 5000000},
    ]
    return render_template('products.html', products=items)

Template products.html

<h1>Danh sách sản phẩm</h1>

<ul>
  {% for item in products %}
    <li>{{ item.name }} - {{ item.price }} VNĐ</li>
  {% endfor %}
</ul>

👉 Đây là cách Flask + Jinja2 truyền dữ liệu một chiều, rất rõ ràng và dễ debug.

5. Kế thừa template (Template Inheritance trong Jinja2)

Đây là tính năng mạnh nhất của Jinja2 Template, giúp bạn không phải copy-paste code (như header, footer) nhiều lần, dễ thay đổi layout toàn site, chuẩn kiến trúc web lớn.

Cơ chế hoạt động dựa trên 2 từ khóa chính:

  1. {% block %}: Định nghĩa các “lỗ chờ” ở file cha để file con điền nội dung vào.
  2. {% extends %}: Khai báo ở file con để biết nó kế thừa từ file cha nào.

File cha base.html – File này chứa những phần giống nhau ở mọi trang (Header, Footer, CSS, JS).

<!DOCTYPE html>
<html lang="vi">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <header>{% include "partials/header.html" %}</header>
    <main>{% block content %}{% endblock %}</main>
    <footer>{% include "partials/footer.html" %}</footer>
</body>
</html>

File con kế thừa home.html – File này chỉ cần viết nội dung riêng biệt của nó.

{% extends "base.html" %}

{% block title %}Trang chủ{% endblock %}

{% block content %}
<h1>Chào mừng bạn đến với website</h1>
<p>Nội dung trang chủ ở đây</p>
{% endblock %}

👉 Mọi trang trong Flask dùng chung layout, chỉ thay phần nội dung cần thiết thông qua template inheritance của Jinja2.

6. Include & Macro – Tổ chức Jinja2 Template chuyên nghiệp

Include và Macro là hai kỹ thuật nâng cao giúp Jinja2 Template trở nên gọn gàng, dễ bảo trì và mở rộng.

Include (Chèn file)

Dùng để tách các đoạn HTML nhỏ (snippet) và tái sử dụng (ví dụ: banner quảng cáo, sidebar). Khác với kế thừa, include chỉ đơn giản là “copy-paste” nội dung file này vào file kia.

<div class="sidebar">Quảng cáo ở đây</div>

{% include 'sidebar.html' %}

Macro (Hàm tạo HTML)

Giống như function trong Python, dùng để tạo ra các đoạn HTML lặp đi lặp lại có cấu trúc giống nhau (ví dụ: input form).

{# Định nghĩa macro #}
{% macro render_input(name, placeholder) %}
    <div class="form-group">
        <label>{{ name }}</label>
        <input type="text" name="{{ name }}" placeholder="{{ placeholder }}">
    </div>
{% endmacro %}

{# Sử dụng macro #}
{{ render_input('username', 'Nhập tên đăng nhập') }}
{{ render_input('email', 'Nhập email') }}

👉 Macro đặc biệt hữu ích cho form lớn, dashboard, admin panel trong các dự án Flask thực tế.

7. Lỗi thường gặp khi dùng Jinja2 Template

  • ❌ Viết logic phức tạp trong Jinja2 Template
  • ❌ Quên escape dữ liệu (safe dùng sai chỗ → XSS)
  • ❌ Không dùng template inheritance
  • ❌ Template quá dài, không tách include

8. Best Practice khi dùng Jinja2 Template

  • ✅ Jinja2 Template chỉ lo hiển thị.
  • ✅ Xử lý logic ở Python càng nhiều càng tốt.
  • ✅ Dùng base.html cho toàn site.
  • ✅ Tách partials/, macros rõ ràng.
  • ✅ Đặt tên biến rõ nghĩa, tránh viết tắt khó hiểu.

9. Kết luận

Jinja2 Template không chỉ là template engine, mà là nền tảng kiến trúc giao diện cho Flask.

Nắm vững Jinja2 Template giúp bạn:

  • Viết code sạch hơn
  • Dễ mở rộng dự án
  • Làm việc nhóm hiệu quả
  • Xây dựng dashboard & SaaS chuyên nghiệp

👉 Nếu bạn đang học Flask nghiêm túc, Jinja2 Template là thứ bắt buộc phải thành thạo.