Hướng dẫn tạo trang web động bằng mẫu Jinja trong FastAPI

Các mẫu Jinja cung cấp một ngôn ngữ mạnh mẽ mà bạn có thể dùng để tạo những trang web động dễ dàng. Dưới đây là cách tạo web động bằng mẫu Jinja trong Fast API.

Dùng mẫu Jinja tạo web động

Tích hợp Jinja với FastAPI cho phép bạn tạo trang web động kết hợp liền mạch code Python với HTML, cho phép bạn tách riêng lớp thuyết trình của ứng dụng khỏi layer logic. Với những trang web động, bạn có thể tạo nội dung được cá nhân hóa và dựa trên dữ liệu, nhằm nâng cao trải nghiệm người dùng.

Jinja là gì?

Jinja là một công cụ mẫu giàu tính năng, mạnh mẽ cho Python tạo trang web động. Jinja Templating hỗ trợ tính kế thừa, lệnh điều kiện, vòng lặp và nhiều tính năng khác nhằm đơn giản hóa sáng tạo trang web động.

Bạn có thể kết hợp FastAPI và Jinja để tạo các trang web có bố cục nhất quán mà có thể hiện dữ liệu tại thời gian thực và xử lý đầu vào của người dùng. Bạn cũng có thể tách biệt các mối quan tâm, làm code dễ bảo trì và dễ hiểu hơn.

Thiết lập dự án FastAPI

Để bắt đầu, bạn cần thiết lập dự án FastAPI.

1. Tạo và kích hoạt môi trường ảo bằng những lệnh terminal sau:

python -m venv env

# Trên Unix/MacOS: 
source venv/bin/activate

# Trên Windows:
.\venv\Scripts\activate

2. Cài FastAPI và các phần phụ thuộc cần thiết.

pip install "fastapi[all]"

3. Tạo thư mục dự án my_blog.

4. Tạo một file Python main.py trong thư mục dự án của bạn.

5. Thêm code sau vào file main.py:

from fastapi import FastAPI

fake_posts_db = [{
    'title': 'First Blog Post',
    'content': 'Content of the first blog post.',
    'author': 'John Doe',
    'publication_date': '2023-06-20',
    'comments': [
        {'author': 'Alice', 'content': 'Great post!'},
        {'author': 'Bob', 'content': 'Intresting read.'}
    ],
    'status': 'published'
},{
    'title': 'Second Blog Post',
    'content': 'Content of the second blog post.',
    'author': 'Jane Smith',
    'publication_date': None,
    'comments': [],
    'status': 'draft'
}]

app = FastAPI()

@app.get("/about")
def about():
    return "All you need to know about Simple Blog"

Code trên tạo một ứng dụng FastAPI đơn giản với một endpoint duy nhất trả về phản hồi JSON khi được truy cập qua URL tương ứng. Bạn có thể dùng một từ điển Python như thế thay cho database thực tế. Nó giúp giảm sự phức tạp trong khi tập trung vào mục tiêu chính.

6. Chạy server này.

uvicorn main:app --reload

Truy cập http://localhost:8000/about trong trình duyệt để thấy phản hồi server.

Tích hợp mẫu Jinja

Sau khi thành công thiết lập dự án, giờ bạn có thể thêm mẫu Jinja vào nó.

1. Trong file main.py, nhập mô đun sau:

from fastapi.templating import Jinja2Templates
  from fastapi.staticfiles import StaticFiles

2. Bên dưới biến app, tạo một phiên bản của class Jinja2Templates và chuyển sang thư mục sẽ chứa template của bạn.

templates = Jinja2Templates(directory="templates")

3. Sau biến templates, thêm dòng code sau:

app.mount("/static", StaticFiles(directory="static"), name="static")

Code trên gắn thư mục static và hướng dẫn FastAPI để sử dụng cho bất kỳ file tĩnh nằm trong thư mục khi một URL truy vấn bắt đầu bằng /static.

4. Trong my_blog, tạo hai thư mục, templates chứa file HTML và static chứa toàn bộ file tĩnh.

Dùng mẫu Jinja tạo web động

Khi hoàn thành bước trên, bạn đã thành công tích hợp Jinja Templating vào dự án.

Tạo trang web động với Jinja

Jinja cung cấp một bộ cú pháp và tính năng phong phú để tạo các mẫu động. Trong phần này, bạn sẽ thấy cách dùng cú pháp mẫu Jinja để tạo trang web động.

Tag mẫu

Kèm theo các thẻ mẫu với dấu ngoặc nhọn và ký hiệu phần trăm ở cả hai bên. Bạn có thể sử dụng các thẻ như vậy để thực hiện những thao tác logic và luồng điều khiển trong mẫu. Một số thẻ mẫu thường được sử dụng bao gồm:

Condition: Chạy khối code nếu điều kiện là true.

{% if condition %}...{% endif %}

Loop: Lặp lại một iterable và chạy khối code cho từng mục.

{% for item in iterable %}...{% endfor %}

Include: Bao gồm mẫu khác trong mẫu hiện tại.

{% include 'template_name.html' %}

Block: Xác định một khối mà các mẫu con có thể ghi đè bằng cách dùng tính kế thừa.

{% block block_name %}...{% endblock %}

Extend: Cho phép các mẫu con kế thừa và mở rộng mẫu parent.

{% extend parent_temp.html %}

Những tag này cung cấp một cách linh hoạt và ấn tượng để tạo nội dung HTML dựa trên dữ liệu động và kiểm soát logic của ứng dụng.

Kế thừa mẫu

Jinja Templating hỗ trợ kế thừa mẫu. Điều này cho phép bạn xác định một mẫu cơ sở (parent) với bố cục thông dụng và các phần trong đó một mẫu con có thể mở rộng hoặc ghi đè. Một mẫu con có thể dùng thẻ Extend để kế thừa và mở rộng mẫu chính.

Tạo một file base.html trong thư mục templates bằng code sau:

<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}Simple Blog{% endblock %}</title>
</head>
<body>
    <h1>{% block heading %}Simple Blog{% endblock %}</h1>

    {% block content %}
    {% endblock %}

    {% include "footer.html" %}
</body>
</html>

Bằng cách này, bạn có một mẫu chính, chứa code thông dụng cho toàn bộ mẫu, cho phép mẫu con kế thừa và mở rộng nó khi cần.

Trong thư mục template tạo một file footer.html bằng code sau:

<footer>
    <p>&copy; 2023 Simple Blog. All rights reserved.</p>
    <a href="/{{ url_for('about') }}">About</a>
</footer>

Footer.html bao gồm mẫu chứa code HTML cho phần footer. Bạn có thể tái sử dụng nó trên nhiều trang bằng cách bao gồm nó trong mẫu cơ sở dùng thẻ Include.

Trong thư mục templates, tạo file blog.html bằng code sau:

{% extends "base.html" %}

{% block title %}Simple Blog - Blog Page{% endblock %}

{% block heading %}Simple Blog - Blog Page{% endblock %}

{% block content %}
    <h2>Total Number of Posts: {{ posts|length }}</h2>

    {% for post in posts %}
        <div class="post">

            {% if post.status == 'published' %}
                <h3>{{ post.title }}</h3>
                <p>{{ post.content|truncate }}</p>
                <p>Published on: {{ post.publication_date }}</p>

                <h4>Comments:</h4>
                <ul>
                    {% for comment in post.comments %}
                        <li class="comment">{{ comment.author }}-: {{ comment.content }}</li>
                        

                    {% endfor %}
                </ul>
            {% else %}
                <p>This post is still in draft mode.</p>
            {% endif %}
        </div>
        <hr>
    {% endfor %}
{% endblock %}

Mẫu con kế thừa từ base.html bằng thẻ Extend. Nó ghi đè các khối cụ thể được xác định trong mẫu cơ sở nhằm cung cấp nội dung được tùy biến cho trang blog. Nó cũng bao gồm logic cần thiết và lặp lại để hiện bài đăng và bình luận liên quan.

Biểu thức

Jinja hỗ trợ một loạt biểu thức, bao gồm phép tính số học, so sánh và toán tử logic. Ví dụ:

{{2 + 2}} // output: 4

Thay thế biến

Để xuất các biến trong mẫu, hãy đặt chúng trong dấu ngoặc nhọn kép. Ví dụ:

{{post.title}} // output: 'First Blog Post'

Bộ lọc

Bộ lọc chỉnh sửa đầu ra của một biến. Bạn có thể thêm một số sau một biến bằng cách dùng biểu tượng (|). Ví dụ:

{{post|length}} // output: 2

Bình luận

Bạn có thể thêm bình luận trên cùng một dòng và nhiều dòng trong mẫu. Jinja sẽ bỏ qua những bình luận này trong khi hiển thị mẫu, vì thế, chúng hữu ích trong việc bổ sung giải thích trong một mẫu.

{# #} // inline

{% comment %} ... {% end comment %} // multiline

URL

Để tạo các siêu liên kết chính xác tới trang khác trong ứng dụng, nội dung mẫu Jinja bao gồm hàm url_for. Ví dụ:

<a href="/{{ url_for('about') }}">About</a>

Code trên trở thành http://localhost:8000/about. Bạn cũng sẽ thấy cách dùng hàm url_for để lấy những đường dẫn file tĩnh sau đó.

Trên đây chỉ là một vài trong số các khía cạnh cơ bản của cú pháp Jinja Templating. Nó còn cung cấp nhiều tính năng khác như macro, nội dung mẫu… cho bạn sáng tạo và tùy biến mẫu hiệu quả và linh hoạt.

Chuyển dữ liệu sang mẫu

Thêm code sau vào file main.py:

from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse

@app.get("/", response_class=HTMLResponse)
async def read_posts(request: Request):
    return templates.TemplateResponse("blog.html", {"request": request, 
                                                    "posts": fake_posts_db})

Code này xác định một endpoint FastAPI xử lý truy vấn GET tới URL gốc (“/”) và trả về HTMLResponse được tạo từ mẫu blog.html. Nó chuyển từ điển ngữ cảnh, chứa request objectfake_posts_db vào mẫu này. Bằng cách đó, Jinja có thể hiện dữ liệu động chính xác.

Truy cập http://localhost:8000/ trên trình duyệt của bạn, bạn sẽ thấy:

Dùng mẫu Jinja tạo web động

Bạn đã thành công chuyển dữ liệu vào các mẫu để hiển thị.

Trên đây là hướng dẫn tạo trang web động đơn giản. Hi vọng bài viết hữu ích với các bạn!

CÓ THỂ BẠN QUAN TÂM