Tìm hiểu và sử dụng Jinja template

Tìm hiểu và sử dụng Jinja template

Jinja là một công cụ tạo khuôn mẫu nhanh, biểu cảm và có khả năng mở rộng. Các phần giữ chỗ đặc biệt trong mẫu cho phép viết mã tương tự như cú pháp Python. Sau đó, mẫu được truyền dữ liệu để hiển thị tài liệu cuối cùng.

Tài liệu thiết kế mẫu 

Tài liệu này mô tả cú pháp và ngữ nghĩa của công cụ tạo mẫu và sẽ hữu ích nhất khi tham khảo cho những người tạo mẫu Jinja. Vì công cụ tạo mẫu rất linh hoạt nên cấu hình của ứng dụng có thể hơi khác so với mã được trình bày ở đây về các dấu phân cách và hành vi của các giá trị không xác định.

Tóm tắt 

Mẫu Jinja chỉ đơn giản là một tệp văn bản. Jinja có thể tạo bất kỳ định dạng dựa trên văn bản nào (HTML, XML, CSV, LaTeX, v.v.). Mẫu Jinja không cần phải có tiện ích mở rộng cụ thể: .html.xmlhoặc bất kỳ tiện ích mở rộng nào khác đều ổn.

Mẫu chứa các biến và/hoặc biểu thức , được thay thế bằng các giá trị khi mẫu được hiển thị ; và tags , điều khiển logic của mẫu. Cú pháp mẫu được lấy cảm hứng rất nhiều từ Django và Python.

Dưới đây là mẫu tối thiểu minh họa một số điều cơ bản khi sử dụng cấu hình Jinja mặc định. Chúng tôi sẽ trình bày chi tiết sau trong tài liệu này:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>My Webpage</title>
</head>
<body>
    <ul id="navigation">
    {% for item in navigation %}
        <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
    {% endfor %}
    </ul>

    <h1>My Webpage</h1>
    {{ a_variable }}

    {# a comment #}
</body>
</html>

Ví dụ sau đây hiển thị các cài đặt cấu hình mặc định. Nhà phát triển ứng dụng có thể thay đổi cấu hình cú pháp từ sang hoặc tương tự.{% foo %}<% foo %>

Có một số loại dấu phân cách. Các dấu phân cách Jinja mặc định được định cấu hình như sau:

Cũng có thể sử dụng Tuyên bố dòng và Nhận xét , mặc dù chúng không có ký tự tiền tố mặc định. Để sử dụng chúng, hãy đặtline_statement_prefixline_comment_prefixkhi tạo tệpEnvironment.

Phần mở rộng tệp mẫu 

Như đã nêu ở trên, bất kỳ tệp nào cũng có thể được tải dưới dạng mẫu, bất kể đuôi tệp là gì. Việc thêm .jinjatiện ích mở rộng, chẳng hạn như user.html.jinjacó thể giúp một số IDE hoặc plugin trình chỉnh sửa dễ dàng hơn nhưng không bắt buộc. Tính năng tự động thoát, được giới thiệu sau, có thể được áp dụng dựa trên phần mở rộng của tệp, vì vậy bạn sẽ cần tính đến hậu tố bổ sung trong trường hợp đó.

Một phương pháp phỏng đoán hữu ích khác để xác định mẫu là chúng nằm trong một templatesthư mục, bất kể phần mở rộng. Đây là cách bố trí chung cho các dự án.

Biến 

Các biến mẫu được xác định bởi từ điển ngữ cảnh được truyền cho mẫu.

Bạn có thể loay hoay với các biến trong mẫu miễn là chúng được ứng dụng chuyển vào. Các biến có thể có các thuộc tính hoặc phần tử mà bạn có thể truy cập. Những thuộc tính nào của một biến phụ thuộc rất nhiều vào ứng dụng cung cấp biến đó.

Bạn có thể sử dụng dấu chấm ( .) để truy cập các thuộc tính của một biến ngoài __getitem__cú pháp “chỉ số dưới” tiêu chuẩn của Python ( []).

Các dòng sau thực hiện tương tự:

{{ foo.bar }}
{{ foo['bar'] }}

Điều quan trọng cần biết là dấu ngoặc nhọn đôi bên ngoài không phải là một phần của biến mà là câu lệnh in. Nếu bạn truy cập các biến bên trong thẻ thì đừng đặt dấu ngoặc nhọn xung quanh chúng.

Nếu một biến hoặc thuộc tính không tồn tại, bạn sẽ nhận được một giá trị không xác định. Những gì bạn có thể làm với loại giá trị đó tùy thuộc vào cấu hình ứng dụng: hành vi mặc định là đánh giá thành một chuỗi trống nếu được in hoặc lặp lại và không thực hiện được đối với mọi thao tác khác.

Thực hiện

Để thuận tiện, foo.barJinja thực hiện những việc sau trên lớp Python:

  • kiểm tra thuộc tính có tên bartrên foo( )getattr(foo, 'bar')
  • nếu không có, hãy kiểm tra mục 'bar'trong foofoo.__getitem__('bar'))
  • nếu không có, trả về một đối tượng không xác định.

foo['bar']hoạt động gần như giống nhau với một sự khác biệt nhỏ về trình tự:

  • kiểm tra một mục 'bar'trong foo. ( foo.__getitem__('bar'))
  • nếu không có, hãy kiểm tra thuộc tính được gọi bartrên foo. ( )getattr(foo, 'bar')
  • nếu không có, trả về một đối tượng không xác định.

Điều này rất quan trọng nếu một đối tượng có một mục và thuộc tính có cùng tên. Ngoài ra, attr()bộ lọc chỉ tra cứu các thuộc tính.

Bộ lọc 

Các biến có thể được sửa đổi bằng bộ lọc . Các bộ lọc được phân tách khỏi biến bằng ký hiệu ống dẫn ( |) và có thể có các đối số tùy chọn trong ngoặc đơn. Nhiều bộ lọc có thể được xâu chuỗi. Đầu ra của một bộ lọc được áp dụng cho bộ lọc tiếp theo.

Ví dụ: sẽ xóa tất cả Thẻ HTML khỏi biến và trường hợp tiêu đề đầu ra ( ).{{ name|striptags|title }}nametitle(striptags(name))

Các bộ lọc chấp nhận đối số có dấu ngoặc đơn xung quanh đối số, giống như lệnh gọi hàm. Ví dụ: sẽ nối một danh sách bằng dấu phẩy ( ).{{ listx|join(', ') }}str.join(', ', listx)

Danh sách Bộ lọc dựng sẵn bên dưới mô tả tất cả các bộ lọc dựng sẵn.

Kiểm tra 

Bên cạnh các bộ lọc, còn có cái gọi là “thử nghiệm”. Các thử nghiệm có thể được sử dụng để kiểm tra một biến dựa trên một biểu thức chung. Để kiểm tra một biến hoặc biểu thức, bạn thêm isdấu cộng vào tên của phép kiểm tra sau biến đó. Ví dụ: để tìm hiểu xem một biến có được xác định hay không, bạn có thể thực hiện , sau đó sẽ trả về true hoặc false tùy thuộc vào việc biến có được xác định trong ngữ cảnh mẫu hiện tại hay không.name is definedname

Các bài kiểm tra cũng có thể chấp nhận các đối số. Nếu bài kiểm tra chỉ lấy một đối số, bạn có thể bỏ dấu ngoặc đơn. Ví dụ: hai biểu thức sau đây thực hiện điều tương tự:

{% if loop.index is divisibleby 3 %}
{% if loop.index is divisibleby(3) %}

Danh sách các bài kiểm tra dựng sẵn bên dưới mô tả tất cả các bài kiểm tra dựng sẵn.

Bình luận 

Để nhận xét một phần của dòng trong mẫu, hãy sử dụng cú pháp nhận xét theo mặc định được đặt thành . Điều này rất hữu ích khi nhận xét các phần của mẫu để gỡ lỗi hoặc để thêm thông tin cho những người thiết kế mẫu khác hoặc chính bạn:{# ... #}

{# note: commented-out template because we no longer use this
    {% for user in users %}
        ...
    {% endfor %}
#}

Kiểm soát khoảng trắng 

Trong cấu hình mặc định:

  • một dòng mới ở cuối sẽ bị loại bỏ nếu có
  • khoảng trắng khác (dấu cách, tab, dòng mới, v.v.) được trả về không thay đổi

Nếu một ứng dụng định cấu hình Jinja thành trim_blocks, dòng mới đầu tiên sau thẻ mẫu sẽ tự động bị xóa (như trong PHP). Tùy chọn này lstrip_blockscũng có thể được đặt để loại bỏ các tab và dấu cách từ đầu dòng đến đầu khối. (Không có gì bị loại bỏ nếu có các ký tự khác trước khi bắt đầu khối.)

Với cả hai trim_blocksvà lstrip_blocksđược bật, bạn có thể đặt thẻ khối trên các dòng riêng của chúng và toàn bộ dòng khối sẽ bị xóa khi hiển thị, duy trì khoảng trắng của nội dung. Ví dụ: không có tùy chọn trim_blocksvà lstrip_blocks, mẫu này:

<div>
    {% if True %}
        yay
    {% endif %}
</div>

được hiển thị với các dòng trống bên trong div:

<div>

        yay

</div>

Nhưng với cả hai trim_blocksvà lstrip_blocksđược bật, các dòng khối mẫu sẽ bị xóa và khoảng trắng khác được giữ nguyên:

<div>
        yay
</div>

Bạn có thể vô hiệu hóa lstrip_blockshành vi này theo cách thủ công bằng cách đặt dấu cộng ( +) ở đầu khối:

<div>
        {%+ if something %}yay{% endif %}
</div>

Tương tự, bạn có thể vô hiệu hóa trim_blockshành vi này theo cách thủ công bằng cách đặt dấu cộng ( +) ở cuối khối:

<div>
    {% if something +%}
        yay
    {% endif %}
</div>

Bạn cũng có thể loại bỏ khoảng trắng trong mẫu bằng tay. Nếu bạn thêm dấu trừ ( -) vào đầu hoặc cuối khối (ví dụ: thẻ For ), nhận xét hoặc biểu thức biến, khoảng trắng trước hoặc sau khối đó sẽ bị xóa:

{% for item in seq -%}
    {{ item }}
{%- endfor %}

Điều này sẽ mang lại tất cả các phần tử không có khoảng trắng giữa chúng. Nếu seqlà danh sách các số từ 1đến 9, kết quả sẽ là 123456789.

Nếu Báo cáo dòng được bật, chúng sẽ tự động loại bỏ khoảng trắng ở đầu dòng cho đến đầu dòng.

Theo mặc định, Jinja cũng loại bỏ các dòng mới ở cuối. Để giữ các dòng mới ở cuối, hãy định cấu hình Jinja thành keep_trailing_newline.

Ghi chú

Bạn không được thêm khoảng trắng giữa thẻ và dấu trừ.

có hiệu lực :

{%- if foo -%}...{% endif %}

không hợp lệ :

{% - if foo - %}...{% endif %}

Chạy trốn 

Đôi khi, điều mong muốn – thậm chí là cần thiết – là để Jinja bỏ qua các phần mà nếu không nó sẽ xử lý dưới dạng biến hoặc khối. Ví dụ: nếu với cú pháp mặc định, bạn muốn sử dụng {{làm chuỗi thô trong mẫu và không bắt đầu một biến, bạn phải sử dụng một thủ thuật.

Cách dễ nhất để xuất ra dấu phân cách biến bằng chữ ( {{) là sử dụng biểu thức biến:

{{ '{{' }}

Đối với các phần lớn hơn, việc đánh dấu một khối là điều hợp lý raw. Ví dụ: để đưa cú pháp Jinja mẫu vào một mẫu, bạn có thể sử dụng đoạn mã này:

{% raw %}
    <ul>
    {% for item in seq %}
        <li>{{ item }}</li>
    {% endfor %}
    </ul>
{% endraw %}

Ghi chú

Dấu trừ ở cuối thẻ sẽ xóa tất cả khoảng trắng và dòng mới trước ký tự đầu tiên của dữ liệu thô của bạn.{% raw -%}

Báo cáo dòng 

Nếu các câu lệnh dòng được ứng dụng kích hoạt thì có thể đánh dấu một dòng là một câu lệnh. Ví dụ: nếu tiền tố câu lệnh dòng được định cấu hình thành #, thì hai ví dụ sau là tương đương:

<ul>
# for item in seq
    <li>{{ item }}</li>
# endfor
</ul>

<ul>
{% for item in seq %}
    <li>{{ item }}</li>
{% endfor %}
</ul>

Tiền tố câu lệnh dòng có thể xuất hiện ở bất kỳ đâu trên dòng miễn là không có văn bản nào đứng trước nó. Để dễ đọc hơn, các câu lệnh bắt đầu một khối (chẳng hạn như forifelifv.v.) có thể kết thúc bằng dấu hai chấm:

# for item in seq:
    ...
# endfor

Ghi chú

Câu lệnh dòng có thể trải dài trên nhiều dòng nếu có dấu ngoặc đơn, dấu ngoặc nhọn hoặc dấu ngoặc mở:

<ul>
# for href, caption in [('index.html', 'Index'),
                        ('about.html', 'About')]:
    <li><a href="{{ href }}">{{ caption }}</a></li>
# endfor
</ul>

Kể từ Jinja 2.2, tính năng nhận xét theo dòng cũng có sẵn. Ví dụ: nếu tiền tố dòng nhận xét được định cấu hình là ##, mọi thứ từ ##đến cuối dòng sẽ bị bỏ qua (ngoại trừ dấu dòng mới):

# for item in seq:
    <li>{{ item }}</li>     ## this comment is ignored
# endfor

Kế thừa mẫu 

Phần mạnh mẽ nhất của Jinja là kế thừa mẫu. Kế thừa mẫu cho phép bạn xây dựng một mẫu “khung” cơ sở chứa tất cả các thành phần chung của trang web của bạn và xác định các khối mà các mẫu con có thể ghi đè.

Nghe có vẻ phức tạp nhưng rất cơ bản. Dễ hiểu nhất là bắt đầu bằng một ví dụ.

Mẫu cơ sở 

Mẫu này, chúng ta sẽ gọi là base.html, xác định một tài liệu khung HTML đơn giản mà bạn có thể sử dụng cho một trang hai cột đơn giản. Nhiệm vụ của các mẫu “con” là lấp đầy các khối trống bằng nội dung:

<!DOCTYPE html>
<html lang="en">
<head>
    {% block head %}
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}{% endblock %} - My Webpage</title>
    {% endblock %}
</head>
<body>
    <div id="content">{% block content %}{% endblock %}</div>
    <div id="footer">
        {% block footer %}
        &copy; Copyright 2008 by <a href="http://domain.invalid/">you</a>.
        {% endblock %}
    </div>
</body>
</html>

Trong ví dụ này, các thẻ xác định bốn khối mà các mẫu con có thể điền vào. Tất cả những gì thẻ làm là cho công cụ tạo mẫu biết rằng mẫu con có thể ghi đè các phần giữ chỗ đó trong mẫu.{% block %}block

blockcác thẻ có thể nằm bên trong các khối khác, chẳng hạn như if, nhưng chúng sẽ luôn được thực thi bất kể ifkhối đó có thực sự được hiển thị hay không.

Mẫu con 

Một mẫu con có thể trông như thế này:

{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
    {{ super() }}
    <style type="text/css">
        .important { color: #336699; }
    </style>
{% endblock %}
{% block content %}
    <h1>Index</h1>
    <p class="important">
      Welcome to my awesome homepage.
    </p>
{% endblock %}

Thẻ là chìa khóa ở đây. Nó báo cho công cụ tạo mẫu rằng mẫu này “mở rộng” một mẫu khác. Khi hệ thống mẫu đánh giá mẫu này, trước tiên nó sẽ định vị mẫu mẹ. Thẻ mở rộng phải là thẻ đầu tiên trong mẫu. Mọi thứ trước khi in ra đều bình thường và có thể gây nhầm lẫn. Để biết chi tiết về hành vi này và cách tận dụng nó, hãy xem Dự phòng mặc định Null . Ngoài ra, một khối sẽ luôn được điền vào bất kể điều kiện xung quanh được đánh giá là đúng hay sai.{% extends %}

Tên tệp của mẫu phụ thuộc vào trình tải mẫu. Ví dụ: FileSystemLoadercho phép bạn truy cập các mẫu khác bằng cách cung cấp tên tệp. Bạn có thể truy cập các mẫu trong thư mục con bằng dấu gạch chéo:

{% extends "layout/default.html" %}

Nhưng hành vi này có thể phụ thuộc vào ứng dụng nhúng Jinja. Lưu ý rằng vì mẫu con không xác định khối footernên giá trị từ mẫu gốc sẽ được sử dụng thay thế.

Bạn không thể xác định nhiều thẻ có cùng tên trong cùng một mẫu. Hạn chế này tồn tại vì thẻ khối hoạt động theo hướng “cả hai”. Nghĩa là, thẻ khối không chỉ cung cấp phần giữ chỗ để điền – nó còn xác định nội dung điền vào phần giữ chỗ trong thẻ gốc . Nếu có hai thẻ có tên giống nhau trong một mẫu, thì cấp độ gốc của mẫu đó sẽ không biết nên sử dụng nội dung nào trong các khối.{% block %}{% block %}

Tuy nhiên, nếu bạn muốn in một khối nhiều lần, bạn có thể sử dụng selfbiến đặc biệt và gọi khối có tên đó:

<title>{% block title %}{% endblock %}</title>
<h1>{{ self.title() }}</h1>
{% block body %}{% endblock %}

Siêu khối 

Có thể hiển thị nội dung của khối cha bằng cách gọi super(). Điều này trả lại kết quả của khối cha:

{% block sidebar %}
    <h3>Table Of Contents</h3>
    ...
    {{ super() }}
{% endblock %}

Lồng nhau mở rộng 

Trong trường hợp có nhiều cấp độ , các tham chiếu có thể được xâu chuỗi (như trong ) để bỏ qua các cấp độ trong cây kế thừa.{% extends %}supersuper.super()

Ví dụ:

# parent.tmpl
body: {% block body %}Hi from parent.{% endblock %}

# child.tmpl
{% extends "parent.tmpl" %}
{% block body %}Hi from child. {{ super() }}{% endblock %}

# grandchild1.tmpl
{% extends "child.tmpl" %}
{% block body %}Hi from grandchild1.{% endblock %}

# grandchild2.tmpl
{% extends "child.tmpl" %}
{% block body %}Hi from grandchild2. {{ super.super() }} {% endblock %}

Kết xuất child.tmplsẽ chobody: Hi from child. Hi from parent.

Kết xuất grandchild1.tmplsẽ chobody: Hi from grandchild1.

Kết xuất grandchild2.tmplsẽ chobody: Hi from grandchild2. Hi from parent.

Thẻ kết thúc khối được đặt tên 

Jinja cho phép bạn đặt tên khối sau thẻ kết thúc để dễ đọc hơn:

{% block sidebar %}
    {% block inner_sidebar %}
        ...
    {% endblock inner_sidebar %}
{% endblock sidebar %}

Tuy nhiên, tên sau endblocktừ phải trùng với tên khối.

Khối lồng nhau và phạm vi 

Các khối có thể được lồng vào nhau để có bố cục phức tạp hơn. Tuy nhiên, các khối mặc định có thể không truy cập được các biến từ phạm vi bên ngoài:

{% for item in seq %}
    <li>{% block loop_item %}{{ item }}{% endblock %}</li>
{% endfor %}

Ví dụ này sẽ xuất ra <li>các mục trống vì itemkhông có sẵn trong khối. Lý do cho điều này là nếu khối được thay thế bằng mẫu con, một biến không được xác định trong khối hoặc được chuyển vào ngữ cảnh sẽ xuất hiện.

Bắt đầu với Jinja 2.2, bạn có thể chỉ định rõ ràng rằng các biến có sẵn trong một khối bằng cách đặt khối thành “có phạm vi” bằng cách thêm công scopedcụ sửa đổi vào khai báo khối:

{% for item in seq %}
    <li>{% block loop_item scoped %}{{ item }}{% endblock %}</li>
{% endfor %}

Khi ghi đè một khối, scopedkhông cần phải cung cấp công cụ sửa đổi.

Khối bắt buộc 

Các khối có thể được đánh dấu là required. Chúng phải được ghi đè tại một số điểm, nhưng không nhất thiết phải bằng mẫu con trực tiếp. Các khối bắt buộc chỉ có thể chứa khoảng trắng và nhận xét và chúng không thể được hiển thị trực tiếp.

page.txt

{% block body required %}{% endblock %}

issue.txt

{% extends "page.txt" %}

bug_report.txt

{% extends "issue.txt" %}
{% block body %}Provide steps to demonstrate the bug.{% endblock %}

Hiển thị page.txthoặc issue.txtsẽ tăng TemplateRuntimeErrorvì chúng không ghi đè bodykhối. Kết xuất bug_report.txtsẽ thành công vì nó ghi đè lên khối.

Khi kết hợp với scopedrequiredcông cụ sửa đổi phải được đặt sau công cụ sửa đổi phạm vi. Dưới đây là một số ví dụ hợp lệ:

{% block body scoped %}{% endblock %}
{% block body required %}{% endblock %}
{% block body scoped required %}{% endblock %}

Đối tượng mẫu 

extendsincludevà importcó thể lấy một đối tượng mẫu thay vì tên của mẫu để tải. Điều này có thể hữu ích trong một số tình huống nâng cao, vì bạn có thể sử dụng mã Python để tải mẫu trước và chuyển nó vào render.

if debug_mode:
    layout = env.get_template("debug_layout.html")
else:
    layout = env.get_template("layout.html")

user_detail = env.get_template("user/detail.html")
return user_detail.render(layout=layout)
{% extends layout %}

Lưu ý cách extendstruyền biến bằng đối tượng mẫu đã được truyền tới render, thay vì một chuỗi.

Thoát HTML 

Khi tạo HTML từ mẫu, luôn có nguy cơ biến sẽ bao gồm các ký tự ảnh hưởng đến HTML kết quả. Có hai cách tiếp cận:

  1. thoát từng biến theo cách thủ công; hoặc
  2. tự động thoát mọi thứ theo mặc định.

Jinja hỗ trợ cả hai. Những gì được sử dụng phụ thuộc vào cấu hình ứng dụng. Cấu hình mặc định không tự động thoát; vì nhiều lý do:

  • Việc thoát khỏi mọi thứ ngoại trừ các giá trị an toàn cũng có nghĩa là Jinja đang thoát khỏi các biến được biết là không bao gồm HTML (ví dụ: số, booleans), điều này có thể gây ảnh hưởng lớn đến hiệu suất.
  • Thông tin về sự an toàn của một biến rất mong manh. Có thể xảy ra trường hợp bằng cách ép buộc các giá trị an toàn và không an toàn, giá trị trả về là HTML thoát kép.

Làm việc với tính năng Thoát thủ công 

Nếu tính năng thoát thủ công được bật, bạn có trách nhiệm thoát khỏi các biến nếu cần. Làm gì để trốn thoát? Nếu bạn có một biến có thể bao gồm bất kỳ ký tự nào sau đây ( ><&hoặc "), bạn NÊN thoát khỏi biến đó trừ khi biến đó chứa HTML được định dạng đúng và đáng tin cậy. Việc thoát hoạt động bằng cách chuyển biến qua |ebộ lọc:

{{ user.username|e }}

Làm việc với tính năng Thoát tự động 

Khi tính năng thoát tự động được bật, mọi thứ đều được thoát theo mặc định ngoại trừ các giá trị được đánh dấu rõ ràng là an toàn. Các biến và biểu thức có thể được đánh dấu là an toàn trong:

  1. Từ điển ngữ cảnh của ứng dụng vớimarkupsafe.Markup
  2. Mẫu, với bộ |safelọc.

Nếu một chuỗi mà bạn đã đánh dấu là an toàn được chuyển qua mã Python khác không hiểu dấu đó thì chuỗi đó có thể bị mất. Hãy lưu ý khi nào dữ liệu của bạn được đánh dấu là an toàn và cách xử lý dữ liệu đó trước khi đến mẫu.

Nếu một giá trị đã được thoát nhưng không được đánh dấu là an toàn thì quá trình tự động thoát sẽ vẫn diễn ra và dẫn đến các ký tự thoát kép. Nếu bạn biết mình có dữ liệu đã an toàn nhưng chưa được đánh dấu, hãy nhớ bọc dữ liệu đó lại Markuphoặc sử dụng |safebộ lọc.

Các hàm Jinja (macro, superself.BLOCKNAME) luôn trả về dữ liệu mẫu được đánh dấu là an toàn.

Các chuỗi ký tự trong các mẫu có tính năng thoát tự động được coi là không an toàn vì các chuỗi Python gốc không an toàn.

Danh sách các cấu trúc điều khiển 

Cấu trúc điều khiển đề cập đến tất cả những thứ kiểm soát luồng của chương trình – các điều kiện (tức là if/elif/else), vòng lặp for, cũng như những thứ như macro và khối. Với cú pháp mặc định, cấu trúc điều khiển xuất hiện bên trong các khối.{% ... %}

Vì 

Lặp lại từng mục theo trình tự. Ví dụ: để hiển thị danh sách người dùng được cung cấp trong một biến có tên users:

<h1>Members</h1>
<ul>
{% for user in users %}
  <li>{{ user.username|e }}</li>
{% endfor %}
</ul>

Vì các biến trong mẫu giữ lại các thuộc tính đối tượng của chúng, nên có thể lặp qua các vùng chứa như dict:

<dl>
{% for key, value in my_dict.items() %}
    <dt>{{ key|e }}</dt>
    <dd>{{ value|e }}</dd>
{% endfor %}
</dl>

Các ký tự Python có thể không theo thứ tự bạn muốn hiển thị. Nếu thứ tự quan trọng, hãy sử dụng bộ |dictsortlọc.

<dl>
{% for key, value in my_dict | dictsort %}
    <dt>{{ key|e }}</dt>
    <dd>{{ value|e }}</dd>
{% endfor %}
</dl>

Bên trong khối vòng lặp for, bạn có thể truy cập một số biến đặc biệt:

Biến đổiSự miêu tả
loop.indexSự lặp lại hiện tại của vòng lặp. (1 được lập chỉ mục)
loop.index0Sự lặp lại hiện tại của vòng lặp. (0 được lập chỉ mục)
loop.revindexSố lần lặp từ cuối vòng lặp (1 chỉ số)
loop.revindex0Số lần lặp từ cuối vòng lặp (được lập chỉ mục 0)
loop.firstĐúng nếu lần lặp đầu tiên.
loop.lastĐúng nếu lần lặp cuối cùng.
loop.lengthSố lượng mục trong chuỗi.
loop.cycleMột hàm trợ giúp để chuyển đổi giữa một danh sách các trình tự. Xem giải thích bên dưới.
loop.depthCho biết mức độ hiển thị hiện tại của vòng lặp đệ quy. Bắt đầu ở cấp độ 1
loop.depth0Cho biết mức độ hiển thị hiện tại của vòng lặp đệ quy. Bắt đầu ở cấp độ 0
loop.previtemMục từ lần lặp trước của vòng lặp. Không xác định trong lần lặp đầu tiên.
loop.nextitemMục từ lần lặp tiếp theo của vòng lặp. Không xác định trong lần lặp cuối cùng.
loop.changed(*val)Đúng nếu trước đó được gọi với một giá trị khác (hoặc hoàn toàn không được gọi).

Trong vòng lặp for, có thể chuyển đổi giữa một danh sách các chuỗi/biến mỗi lần thông qua vòng lặp bằng cách sử dụng trình loop.cycletrợ giúp đặc biệt:

{% for row in rows %}
    <li class="{{ loop.cycle('odd', 'even') }}">{{ row }}</li>
{% endfor %}

Kể từ Jinja 2.1, cycleđã tồn tại một trình trợ giúp bổ sung cho phép đạp xe không vòng lặp. Để biết thêm thông tin, hãy xem Danh sách các hàm toàn cục .

Không giống như trong Python, nó không thể thực hiện được breaktrong continuemột vòng lặp. Tuy nhiên, bạn có thể lọc trình tự trong quá trình lặp, điều này cho phép bạn bỏ qua các mục. Ví dụ sau bỏ qua tất cả người dùng bị ẩn:

{% for user in users if not user.hidden %}
    <li>{{ user.username|e }}</li>
{% endfor %}

Ưu điểm là loopbiến đặc biệt sẽ được tính chính xác; do đó không tính người dùng không lặp đi lặp lại.

Nếu không có lần lặp nào diễn ra do chuỗi trống hoặc quá trình lọc đã xóa tất cả các mục khỏi chuỗi, bạn có thể hiển thị khối mặc định bằng cách sử dụng else:

<ul>
{% for user in users %}
    <li>{{ user.username|e }}</li>
{% else %}
    <li><em>no users found</em></li>
{% endfor %}
</ul>

Lưu ý rằng, trong Python, elsecác khối được thực thi bất cứ khi nào vòng lặp tương ứng không thực hiện break . Vì dù sao thì vòng lặp Jinja cũng không thể thực hiện được breaknên hành vi hơi khác của elsetừ khóa đã được chọn.

Cũng có thể sử dụng các vòng lặp đệ quy. Điều này hữu ích nếu bạn đang xử lý dữ liệu đệ quy như sơ đồ trang web hoặc RDFa. Để sử dụng vòng lặp một cách đệ quy, về cơ bản, bạn phải thêm công recursivecụ sửa đổi vào định nghĩa vòng lặp và gọi loopbiến có khả năng lặp mới ở nơi bạn muốn lặp lại.

Ví dụ sau đây triển khai sơ đồ trang web có vòng lặp đệ quy:

<ul class="sitemap">
{%- for item in sitemap recursive %}
    <li><a href="{{ item.href|e }}">{{ item.title }}</a>
    {%- if item.children -%}
        <ul class="submenu">{{ loop(item.children) }}</ul>
    {%- endif %}</li>
{%- endfor %}
</ul>

Biến loopluôn đề cập đến vòng lặp gần nhất (trong cùng). Nếu chúng ta có nhiều cấp độ vòng lặp, chúng ta có thể liên kết lại biến loopbằng cách viết sau vòng lặp mà chúng ta muốn sử dụng đệ quy. Sau đó, chúng ta có thể gọi nó bằng cách sử dụng{% set outer_loop = loop %}{{ outer_loop(...) }}

Xin lưu ý rằng các phép gán trong vòng lặp sẽ bị xóa khi kết thúc vòng lặp và không thể tồn tại lâu hơn trong phạm vi vòng lặp. Các phiên bản cũ hơn của Jinja có một lỗi khiến trong một số trường hợp có vẻ như các bài tập sẽ hoạt động. Điều này không được hỗ trợ. Xem Bài tập để biết thêm thông tin về cách giải quyết vấn đề này.

Nếu tất cả những gì bạn muốn làm là kiểm tra xem một số giá trị đã thay đổi kể từ lần lặp cuối cùng hay sẽ thay đổi trong lần lặp tiếp theo, bạn có thể sử dụng previtemand nextitem:

{% for value in values %}
    {% if loop.previtem is defined and value > loop.previtem %}
        The value just increased!
    {% endif %}
    {{ value }}
    {% if loop.nextitem is defined and loop.nextitem > value %}
        The value will increase even more!
    {% endif %}
{% endfor %}

Nếu bạn chỉ quan tâm liệu giá trị có thay đổi hay không, việc sử dụng changedthậm chí còn dễ dàng hơn:

{% for entry in entries %}
    {% if loop.changed(entry.category) %}
        <h2>{{ entry.category }}</h2>
    {% endif %}
    <p>{{ entry.message }}</p>
{% endfor %}

Nếu như 

Câu iflệnh trong Jinja có thể so sánh với câu lệnh if của Python. Ở dạng đơn giản nhất, bạn có thể sử dụng nó để kiểm tra xem một biến có được xác định, không trống và không sai hay không:

{% if users %}
<ul>
{% for user in users %}
    <li>{{ user.username|e }}</li>
{% endfor %}
</ul>
{% endif %}

Dành cho nhiều nhánh elifvà elsecó thể được sử dụng như trong Python. Bạn cũng có thể sử dụng các Biểu thức phức tạp hơn ở đó:

{% if kenny.sick %}
    Kenny is sick.
{% elif kenny.dead %}
    You killed Kenny!  You bastard!!!
{% else %}
    Kenny looks okay --- so far
{% endif %}

If cũng có thể được sử dụng như một biểu thức nội tuyến và để lọc vòng lặp .

Macro 

Macro có thể so sánh với các hàm trong các ngôn ngữ lập trình thông thường. Chúng rất hữu ích khi đưa các thành ngữ thường được sử dụng vào các hàm có thể sử dụng lại để không lặp lại chính mình (“DRY”).

Đây là một ví dụ nhỏ về macro hiển thị thành phần biểu mẫu:

{% macro input(name, value='', type='text', size=20) -%}
    <input type="{{ type }}" name="{{ name }}" value="{{
        value|e }}" size="{{ size }}">
{%- endmacro %}

Macro sau đó có thể được gọi giống như một hàm trong không gian tên:

<p>{{ input('username') }}</p>
<p>{{ input('password', type='password') }}</p>

Nếu macro được xác định trong một mẫu khác thì trước tiên bạn phải nhập macro đó.

Bên trong macro, bạn có quyền truy cập vào ba biến đặc biệt:varargs

Nếu nhiều đối số vị trí được chuyển tới macro hơn số lượng được macro chấp nhận thì chúng sẽ trở thành varargsbiến đặc biệt dưới dạng danh sách các giá trị.kwargs

Giống như varargsnhưng đối với các đối số từ khóa. Tất cả các đối số từ khóa chưa được sử dụng sẽ được lưu trữ trong biến đặc biệt này.caller

Nếu macro được gọi từ thẻ cuộc gọi thì người gọi sẽ được lưu trữ trong biến này dưới dạng macro có thể gọi được.

Macro cũng tiết lộ một số chi tiết bên trong của chúng. Các thuộc tính sau đây có sẵn trên một đối tượng macro:name

Tên của macro. sẽ in .{{ input.name }}inputarguments

Một bộ tên của các đối số mà macro chấp nhận.catch_kwargs

Đây là truenếu macro chấp nhận các đối số từ khóa bổ sung (tức là: truy cập vào kwargsbiến đặc biệt).catch_varargs

Điều này xảy ra truenếu macro chấp nhận các đối số vị trí bổ sung (tức là: truy cập vào varargsbiến đặc biệt).caller

Điều này xảy ra truenếu macro truy cập vào callerbiến đặc biệt và có thể được gọi từ thẻ cuộc gọi .

Nếu tên macro bắt đầu bằng dấu gạch dưới thì tên đó sẽ không được xuất và không thể nhập được.

Do cách hoạt động của phạm vi trong Jinja, macro trong mẫu con không ghi đè macro trong mẫu gốc. Phần sau đây sẽ xuất ra “BỐ TRÍ”, không phải “CHILD”.

layout.txt

{% macro foo() %}LAYOUT{% endmacro %}
{% block body %}{% endblock %}

child.txt

{% extends 'layout.txt' %}
{% macro foo() %}CHILD{% endmacro %}
{% block body %}{{ foo() }}{% endblock %}

Gọi 

Trong một số trường hợp, việc chuyển macro sang macro khác có thể hữu ích. Với mục đích này, bạn có thể sử dụng callkhối đặc biệt. Ví dụ sau đây cho thấy một macro tận dụng chức năng cuộc gọi và cách sử dụng nó:

{% macro render_dialog(title, class='dialog') -%}
    <div class="{{ class }}">
        <h2>{{ title }}</h2>
        <div class="contents">
            {{ caller() }}
        </div>
    </div>
{%- endmacro %}

{% call render_dialog('Hello World') %}
    This is a simple dialog rendered by using a macro and
    a call block.
{% endcall %}

Cũng có thể chuyển các đối số trở lại khối cuộc gọi. Điều này làm cho nó hữu ích khi thay thế cho các vòng lặp. Nói chung, khối cuộc gọi hoạt động chính xác như một macro không có tên.

Dưới đây là ví dụ về cách sử dụng khối cuộc gọi với các đối số:

{% macro dump_users(users) -%}
    <ul>
    {%- for user in users %}
        <li><p>{{ user.username|e }}</p>{{ caller(user) }}</li>
    {%- endfor %}
    </ul>
{%- endmacro %}

{% call(user) dump_users(list_of_user) %}
    <dl>
        <dt>Realname</dt>
        <dd>{{ user.realname|e }}</dd>
        <dt>Description</dt>
        <dd>{{ user.description }}</dd>
    </dl>
{% endcall %}

Bộ lọc 

Phần bộ lọc cho phép bạn áp dụng các bộ lọc Jinja thông thường trên một khối dữ liệu mẫu. Chỉ cần bọc mã trong filterphần đặc biệt:

{% filter upper %}
    This text becomes uppercase
{% endfilter %}

Các bộ lọc chấp nhận đối số có thể được gọi như thế này:

{% filter center(100) %}Center this{% endfilter %}

Bài tập 

Bên trong các khối mã, bạn cũng có thể gán giá trị cho các biến. Các bài tập ở cấp cao nhất (bên ngoài khối, macro hoặc vòng lặp) được xuất từ ​​mẫu giống như macro cấp cao nhất và có thể được nhập bởi các mẫu khác.

Bài tập sử dụng setthẻ và có thể có nhiều mục tiêu:

{% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %}
{% set key, value = call_something() %}

Hành vi xác định phạm vi

Xin lưu ý rằng không thể đặt các biến bên trong một khối và để chúng hiển thị bên ngoài khối đó. Điều này cũng áp dụng cho các vòng lặp. Ngoại lệ duy nhất cho quy tắc đó là các câu lệnh if không đưa ra phạm vi. Kết quả là mẫu sau sẽ không thực hiện được những gì bạn mong đợi:

{% set iterated = false %}
{% for item in seq %}
    {{ item }}
    {% set iterated = true %}
{% endfor %}
{% if not iterated %} did not iterate {% endif %}

Cú pháp Jinja không thể thực hiện được điều này. Thay vào đó hãy sử dụng các cấu trúc thay thế như khối vòng lặp khác hoặc loopbiến đặc biệt:

{% for item in seq %}
    {{ item }}
{% else %}
    did not iterate
{% endfor %}

Kể từ phiên bản 2.10, các trường hợp sử dụng phức tạp hơn có thể được xử lý bằng cách sử dụng các đối tượng không gian tên cho phép truyền bá các thay đổi trên phạm vi:

{% set ns = namespace(found=false) %}
{% for item in items %}
    {% if item.check_something() %}
        {% set ns.found = true %}
    {% endif %}
    * {{ item.title }}
{% endfor %}
Found item having something: {{ ns.found }}

Lưu ý rằng obj.attrký hiệu trong setthẻ chỉ được phép đối với các đối tượng không gian tên; cố gắng gán một thuộc tính cho bất kỳ đối tượng nào khác sẽ gây ra một ngoại lệ.Nhật ký thay đổi

Khối bài tập 

Nhật ký thay đổi

Bắt đầu với Jinja 2.8, bạn cũng có thể sử dụng phép gán khối để chuyển nội dung của khối thành tên biến. Điều này có thể hữu ích trong một số trường hợp thay thế cho macro. Trong trường hợp đó, thay vì sử dụng dấu bằng và giá trị, bạn chỉ cần viết tên biến rồi viết mọi thứ cho đến khi được ghi lại.{% endset %}

Ví dụ:

{% set navigation %}
    <li><a href="/">Index</a>
    <li><a href="/downloads">Downloads</a>
{% endset %}

Sau đó, biến này navigationchứa nguồn HTML điều hướng.Nhật ký thay đổi

Bắt đầu với Jinja 2.10, việc gán khối hỗ trợ các bộ lọc.

Ví dụ:

{% set reply | wordwrap %}
    You wrote:
    {{ message }}
{% endset %}

Mở rộng 

Thẻ extendscó thể được sử dụng để mở rộng mẫu này sang mẫu khác. Bạn có thể có nhiều extendsthẻ trong một tệp, nhưng mỗi lần chỉ một trong số chúng có thể được thực thi.

Xem phần về Kế thừa mẫu ở trên.

Khối 

Các khối được sử dụng để kế thừa và đóng vai trò giữ chỗ và thay thế cùng một lúc. Chúng được ghi lại chi tiết trong phần Kế thừa Mẫu .

Bao gồm 

Thẻ includehiển thị một mẫu khác và xuất kết quả vào mẫu hiện tại.

{% include 'header.html' %}
Body goes here.
{% include 'footer.html' %}

Theo mặc định, mẫu đi kèm có quyền truy cập vào ngữ cảnh của mẫu hiện tại. Sử dụng để sử dụng một bối cảnh riêng biệt thay thế. cũng hợp lệ nhưng là hành vi mặc định. Xem Hành vi bối cảnh nhập .without contextwith context

Mẫu đi kèm có thể là extendmẫu khác và ghi đè các khối trong mẫu đó. Tuy nhiên, mẫu hiện tại không thể ghi đè bất kỳ khối nào mà mẫu đi kèm xuất ra.

Sử dụng để bỏ qua câu lệnh nếu mẫu không tồn tại. Nó phải được đặt trước một tuyên bố về khả năng hiển thị ngữ cảnh.ignore missing

{% include "sidebar.html" without context %}
{% include "sidebar.html" ignore missing %}
{% include "sidebar.html" ignore missing with context %}
{% include "sidebar.html" ignore missing without context %}

Nếu một danh sách các mẫu được đưa ra, mỗi mẫu sẽ được thử theo thứ tự cho đến khi không thiếu một mẫu nào. Điều này có thể được sử dụng để bỏ qua nếu không có mẫu nào tồn tại.ignore missing

{% include ['page_detailed.html', 'page.html'] %}
{% include ['special_sidebar.html', 'sidebar.html'] ignore missing %}

Một biến có tên mẫu hoặc đối tượng mẫu cũng có thể được truyền vào câu lệnh.

Nhập khẩu 

Jinja hỗ trợ đưa mã thường được sử dụng vào macro. Các macro này có thể đi vào các mẫu khác nhau và được nhập từ đó. Điều này hoạt động tương tự như các câu lệnh nhập trong Python. Điều quan trọng cần biết là quá trình nhập được lưu vào bộ nhớ đệm và các mẫu đã nhập không có quyền truy cập vào các biến mẫu hiện tại mà chỉ có quyền truy cập vào các biến chung theo mặc định. Để biết thêm chi tiết về hành vi ngữ cảnh của quá trình nhập và bao gồm, hãy xem Hành vi bối cảnh nhập .

Có hai cách để nhập mẫu. Bạn có thể nhập một mẫu hoàn chỉnh vào một biến hoặc yêu cầu các macro/biến được xuất cụ thể từ biến đó.

Hãy tưởng tượng chúng ta có một mô-đun trợ giúp hiển thị các biểu mẫu (được gọi là forms.html):

{% macro input(name, value='', type='text') -%}
    <input type="{{ type }}" value="{{ value|e }}" name="{{ name }}">
{%- endmacro %}

{%- macro textarea(name, value='', rows=10, cols=40) -%}
    <textarea name="{{ name }}" rows="{{ rows }}" cols="{{ cols
        }}">{{ value|e }}</textarea>
{%- endmacro %}

Cách dễ dàng và linh hoạt nhất để truy cập các biến và macro của mẫu là nhập toàn bộ mô-đun mẫu vào một biến. Bằng cách đó, bạn có thể truy cập các thuộc tính:

{% import 'forms.html' as forms %}
<dl>
    <dt>Username</dt>
    <dd>{{ forms.input('username') }}</dd>
    <dt>Password</dt>
    <dd>{{ forms.input('password', type='password') }}</dd>
</dl>
<p>{{ forms.textarea('comment') }}</p>

Ngoài ra, bạn có thể nhập tên cụ thể từ một mẫu vào không gian tên hiện tại:

{% from 'forms.html' import input as input_field, textarea %}
<dl>
    <dt>Username</dt>
    <dd>{{ input_field('username') }}</dd>
    <dt>Password</dt>
    <dd>{{ input_field('password', type='password') }}</dd>
</dl>
<p>{{ textarea('comment') }}</p>

Macro và biến bắt đầu bằng một hoặc nhiều dấu gạch dưới là riêng tư và không thể nhập được.Nhật ký thay đổi

Hành vi bối cảnh nhập khẩu 

Theo mặc định, các mẫu được bao gồm sẽ được chuyển qua ngữ cảnh hiện tại còn các mẫu đã nhập thì không. Lý do cho điều này là các nội dung nhập, không giống như bao gồm, được lưu vào bộ đệm; vì quá trình nhập thường được sử dụng giống như một mô-đun chứa macro.

Hành vi này có thể được thay đổi một cách rõ ràng: bằng cách thêm hoặc vào lệnh nhập/bao gồm, ngữ cảnh hiện tại có thể được chuyển tới mẫu và bộ nhớ đệm sẽ tự động bị tắt.with contextwithout context

Dưới đây là hai ví dụ:

{% from 'forms.html' import input with context %}
{% include 'header.html' without context %}

Ghi chú

Trong Jinja 2.0, ngữ cảnh được chuyển đến mẫu đi kèm không bao gồm các biến được xác định trong mẫu. Trên thực tế, điều này không hiệu quả:

{% for box in boxes %}
    {% include "render_box.html" %}
{% endfor %}

Mẫu đi kèm render_box.htmlkhông thể truy cập được boxtrong Jinja 2.0. Kể từ Jinja 2.1, render_box.html  thể làm như vậy.

Biểu thức 

Jinja cho phép các biểu thức cơ bản ở mọi nơi. Chúng hoạt động rất giống với Python thông thường; ngay cả khi bạn không làm việc với Python, bạn vẫn cảm thấy thoải mái với nó.

Chữ 

Hình thức biểu đạt đơn giản nhất là chữ. Literal là cách biểu diễn cho các đối tượng Python như chuỗi và số. Các chữ sau đây tồn tại:"Hello World"

Mọi thứ nằm giữa hai dấu ngoặc kép hoặc dấu ngoặc đơn đều là một chuỗi. Chúng hữu ích bất cứ khi nào bạn cần một chuỗi trong mẫu (ví dụ: làm đối số cho lệnh gọi hàm và bộ lọc hoặc chỉ để mở rộng hoặc bao gồm một mẫu).42/123_456

Số nguyên là số nguyên không có phần thập phân. Ký tự ‘_’ có thể được sử dụng để phân tách các nhóm cho dễ đọc.42.2342.1e2/123_456.789

Số dấu phẩy động có thể được viết bằng dấu ‘.’ dưới dạng dấu thập phân. Chúng cũng có thể được viết bằng ký hiệu khoa học với chữ ‘e’ viết hoa hoặc viết thường để biểu thị phần số mũ. Ký tự ‘_’ có thể được sử dụng để phân tách các nhóm cho dễ đọc, nhưng không thể sử dụng trong phần số mũ.['list', 'of', 'objects']

Mọi thứ giữa hai dấu ngoặc là một danh sách. Danh sách rất hữu ích cho việc lưu trữ dữ liệu tuần tự được lặp đi lặp lại. Ví dụ: bạn có thể dễ dàng tạo danh sách các liên kết bằng cách sử dụng danh sách và bộ dữ liệu cho (và với) vòng lặp for:

<ul>
{% for href, caption in [('index.html', 'Index'), ('about.html', 'About'),
                         ('downloads.html', 'Downloads')] %}
    <li><a href="{{ href }}">{{ caption }}</a></li>
{% endfor %}
</ul>

('tuple', 'of', 'values')

Các bộ dữ liệu giống như các danh sách không thể sửa đổi được (“bất biến”). Nếu một bộ chỉ có một mục thì sau nó phải có dấu phẩy ( ('1-tuple',)). Các bộ dữ liệu thường được sử dụng để biểu diễn các phần tử có từ hai phần tử trở lên. Xem ví dụ về danh sách ở trên để biết thêm chi tiết.{'dict': 'of', 'key': 'and', 'value': 'pairs'}

Lệnh trong Python là một cấu trúc kết hợp các khóa và giá trị. Khóa phải là duy nhất và luôn có chính xác một giá trị. Dict hiếm khi được sử dụng trong các mẫu; chúng hữu ích trong một số trường hợp hiếm hoi như bộ xmlattr()lọc.true/false

trueluôn đúng và falseluôn sai.

Ghi chú

Các hằng số đặc biệt truefalsevà nonethực sự là chữ thường. Bởi vì điều đó đã gây ra sự nhầm lẫn trong quá khứ, ( Trueđược sử dụng để mở rộng thành một biến không xác định được coi là sai), cả ba biến này giờ đây cũng có thể được viết bằng chữ thường ( TrueFalse, và None). Tuy nhiên, để thống nhất, (tất cả số nhận dạng Jinja đều là chữ thường), bạn nên sử dụng phiên bản chữ thường.

Toán học 

Jinja cho phép bạn tính toán bằng các giá trị. Điều này hiếm khi hữu ích trong các mẫu nhưng tồn tại vì mục đích hoàn chỉnh. Các toán tử sau được hỗ trợ:+

Thêm hai đối tượng lại với nhau. Thông thường các đối tượng là số, nhưng nếu cả hai đều là chuỗi hoặc danh sách, bạn có thể nối chúng theo cách này. Tuy nhiên, đây không phải là cách ưa thích để nối chuỗi! Để nối chuỗi, hãy xem ~toán tử. là .{{ 1 + 1 }}2-

Trừ số thứ hai từ số đầu tiên. là .{{ 3 - 2 }}1/

Chia hai số. Giá trị trả về sẽ là số dấu phẩy động. là .{{ 1 / 2 }}{{ 0.5 }}//

Chia hai số và trả về kết quả số nguyên bị cắt cụt. là .{{ 20 // 7 }}2%

Tính phần dư của phép chia số nguyên. là .{{ 11 % 7 }}4*

Nhân toán hạng bên trái với toán hạng bên phải. sẽ trở lại . Điều này cũng có thể được sử dụng để lặp lại một chuỗi nhiều lần. sẽ in một thanh gồm 80 dấu bằng.{{ 2 * 2 }}4{{ '=' * 80 }}**

Nâng toán hạng bên trái lên lũy thừa của toán hạng bên phải. sẽ trở lại .{{ 2**3 }}8

Không giống như Python, chuỗi chuỗi được đánh giá từ trái sang phải. được đánh giá như trong Jinja, nhưng sẽ được đánh giá như trong Python. Sử dụng dấu ngoặc đơn trong Jinja để nói rõ thứ tự bạn muốn. Thông thường, nên thực hiện phép toán mở rộng bằng Python và chuyển kết quả sang thay vì thực hiện nó trong mẫu.{{ 3**3**3 }}(3**3)**33**(3**3)render

Hành vi này có thể được thay đổi trong tương lai để phù hợp với Python, nếu có thể giới thiệu đường dẫn nâng cấp.

So sánh 

==

So sánh hai đối tượng để tìm sự bằng nhau.!=

So sánh hai đối tượng để tìm bất đẳng thức.>

truenếu vế trái lớn hơn vế phải.>=

truenếu vế trái lớn hơn hoặc bằng vế phải.<

truenếu phía bên trái thấp hơn phía bên phải.<=

truenếu vế trái thấp hơn hoặc bằng vế phải.

Hợp lý 

Đối với ifcác câu lệnh, forlọc và ifbiểu thức, việc kết hợp nhiều biểu thức có thể hữu ích:and

Trả về true nếu toán hạng bên trái và bên phải đều đúng.or

Trả về true nếu toán hạng bên trái hoặc bên phải là đúng.not

phủ định một tuyên bố (xem bên dưới).(expr)

Dấu ngoặc đơn nhóm một biểu thức.

Ghi chú

Các toán tử isvà cũng inhỗ trợ phủ định bằng cách sử dụng ký hiệu trung tố: và thay vì và . Tất cả các biểu thức khác yêu cầu ký hiệu tiền tố:foo is not barfoo not in barnot foo is barnot foo in barnot (foo and bar).

Các nhà khai thác khác 

Các toán tử sau đây rất hữu ích nhưng không phù hợp với bất kỳ loại nào trong hai loại còn lại:in

Thực hiện kiểm tra ngăn chặn trình tự/ánh xạ. Trả về true nếu toán hạng bên trái được chứa ở bên phải. ví dụ, sẽ trả về true.{{ 1 in [1, 2, 3] }}is

Thực hiện một bài kiểm tra .|(ống, thanh đứng)

Áp dụng một bộ lọc .~(dấu ngã)

Chuyển đổi tất cả toán hạng thành chuỗi và nối chúng.

{{ "Hello " ~ name ~ "!" }}sẽ trả về (giả sử nameđược đặt thành 'John') .Hello John!()

Gọi một cuộc gọi có thể gọi được: . Bên trong dấu ngoặc đơn, bạn có thể sử dụng các đối số vị trí và đối số từ khóa như trong Python:{{ post.render() }}

{{ post.render(user, full=true) }}../[]

Lấy một thuộc tính của một đối tượng. (Xem Biến )

Biểu thức If 

Cũng có thể sử dụng ifcác biểu thức nội tuyến. Đây là hữu ích trong một số tình huống. Ví dụ: bạn có thể sử dụng điều này để mở rộng từ một mẫu nếu một biến được xác định, nếu không thì từ mẫu bố cục mặc định:

{% extends layout_template if layout_template is defined else 'default.html' %}

Cú pháp chung là .<do something> if <something is true> else <do something else>

Phần này elselà tùy chọn. Nếu không được cung cấp, khối else sẽ ngầm đánh giá thành một Undefinedđối tượng (bất kể nội dung nào undefinedtrong môi trường được đặt thành):

{{ "[{}]".format(page.title) if page.title }}

Phương thức Python 

Bạn cũng có thể sử dụng bất kỳ phương thức nào được xác định trên loại biến. Giá trị được trả về từ lệnh gọi phương thức được sử dụng làm giá trị của biểu thức. Đây là một ví dụ sử dụng các phương thức được xác định trên chuỗi (trong đó page.titlecó một chuỗi):

{{ page.title.capitalize() }}

Điều này hoạt động đối với các phương thức trên các loại do người dùng xác định. Ví dụ: nếu biến thuộc floại Foocó một phương thức barđược xác định trên đó, bạn có thể thực hiện các thao tác sau:

{{ f.bar(value) }}

Phương thức vận hành cũng hoạt động như mong đợi. Ví dụ: %triển khai kiểu printf cho chuỗi:

{{ "Hello, %s!" % name }}

Mặc dù bạn nên thích .formatphương pháp này hơn cho trường hợp đó (điều này hơi phức tạp trong bối cảnh hiển thị mẫu):

{{ "Hello, {}!".format(name) }}

Danh sách các bộ lọc dựng sẵn 

abs()forceescape()map()select()unique()
attr()format()max()selectattr()upper()
batch()groupby()min()slice()urlencode()
capitalize()indent()pprint()sort()urlize()
center()int()random()string()wordcount()
default()items()reject()striptags()wordwrap()
dictsort()join()rejectattr()sum()xmlattr()
escape()last()replace()title()
filesizeformat()length()reverse()tojson()
first()list()round()trim()
float()lower()safe()truncate()

bộ lọc jinja. cơ bụng ( x , / ) 

Trả về giá trị tuyệt đối của đối số.bộ lọc jinja. attr ( obj : Any , name : str ) → jinja2.runtime.Und xác định | Bất kì 

Lấy một thuộc tính của một đối tượng. foo|attr("bar")hoạt động giống như foo.barluôn luôn có một thuộc tính được trả về và các mục không được tra cứu.

Xem Ghi chú về đăng ký để biết thêm chi tiết.bộ lọc jinja. batch ( value : ‘t.Iterable[V]’ , linecount : int , fill_with : ‘t.Optional[V]’ = None ) → ‘t.Iterator[t.List[V]]’

Một bộ lọc sắp xếp các mục. Nó hoạt động khá giống như slicecách khác. Nó trả về một danh sách các danh sách với số lượng mục nhất định. Nếu bạn cung cấp tham số thứ hai, tham số này sẽ được sử dụng để điền vào các mục còn thiếu. Xem ví dụ này:

<table>
{%- for row in items|batch(3, '&nbsp;') %}
  <tr>
  {%- for column in row %}
    <td>{{ column }}</td>
  {%- endfor %}
  </tr>
{%- endfor %}
</table>

bộ lọc jinja. viết hoa ( s : str ) → str

Viết hoa một giá trị. Ký tự đầu tiên sẽ là chữ hoa, tất cả các ký tự khác sẽ là chữ thường.bộ lọc jinja. center ( value : str , width : int = 80 ) → str

Căn giữa giá trị trong một trường có chiều rộng nhất định.bộ lọc jinja. mặc định ( value : V , default_value : V = ” , boolean : bool = False ) → V

Nếu giá trị không được xác định, nó sẽ trả về giá trị mặc định đã truyền, nếu không thì giá trị của biến:

{{ my_variable|default('my_variable is not defined') }}

Điều này sẽ xuất ra giá trị my_variablenếu biến được xác định, nếu không thì . Nếu bạn muốn sử dụng mặc định với các biến có giá trị sai, bạn phải đặt tham số thứ hai thành :'my_variable is not defined'true

{{ ''|default('the string was empty', true) }}

Nhật ký thay đổi

Bí danh :

dbộ lọc jinja. dictsort ( value : Ánh xạ [ K , V ] , case_sensitive : bool = False , by : ‘te.Literal[“key”, “value”]’ = ‘key’ , đảo ngược : bool = False ) → Danh sách Tuple [ K , V ] ] 

Sắp xếp một cặp chính tả và năng suất (khóa, giá trị). Các ký tự Python có thể không theo thứ tự bạn muốn hiển thị, vì vậy hãy sắp xếp chúng trước.

{% for key, value in mydict|dictsort %}
    sort the dict by key, case insensitive

{% for key, value in mydict|dictsort(reverse=true) %}
    sort the dict by key, case insensitive, reverse order

{% for key, value in mydict|dictsort(true) %}
    sort the dict by key, case sensitive

{% for key, value in mydict|dictsort(false, 'value') %}
    sort the dict by value, case insensitive

bộ lọc jinja. thoát ( giá trị ) 

Thay thế các ký tự &<>'và "trong chuỗi bằng các chuỗi an toàn HTML. Sử dụng tính năng này nếu bạn cần hiển thị văn bản có thể chứa các ký tự như vậy trong HTML.

Nếu đối tượng có một __html__phương thức, nó sẽ được gọi và giá trị trả về được coi là an toàn cho HTML.Thông số :

s – Một đối tượng được chuyển đổi thành chuỗi và thoát.Trả về :

Một Markupchuỗi có văn bản thoát.Bí danh :

ebộ lọc jinja. kích thước tập tin ( value : str float int , nhị phân : bool = False ) → str

Định dạng giá trị như kích thước tệp ‘con người có thể đọc được’ (tức là 13 kB, 4,1 MB, 102 Byte, v.v.). Mỗi tiền tố thập phân mặc định được sử dụng (Mega, Giga, v.v.), nếu tham số thứ hai được đặt thành Truetiền tố nhị phân được sử dụng (Mebi, Gibi).bộ lọc jinja. đầu tiên ( seq : ‘t.Iterable[V]’ ) → ‘t.Union[V, Undefined]’

Trả về mục đầu tiên của một chuỗi.bộ lọc jinja. float ( giá trị : Bất kỳ , mặc định : float = 0.0 ) → float

Chuyển đổi giá trị thành số dấu phẩy động. Nếu chuyển đổi không hoạt động, nó sẽ trả về 0.0. Bạn có thể ghi đè mặc định này bằng tham số đầu tiên.bộ lọc jinja. Forceescape ( value : ‘t.Union[str, HasHTML]’ ) → markupsafe.Markup

Thực thi thoát HTML. Điều này có thể sẽ tăng gấp đôi các biến thoát.bộ lọc jinja. định dạng ( value : str , * args : Any , ** kwargs : Any ) → str

Áp dụng các giá trị đã cho cho chuỗi định dạng kiểu printf , như .string % values

{{ "%s, %s!"|format(greeting, name) }}
Hello, World!

Trong hầu hết các trường hợp, việc sử dụng toán %tử hoặc str.format().

{{ "%s, %s!" % (greeting, name) }}
{{ "{}, {}!".format(greeting, name) }}

bộ lọc jinja. groupby ( value : ‘t.Iterable[V]’ , thuộc tính : str int , mặc định : Any | None = None , case_sensitive : bool = False ) → ‘t.List[_GroupTuple]’

Nhóm một chuỗi các đối tượng theo một thuộc tính bằng cách sử dụng itertools.groupby(). Thuộc tính có thể sử dụng ký hiệu dấu chấm để truy cập lồng nhau, như "address.city". Không giống như Python groupby, các giá trị được sắp xếp trước nên chỉ một nhóm được trả về cho mỗi giá trị duy nhất.

Ví dụ: danh sách Usercác đối tượng có citythuộc tính có thể được hiển thị theo nhóm. Trong ví dụ này, grouperđề cập đến citygiá trị của nhóm.

<ul>{% for city, items in users|groupby("city") %}
  <li>{{ city }}
    <ul>{% for user in items %}
      <li>{{ user.name }}
    {% endfor %}</ul>
  </li>
{% endfor %}</ul>

groupbymang lại các bộ dữ liệu có tên của , có thể được sử dụng thay cho việc giải nén bộ dữ liệu ở trên. là giá trị của thuộc tính và là các mục có giá trị đó.(grouper, list)grouperlist

<ul>{% for group in users|groupby("city") %}
  <li>{{ group.grouper }}: {{ group.list|join(", ") }}
{% endfor %}</ul>

Bạn có thể chỉ định một defaultgiá trị để sử dụng nếu một đối tượng trong danh sách không có thuộc tính đã cho.

<ul>{% for city, items in users|groupby("city", default="NY") %}
  <li>{{ city }}: {{ items|map(attribute="name")|join(", ") }}</li>
{% endfor %}</ul>

Giống như sort()bộ lọc, việc sắp xếp và nhóm theo mặc định không phân biệt chữ hoa chữ thường. Đối keyvới mỗi nhóm sẽ có trường hợp của mục đầu tiên trong nhóm giá trị đó. Ví dụ: nếu danh sách người dùng có thành phố thì nhóm “CA” sẽ có hai giá trị. Điều này có thể bị vô hiệu hóa bằng cách chuyển .["CA", "NY", "ca"]case_sensitive=True

Đã thay đổi ở phiên bản 3.1: Đã thêm tham case_sensitivesố. Theo mặc định, việc sắp xếp và nhóm không phân biệt chữ hoa chữ thường, khớp với các bộ lọc khác thực hiện so sánh.Nhật ký thay đổibộ lọc jinja. thụt lề ( s : str , width : int str = 4 , đầu tiên : bool = False , trống : bool = False ) → str

Trả về một bản sao của chuỗi với mỗi dòng thụt vào 4 dấu cách. Dòng đầu tiên và dòng trống không được thụt lề theo mặc định.Thông số :

  • chiều rộng – Số lượng khoảng trắng hoặc một chuỗi để thụt lề.
  • đầu tiên – Đừng bỏ qua việc thụt lề dòng đầu tiên.
  • trống – Đừng bỏ qua việc thụt dòng trống.

Nhật ký thay đổibộ lọc jinja. int ( giá trị : Bất kỳ , mặc định : int = 0 , base : int = 10 ) → int

Chuyển đổi giá trị thành một số nguyên. Nếu chuyển đổi không hoạt động, nó sẽ trả về 0. Bạn có thể ghi đè mặc định này bằng tham số đầu tiên. Bạn cũng có thể ghi đè cơ sở mặc định (10) trong tham số thứ hai, tham số này xử lý đầu vào với các tiền tố như 0b, 0o và 0x tương ứng cho các cơ sở 2, 8 và 16. Cơ số bị bỏ qua đối với số thập phân và giá trị không phải chuỗi.bộ lọc jinja. items ( value : Ánh xạ [ K , V ] | jinja2.runtime.Und xác định ) → Iterator [ Tuple [ K , V ] ] 

Trả về một trình vòng lặp trên các mục của ánh xạ.(key, value)

x|itemsgiống như x.items(), ngoại trừ nếu xkhông được xác định thì một trình vòng lặp trống sẽ được trả về.

Bộ lọc này hữu ích nếu bạn muốn mẫu được hiển thị khi triển khai Jinja bằng ngôn ngữ lập trình khác không có .items()phương thức trên loại ánh xạ của nó.

<dl>
{% for key, value in my_dict|items %}
    <dt>{{ key }}
    <dd>{{ value }}
{% endfor %}
</dl>

Đã thêm vào phiên bản 3.1.bộ lọc jinja. tham gia ( value : Iterable [ Any ] , d : str = ” , thuộc tính : str int | NoneType = None ) → str

Trả về một chuỗi là sự nối của các chuỗi trong chuỗi. Dấu phân cách giữa các phần tử là một chuỗi trống theo mặc định, bạn có thể xác định nó bằng tham số tùy chọn:

{{ [1, 2, 3]|join('|') }}
    -> 1|2|3

{{ [1, 2, 3]|join }}
    -> 123

Cũng có thể nối các thuộc tính nhất định của một đối tượng:

{{ users|join(', ', attribute='username') }}

Nhật ký thay đổibộ lọc jinja. cuối cùng ( seq : ‘t.Reversible[V]’ ) → ‘t.Union[V, Undefined]’

Trả về mục cuối cùng của một chuỗi.

Lưu ý: Không hoạt động với máy phát điện. Bạn có thể muốn chuyển đổi nó thành một danh sách một cách rõ ràng:

{{ data | selectattr('name', '==', 'Jinja') | list | last }}

bộ lọc jinja. độ dài ( obj , / ) 

Trả về số lượng mục trong một thùng chứa.Bí danh :

countbộ lọc jinja. danh sách ( value : ‘t.Iterable[V]’ ) → ‘t.List[V]’

Chuyển đổi giá trị thành một danh sách. Nếu đó là một chuỗi thì danh sách trả về sẽ là danh sách các ký tự.bộ lọc jinja. thấp hơn ( s : str ) → str

Chuyển đổi một giá trị thành chữ thường.bộ lọc jinja. map ( value : Iterable [ Any ] , * args : Any , ** kwargs : Any ) → Iterable [ Any ]

Áp dụng bộ lọc trên một chuỗi đối tượng hoặc tra cứu một thuộc tính. Điều này rất hữu ích khi xử lý danh sách các đối tượng nhưng bạn thực sự chỉ quan tâm đến một giá trị nhất định của nó.

Cách sử dụng cơ bản là ánh xạ trên một thuộc tính. Hãy tưởng tượng bạn có một danh sách người dùng nhưng bạn chỉ quan tâm đến danh sách tên người dùng:

Users on this page: {{ users|map(attribute='username')|join(', ') }}

Bạn có thể chỉ định một defaultgiá trị để sử dụng nếu một đối tượng trong danh sách không có thuộc tính đã cho.

{{ users|map(attribute="username", default="Anonymous")|join(", ") }}

Ngoài ra, bạn có thể cho phép nó gọi bộ lọc bằng cách chuyển tên của bộ lọc và các đối số sau đó. Một ví dụ điển hình là áp dụng bộ lọc chuyển đổi văn bản theo trình tự:

Users on this page: {{ titles|map('lower')|join(', ') }}

Tương tự như cách hiểu về trình tạo, chẳng hạn như:

(u.username for u in users)
(getattr(u, "username", "Anonymous") for u in users)
(do_lower(x) for x in titles)

Nhật ký thay đổibộ lọc jinja. max ( giá trị : ‘t.Iterable[V]’ , case_sensitive : bool = False , thuộc tính : str int | NoneType = None ) → ‘t.Union[V, Unfined]’

Trả về mục lớn nhất từ ​​chuỗi.

{{ [1, 2, 3]|max }}
    -> 3

Thông số :

  • case_sensitive – Phân biệt các chuỗi chữ hoa và chữ thường.
  • thuộc tính – Lấy đối tượng có giá trị tối đa của thuộc tính này.

bộ lọc jinja. min ( value : ‘t.Iterable[V]’ , case_sensitive : bool = False , thuộc tính : str int | NoneType = None ) → ‘t.Union[V, Undefind]’

Trả về mục nhỏ nhất từ ​​chuỗi.

{{ [1, 2, 3]|min }}
    -> 1

Thông số :

  • case_sensitive – Phân biệt các chuỗi chữ hoa và chữ thường.
  • thuộc tính – Lấy đối tượng có giá trị tối thiểu của thuộc tính này.

bộ lọc jinja. pprint ( giá trị : Bất kỳ ) → str

Khá in một biến. Hữu ích cho việc gỡ lỗi.bộ lọc jinja. ngẫu nhiên ( seq : ‘t.Sequence[V]’ ) → ‘t.Union[V, Không xác định]’

Trả về một mục ngẫu nhiên từ chuỗi.bộ lọc jinja. từ chối ( value : ‘t.Iterable[V]’ , * args : Any , ** kwargs : Any ) → ‘t.Iterator[V]’

Lọc một chuỗi các đối tượng bằng cách áp dụng thử nghiệm cho từng đối tượng và từ chối các đối tượng có thử nghiệm thành công.

Nếu không có thử nghiệm nào được chỉ định, mỗi đối tượng sẽ được đánh giá là boolean.

Cách sử dụng ví dụ:

{{ numbers|reject("odd") }}

Tương tự như cách hiểu về trình tạo, chẳng hạn như:

(n for n in numbers if not test_odd(n))

Nhật ký thay đổibộ lọc jinja. từ chối ( value : ‘t.Iterable[V]’ , * args : Any , ** kwargs : Any ) → ‘t.Iterator[V]’

Lọc một chuỗi các đối tượng bằng cách áp dụng thử nghiệm cho thuộc tính được chỉ định của từng đối tượng và từ chối các đối tượng có thử nghiệm thành công.

Nếu không có thử nghiệm nào được chỉ định thì giá trị của thuộc tính sẽ được đánh giá là boolean.

{{ users|rejectattr("is_active") }}
{{ users|rejectattr("email", "none") }}

Tương tự như cách hiểu về trình tạo, chẳng hạn như:

(u for user in users if not user.is_active)
(u for user in users if not test_none(user.email))

Nhật ký thay đổibộ lọc jinja. thay thế ( s : str , old : str , new : str , count : int None = None ) → str

Trả về bản sao của giá trị với tất cả các lần xuất hiện của chuỗi con được thay thế bằng chuỗi mới. Đối số đầu tiên là chuỗi con cần được thay thế, đối số thứ hai là chuỗi thay thế. Nếu đối số thứ ba tùy chọn countđược đưa ra thì chỉ countnhững lần xuất hiện đầu tiên được thay thế:

{{ "Hello World"|replace("Hello", "Goodbye") }}
    -> Goodbye World

{{ "aaaaargh"|replace("a", "d'oh, ", 2) }}
    -> d'oh, d'oh, aaargh

bộ lọc jinja. đảo ngược ( value : str | Iterable [ V ] ) → str | Có thể lặp lại [ V ] 

Đảo ngược đối tượng hoặc trả về một trình vòng lặp lặp lại đối tượng đó theo chiều ngược lại.bộ lọc jinja. vòng ( giá trị : float , độ chính xác : int = 0 , phương thức : ‘te.Literal[“common”, “ceil”, “floor”]’ = ‘common’ ) → float

Làm tròn số đến độ chính xác nhất định. Tham số đầu tiên chỉ định độ chính xác (mặc định là 0), tham số thứ hai là phương thức làm tròn:

  • 'common'làm tròn lên hoặc xuống
  • 'ceil'luôn làm tròn lên
  • 'floor'luôn làm tròn xuống

Nếu bạn không chỉ định một phương pháp 'common'sẽ được sử dụng.

{{ 42.55|round }}
    -> 43.0
{{ 42.55|round(1, 'floor') }}
    -> 42.5

Lưu ý rằng ngay cả khi được làm tròn đến độ chính xác 0, số float vẫn được trả về. Nếu bạn cần một số nguyên thực, hãy chuyển nó qua int:

{{ 42.55|round|int }}
    -> 43

bộ lọc jinja. an toàn ( giá trị : str ) → markupsafe.Markup

Đánh dấu giá trị là an toàn, điều đó có nghĩa là trong môi trường có bật tính năng thoát tự động, biến này sẽ không được thoát.bộ lọc jinja. select ( value : ‘t.Iterable[V]’ , * args : Any , ** kwargs : Any ) → ‘t.Iterator[V]’

Lọc một chuỗi các đối tượng bằng cách áp dụng thử nghiệm cho từng đối tượng và chỉ chọn các đối tượng có thử nghiệm thành công.

Nếu không có thử nghiệm nào được chỉ định, mỗi đối tượng sẽ được đánh giá là boolean.

Cách sử dụng ví dụ:

{{ numbers|select("odd") }}
{{ numbers|select("odd") }}
{{ numbers|select("divisibleby", 3) }}
{{ numbers|select("lessthan", 42) }}
{{ strings|select("equalto", "mystring") }}

Tương tự như cách hiểu về trình tạo, chẳng hạn như:

(n for n in numbers if test_odd(n))
(n for n in numbers if test_divisibleby(n, 3))

Nhật ký thay đổibộ lọc jinja. selectattr ( value : ‘t.Iterable[V]’ , * args : Any , ** kwargs : Any ) → ‘t.Iterator[V]’

Lọc một chuỗi các đối tượng bằng cách áp dụng thử nghiệm cho thuộc tính được chỉ định của từng đối tượng và chỉ chọn các đối tượng có thử nghiệm thành công.

Nếu không có thử nghiệm nào được chỉ định thì giá trị của thuộc tính sẽ được đánh giá là boolean.

Cách sử dụng ví dụ:

{{ users|selectattr("is_active") }}
{{ users|selectattr("email", "none") }}

Tương tự như cách hiểu về trình tạo, chẳng hạn như:

(u for user in users if user.is_active)
(u for user in users if test_none(user.email))

Nhật ký thay đổibộ lọc jinja. slice ( value : ‘t.Collection[V]’ , slice : int , fill_with : ‘t.Optional[V]’ = None ) → ‘t.Iterator[t.List[V]]’

Cắt một trình vòng lặp và trả về danh sách các danh sách chứa các mục đó. Hữu ích nếu bạn muốn tạo một div chứa ba thẻ ul đại diện cho các cột:

<div class="columnwrapper">
  {%- for column in items|slice(3) %}
    <ul class="column-{{ loop.index }}">
    {%- for item in column %}
      <li>{{ item }}</li>
    {%- endfor %}
    </ul>
  {%- endfor %}
</div>

Nếu bạn truyền cho nó một đối số thứ hai thì nó sẽ được dùng để điền các giá trị còn thiếu ở lần lặp cuối cùng.bộ lọc jinja. sắp xếp ( value : ‘t.Iterable[V]’ , đảo ngược : bool = False , case_sensitive : bool = False , thuộc tính : str int | NoneType = None ) → ‘t.List[V]’

Sắp xếp một lần lặp bằng cách sử dụng Python’s sorted().

{% for city in cities|sort %}
    ...
{% endfor %}

Thông số :

  • đảo ngược – Sắp xếp giảm dần thay vì tăng dần.
  • case_sensitive – Khi sắp xếp chuỗi, hãy sắp xếp riêng chữ hoa và chữ thường.
  • thuộc tính – Khi sắp xếp các đối tượng hoặc ký tự, một thuộc tính hoặc khóa để sắp xếp theo. Có thể sử dụng ký hiệu dấu chấm như "address.city". Có thể là danh sách các thuộc tính như "age,name".

Việc sắp xếp ổn định, không làm thay đổi thứ tự tương đối của các phần tử so sánh bằng nhau. Điều này giúp có thể sắp xếp theo chuỗi các thuộc tính và thứ tự khác nhau.

{% for user in users|sort(attribute="name")
    |sort(reverse=true, attribute="age") %}
    ...
{% endfor %}

Là một lối tắt để xâu chuỗi khi hướng giống nhau cho tất cả các thuộc tính, hãy chuyển danh sách thuộc tính được phân tách bằng dấu phẩy.

{% for user in users|sort(attribute="age,name") %}
    ...
{% endfor %}

Nhật ký thay đổibộ lọc jinja. Chuỗi giá trị ) 

Chuyển đổi một đối tượng thành một chuỗi nếu nó chưa có. Điều này bảo tồn một Markupchuỗi thay vì chuyển đổi nó trở lại chuỗi cơ bản, vì vậy nó sẽ vẫn được đánh dấu là an toàn và sẽ không bị thoát nữa.

>>> value = escape("<User 1>")
>>> value
Markup('&lt;User 1&gt;')
>>> escape(str(value))
Markup('&amp;lt;User 1&amp;gt;')
>>> escape(soft_str(value))
Markup('&lt;User 1&gt;')

bộ lọc jinja. thẻ thoát y ( value : ‘t.Union[str, HasHTML]’ ) → str

Loại bỏ các thẻ SGML/XML và thay thế khoảng trắng liền kề bằng một khoảng trắng.bộ lọc jinja. sum ( iterable : ‘t.Iterable[V]’ , thuộc tính : str int | NoneType = None , start : V = 0 ) → V

Trả về tổng của một chuỗi số cộng với giá trị của tham số ‘bắt đầu’ (mặc định là 0). Khi chuỗi trống nó trả về bắt đầu.

Cũng có thể chỉ tổng hợp một số thuộc tính nhất định:

Total: {{ items|sum(attribute='price') }}

Nhật ký thay đổibộ lọc jinja. tiêu đề ( s : str ) → str

Trả về phiên bản có tiêu đề của giá trị. Tức là các từ sẽ bắt đầu bằng chữ in hoa, tất cả các ký tự còn lại là chữ thường.bộ lọc jinja. tojson ( value : Any , thụt lề : int None = None ) → markupsafe.Markup

Tuần tự hóa một đối tượng thành một chuỗi JSON và đánh dấu nó là an toàn để hiển thị dưới dạng HTML. Bộ lọc này chỉ được sử dụng trong các tài liệu HTML.

Chuỗi trả về an toàn để hiển thị trong tài liệu và <script>thẻ HTML. Ngoại lệ là ở các thuộc tính HTML được trích dẫn kép; sử dụng dấu ngoặc đơn hoặc |forceescapebộ lọc.Thông số :

  • value – Đối tượng cần tuần tự hóa thành JSON.
  • thụt lề – indentTham số được truyền tới dumps, để in giá trị đẹp.

Nhật ký thay đổibộ lọc jinja. cắt ( giá trị : str , ký tự : str None = None ) → str

Loại bỏ các ký tự đầu và cuối, theo mặc định là khoảng trắng.bộ lọc jinja. cắt ngắn ( s : str , length : int = 255 , killwords : bool = False , end : str = ‘…’ , leeway : int None = None ) → str

Trả về bản sao bị cắt ngắn của chuỗi. Độ dài được chỉ định với tham số đầu tiên mặc định là 255. Nếu tham số thứ hai là truebộ lọc sẽ cắt văn bản theo chiều dài. Nếu không nó sẽ loại bỏ từ cuối cùng. Nếu văn bản trên thực tế đã bị cắt bớt thì nó sẽ thêm dấu chấm lửng ( "..."). Nếu bạn muốn một dấu chấm lửng khác với dấu chấm lửng, "..."bạn có thể chỉ định nó bằng tham số thứ ba. Các chuỗi chỉ vượt quá độ dài bằng giới hạn dung sai được đưa ra trong tham số thứ tư sẽ không bị cắt bớt.

{{ "foo bar baz qux"|truncate(9) }}
    -> "foo..."
{{ "foo bar baz qux"|truncate(9, True) }}
    -> "foo ba..."
{{ "foo bar baz qux"|truncate(11) }}
    -> "foo bar baz qux"
{{ "foo bar baz qux"|truncate(11, False, '...', 0) }}
    -> "foo bar..."

Thời gian chờ mặc định trên các phiên bản Jinja mới hơn là 5 và trước đó là 0 nhưng có thể được cấu hình lại trên toàn cầu.bộ lọc jinja. duy nhất ( value : ‘t.Iterable[V]’ , case_sensitive : bool = False , thuộc tính : str int | NoneType = None ) → ‘t.Iterator[V]’

Trả về danh sách các mục duy nhất từ ​​lần lặp đã cho.

{{ ['foo', 'bar', 'foobar', 'FooBar']|unique|list }}
    -> ['foo', 'bar', 'foobar']

Các mục duy nhất được tạo ra theo cùng thứ tự với lần xuất hiện đầu tiên của chúng trong vòng lặp được truyền tới bộ lọc.Thông số :

  • case_sensitive – Phân biệt các chuỗi chữ hoa và chữ thường.
  • thuộc tính – Lọc các đối tượng có giá trị duy nhất cho thuộc tính này.

bộ lọc jinja. trên ( s : str ) → str

Chuyển đổi một giá trị thành chữ hoa.bộ lọc jinja. urlencode ( value : str | Ánh xạ [ str , Any ] | Iterable [ Tuple str , Any ] ] ) → str

Trích dẫn dữ liệu để sử dụng trong đường dẫn URL hoặc truy vấn bằng UTF-8.

Trình bao bọc cơ bản xung quanh urllib.parse.quote()khi được cung cấp một chuỗi hoặc urllib.parse.urlencode()cho một lệnh chính tả hoặc có thể lặp lại.Thông số :

value – Dữ liệu để báo giá. Một chuỗi sẽ được trích dẫn trực tiếp. Một cặp dict hoặc iterable sẽ được nối dưới dạng chuỗi truy vấn.(key, value)

Khi đưa ra một chuỗi, “/” không được trích dẫn. Máy chủ HTTP xử lý “/” và “%2F” tương đương trong đường dẫn. Nếu bạn cần dấu gạch chéo được trích dẫn, hãy sử dụng bộ lọc.|replace("/", "%2F")Nhật ký thay đổibộ lọc jinja. urlize ( value : str , Trim_url_limit : int None = None , nofollow : bool = False , target : str None = None , rel : str None = None , extra_schemes : Iterable [ str ] | None = None ) → str

Chuyển đổi URL trong văn bản thành các liên kết có thể nhấp được.

Điều này có thể không nhận ra các liên kết trong một số trường hợp. Thông thường, một trình định dạng toàn diện hơn, chẳng hạn như thư viện Markdown, sẽ là lựa chọn tốt hơn.

Hoạt động trên http://https://www.và mailto:địa chỉ email. Các liên kết có dấu chấm câu ở cuối (dấu chấm, dấu phẩy, dấu ngoặc đơn đóng) và dấu câu ở đầu (dấu ngoặc đơn mở) được nhận dạng ngoại trừ dấu câu. Địa chỉ email bao gồm các trường tiêu đề không được nhận dạng (ví dụ: mailto:address@example.com?cc=copy@example.com).Thông số :

  • value – Văn bản gốc chứa URL cần liên kết.
  • Trim_url_limit – Rút ngắn các giá trị URL được hiển thị theo độ dài này.
  • nofollow – Thêm thuộc rel=nofollowtính vào liên kết.
  • target – Thêm thuộc targettính vào liên kết.
  • rel – Thêm thuộc reltính vào liên kết.
  • extra_schemes – Nhận dạng các URL bắt đầu bằng các lược đồ này ngoài hành vi mặc định. Mặc định là env.policies["urlize.extra_schemes"], mặc định không có lược đồ bổ sung.

Nhật ký thay đổibộ lọc jinja. số từ ( s : str ) → int

Đếm các từ trong chuỗi đó.bộ lọc jinja. wordwrap ( s : str , width : int = 79 , break_long_words : bool = True , Wrapstring : str None = None , break_on_hyphens : bool = True ) → str

Quấn một chuỗi theo chiều rộng nhất định. Các dòng mới hiện tại được coi là các đoạn văn được gói riêng.Thông số :

  • s – Văn bản gốc cần ngắt dòng.
  • chiều rộng – Chiều dài tối đa của các đường được gói.
  • break_long_words – Nếu một từ dài hơn width, hãy chia nó thành các dòng.
  • break_on_hyphens – Nếu một từ chứa dấu gạch nối, từ đó có thể được chia thành các dòng.
  • Wrapstring – Chuỗi để nối mỗi dòng được gói. Mặc định là Environment.newline_sequence.

Nhật ký thay đổibộ lọc jinja. xmlattr ( d : Ánh xạ [ str , Any ] , autospace : bool = True ) → str

Tạo chuỗi thuộc tính SGML/XML dựa trên các mục trong một lệnh.

Các giá trị không phải nonehoặc không undefinedđược thoát tự động, cho phép người dùng nhập dữ liệu không đáng tin cậy một cách an toàn.

Không nên sử dụng đầu vào của người dùng làm chìa khóa cho bộ lọc này. Nếu bất kỳ khóa nào chứa dấu cách, /dấu gạch chéo, >dấu lớn hơn hoặc =dấu bằng thì thao tác này không thành công với dấu ValueError. Bất kể điều này, thông tin đầu vào của người dùng không bao giờ được sử dụng làm khóa cho bộ lọc này hoặc phải được xác thực riêng trước.

<ul{{ {'class': 'my_list', 'missing': none,
        'id': 'list-%d'|format(variable)}|xmlattr }}>
...
</ul>

Kết quả là một cái gì đó như thế này:

<ul class="my_list" id="list-42">
...
</ul>

Như bạn có thể thấy, nó tự động thêm một khoảng trắng phía trước mục nếu bộ lọc trả về thứ gì đó trừ khi tham số thứ hai là sai.

Đã thay đổi trong phiên bản 3.1.4: Không cho phép các khóa có /dấu gạch nối, >dấu lớn hơn hoặc dấu bằng.=

Đã thay đổi trong phiên bản 3.1.3: Không được phép sử dụng phím có dấu cách.

Danh sách các bài kiểm tra dựng sẵn 

boolean()even()in()mapping()sequence()
callable()false()integer()ne()string()
defined()filter()iterable()none()test()
divisibleby()float()le()number()true()
eq()ge()lower()odd()undefined()
escaped()gt()lt()sameas()upper()

jinja-tests. boolean ( giá trị : Bất kỳ ) → bool

Trả về true nếu đối tượng là giá trị boolean.Nhật ký thay đổijinja-tests. có thể gọi được ( obj , / ) 

Trả về xem đối tượng có thể gọi được hay không (tức là một loại hàm nào đó).

Lưu ý rằng các lớp có thể gọi được, cũng như các thể hiện của các lớp có phương thức __call__().jinja-tests. được xác định ( value : Any ) → bool

Trả về true nếu biến được xác định:

{% if variable is defined %}
    value of variable: {{ variable }}
{% else %}
    variable is not defined
{% endif %}

Xem default()bộ lọc để biết cách đơn giản để đặt các biến không xác định.jinja-tests. chia hết cho ( value : int , num : int ) → bool

Kiểm tra xem một biến có chia hết cho một số hay không.jinja-tests. eq ( a , b , / ) 

Giống như a == b.Bí danh :

==,equaltojinja-tests. đã thoát ( value : Any ) → bool

Kiểm tra xem giá trị có được thoát hay không.jinja-tests. chẵn ( giá trị : int ) → bool

Trả về true nếu biến là số chẵn.jinja-tests. sai ( giá trị : Bất kỳ ) → bool

Trả về true nếu đối tượng là Sai.Nhật ký thay đổijinja-tests. bộ lọc ( giá trị : str ) → bool

Kiểm tra xem bộ lọc có tồn tại theo tên hay không. Hữu ích nếu một bộ lọc có thể có sẵn tùy chọn.

{% if 'markdown' is filter %}
    {{ value | markdown }}
{% else %}
    {{ value }}
{% endif %}

Nhật ký thay đổijinja-tests. float ( giá trị : Bất kỳ ) → bool

Trả về true nếu đối tượng là float.Nhật ký thay đổijinja-tests. ge ( a , b , / ) 

Tương tự như a >= b.Bí danh :

>=jinja-tests. gt ( a , b , / ) 

Tương tự như a > b.Bí danh :

>,greaterthanjinja-tests. in ( value : Any , seq : Container [ Any ] ) → bool

Kiểm tra xem giá trị có ở dạng seq không.Nhật ký thay đổijinja-tests. số nguyên ( giá trị : Bất kỳ ) → bool

Trả về true nếu đối tượng là số nguyên.Nhật ký thay đổijinja-tests. có thể lặp lại ( value : Any ) → bool

Kiểm tra xem có thể lặp lại một đối tượng hay không.jinja-tests. le ( a , b , / ) 

Tương tự như a <= b.Bí danh :

<=jinja-tests. thấp hơn ( giá trị : str ) → bool

Trả về true nếu biến được viết thường.jinja-tests. lt ( a , b , / ) 

Tương tự như a < b.Bí danh :

<,lessthanjinja-tests. ánh xạ ( value : Any ) → bool

Trả về true nếu đối tượng là ánh xạ (dict, v.v.).Nhật ký thay đổijinja-tests. ne ( a , b , / ) 

Tương tự như a != b.Bí danh :

!=jinja-tests. không có ( giá trị : Bất kỳ ) → bool

Trả về true nếu biến không có giá trị nào.jinja-tests. số ( giá trị : Bất kỳ ) → bool

Trả về true nếu biến là số.jinja-tests. lẻ ( giá trị : int ) → bool

Trả về true nếu biến là số lẻ.jinja-tests. Sameas ( value : Any , other : Any ) → bool

Kiểm tra xem một đối tượng có trỏ đến cùng địa chỉ bộ nhớ với đối tượng khác hay không:

{% if foo.attribute is sameas false %}
    the foo attribute really is the `False` singleton
{% endif %}

jinja-tests. chuỗi ( giá trị : Bất kỳ ) → bool

Trả về true nếu biến là một chuỗi. Trình tự là các biến có thể lặp lại được.jinja-tests. chuỗi ( giá trị : Bất kỳ ) → bool

Trả về true nếu đối tượng là một chuỗi.jinja-tests. kiểm tra ( giá trị : str ) → bool

Kiểm tra xem bài kiểm tra có tồn tại theo tên hay không. Hữu ích nếu một bài kiểm tra có thể có sẵn tùy chọn.

{% if 'loud' is test %}
    {% if value is loud %}
        {{ value|upper }}
    {% else %}
        {{ value|lower }}
    {% endif %}
{% else %}
    {{ value }}
{% endif %}

Nhật ký thay đổijinja-tests. true ( giá trị : Bất kỳ ) → bool

Trả về true nếu đối tượng là True.Nhật ký thay đổijinja-tests. không xác định ( giá trị : Bất kỳ ) → bool

Giống như defined()nhưng ngược lại.jinja-tests. trên ( giá trị : str ) → bool

Trả về true nếu biến được viết hoa.

Danh sách các hàm toàn cục 

Các hàm sau có sẵn trong phạm vi toàn cục theo mặc định:jinja-toàn cầu. phạm vi ( [ bắt đầu , ] dừng [ , bước ] ) 

Trả về một danh sách chứa cấp số cộng của các số nguyên. trở lại ; bắt đầu (!) mặc định là . Khi bước được đưa ra, nó chỉ định mức tăng (hoặc giảm). Ví dụ: và trả về . Điểm cuối bị bỏ qua! Đây chính xác là các chỉ số hợp lệ cho danh sách 4 phần tử.range(i, j)[i, i+1, i+2, ..., j-1]0range(4)range(0, 4, 1)[0, 1, 2, 3]

Điều này rất hữu ích khi lặp lại một khối mẫu nhiều lần, ví dụ như để điền vào danh sách. Hãy tưởng tượng bạn có 7 người dùng trong danh sách nhưng bạn muốn hiển thị ba mục trống để thực thi chiều cao bằng CSS:

<ul>
{% for user in users %}
    <li>{{ user.username }}</li>
{% endfor %}
{% for number in range(10 - users|count) %}
    <li class="empty"><span>...</span></li>
{% endfor %}
</ul>

jinja-toàn cầu. lipum ( n = 5 , html = True , min = 20 , max = 100 ) 

Tạo một số ipsum lorem cho mẫu. Theo mặc định, năm đoạn HTML được tạo với mỗi đoạn từ 20 đến 100 từ. Nếu html sai, văn bản thông thường sẽ được trả về. Điều này rất hữu ích để tạo nội dung đơn giản cho việc kiểm tra bố cục.jinja-toàn cầu. dict ( \**items ) 

Một sự thay thế thuận tiện cho chữ chính tả. cũng giống như .{'foo': 'bar'}dict(foo='bar')lớp jinja-globals. người đi xe đạp ( \*items ) 

Xoay vòng qua các giá trị bằng cách cung cấp từng giá trị một, sau đó khởi động lại sau khi đạt đến điểm cuối.

Tương tự như loop.cycle, nhưng có thể được sử dụng bên ngoài vòng lặp hoặc trên nhiều vòng lặp. Ví dụ: hiển thị danh sách các thư mục và tệp trong một danh sách, xen kẽ các lớp “lẻ” và “chẵn”.

{% set row_class = cycler("odd", "even") %}
<ul class="browser">
{% for folder in folders %}
  <li class="folder {{ row_class.next() }}">{{ folder }}
{% endfor %}
{% for file in files %}
  <li class="file {{ row_class.next() }}">{{ file }}
{% endfor %}
</ul>

Thông số :

mục – Mỗi đối số vị trí sẽ được cung cấp theo thứ tự nhất định cho mỗi chu kỳ.Nhật ký thay đổitài sản hiện tại

Trả lại mục hiện tại. Tương đương với vật phẩm sẽ được trả lại vào lần sau next()được gọi.Kế tiếp ( ) 

Trả lại mục hiện tại, sau đó chuyển currentsang mục tiếp theo.cài lại ( ) 

Đặt lại mục hiện tại về mục đầu tiên.lớp jinja-globals. người nối ( sep = ‘, ‘ ) 

Một công cụ trợ giúp nhỏ có thể được sử dụng để “nối” nhiều phần. Trình nối được truyền một chuỗi và sẽ trả về chuỗi đó mỗi lần nó được gọi, ngoại trừ lần đầu tiên (trong trường hợp đó nó trả về một chuỗi trống). Bạn có thể sử dụng điều này để tham gia mọi thứ:

{% set pipe = joiner("|") %}
{% if categories %} {{ pipe() }}
    Categories: {{ categories|join(", ") }}
{% endif %}
{% if author %} {{ pipe() }}
    Author: {{ author() }}
{% endif %}
{% if can_edit %} {{ pipe() }}
    <a href="?action=edit">Edit</a>
{% endif %}

Nhật ký thay đổilớp jinja-globals. không gian tên (  ) 

Tạo vùng chứa mới cho phép gán thuộc tính bằng thẻ :{% set %}

{% set ns = namespace() %}
{% set ns.foo = 'bar' %}

Mục đích chính của việc này là cho phép mang một giá trị từ bên trong thân vòng lặp ra phạm vi bên ngoài. Các giá trị ban đầu có thể được cung cấp dưới dạng lệnh, dưới dạng đối số từ khóa hoặc cả hai (hành vi tương tự như dicthàm tạo của Python):

{% set ns = namespace(found=false) %}
{% for item in items %}
    {% if item.check_something() %}
        {% set ns.found = true %}
    {% endif %}
    * {{ item.title }}
{% endfor %}
Found item having something: {{ ns.found }}

Nhật ký thay đổi

Tiện ích mở rộng 

Các phần sau đây đề cập đến các tiện ích mở rộng Jinja tích hợp có thể được ứng dụng kích hoạt. Ứng dụng cũng có thể cung cấp thêm các tiện ích mở rộng không có trong tài liệu này; trong trường hợp đó cần có một tài liệu riêng giải thích các phần mở rộng nói trên .

i18n 

Nếu Tiện ích mở rộng i18n được bật, bạn có thể đánh dấu văn bản trong mẫu là có thể dịch được. Để đánh dấu một phần là có thể dịch được, hãy sử dụng một transkhối:

{% trans %}Hello, {{ user }}!{% endtrans %}

Bên trong khối, không được phép có câu lệnh nào, chỉ có văn bản và các thẻ biến đơn giản.

Thẻ biến chỉ có thể là tên chứ không phải quyền truy cập thuộc tính, bộ lọc hoặc các biểu thức khác. Để sử dụng một biểu thức, hãy liên kết nó với một tên trong transthẻ để sử dụng trong khối.

{% trans user=user.username %}Hello, {{ user }}!{% endtrans %}

Để liên kết nhiều biểu thức, hãy phân tách từng biểu thức bằng dấu phẩy ( ,).

{% trans book_title=book.title, author=author.name %}
This is {{ book_title }} by {{ author }}
{% endtrans %}

Để số nhiều, hãy chỉ định cả dạng số ít và số nhiều được phân tách bằng thẻ pluralize.

{% trans count=list|length %}
There is {{ count }} {{ name }} object.
{% pluralize %}
There are {{ count }} {{ name }} objects.
{% endtrans %}

Theo mặc định, biến đầu tiên trong khối được sử dụng để xác định nên sử dụng dạng số ít hay số nhiều. Nếu điều đó không đúng, hãy chỉ định biến được sử dụng để số nhiều làm tham số cho pluralize.

{% trans ..., user_count=users|length %}...
{% pluralize user_count %}...{% endtrans %}

Khi dịch các khối văn bản, khoảng trắng và ngắt dòng dẫn đến chuỗi dịch khó đọc và dễ bị lỗi. Để tránh điều này, một khối chuyển đổi có thể được đánh dấu là đã cắt bớt, khối này sẽ thay thế tất cả các dấu ngắt dòng và khoảng trắng xung quanh chúng bằng một khoảng trắng duy nhất và loại bỏ khoảng trắng ở đầu và cuối.

{% trans trimmed book_title=book.title %}
    This is {{ book_title }}.
    You should read it!
{% endtrans %}

Điều này dẫn đến tập tin dịch.This is %(book_title)s. You should read it!

Nếu tính năng cắt xén được bật trên toàn cầu, notrimmedcông cụ sửa đổi có thể được sử dụng để tắt tính năng này cho một khối.Nhật ký thay đổi

Nếu bản dịch phụ thuộc vào ngữ cảnh mà thông báo xuất hiện, thì các hàm pgettextvà npgettextsẽ lấy một contextchuỗi làm đối số đầu tiên, đối số này được sử dụng để chọn bản dịch thích hợp. Để chỉ định ngữ cảnh bằng thẻ, hãy cung cấp một chuỗi làm mã thông báo đầu tiên sau .{% trans %}trans

{% trans "fruit" %}apple{% endtrans %}
{% trans "fruit" trimmed count -%}
    1 apple
{%- pluralize -%}
    {{ count }} apples
{%- endtrans %}

Đã thêm trong phiên bản 3.1: Ngữ cảnh có thể được chuyển vào transthẻ để sử dụng pgettextvà npgettext.

Có thể dịch các chuỗi trong biểu thức bằng các hàm sau:

  • _(message): Bí danh cho gettext.
  • gettext(message): Dịch tin nhắn.
  • ngettext(singluar, plural, n): Dịch tin nhắn số ít hoặc số nhiều dựa trên biến đếm.
  • pgettext(context, message): Giống như gettext(), nhưng chọn bản dịch dựa trên chuỗi ngữ cảnh.
  • npgettext(context, singular, plural, n): Giống như npgettext(), nhưng chọn bản dịch dựa trên chuỗi ngữ cảnh.

Bạn có thể in một chuỗi dịch như thế này:

{{ _("Hello, World!") }}

Để sử dụng phần giữ chỗ, hãy sử dụng bộ formatlọc.

{{ _("Hello, %(user)s!")|format(user=user.username) }}

Luôn sử dụng đối số từ khóa để format, vì các ngôn ngữ khác có thể không sử dụng các từ theo cùng thứ tự.

Nếu cuộc gọi Gettext Kiểu Mới được kích hoạt, việc sử dụng trình giữ chỗ sẽ dễ dàng hơn. Định dạng là một phần của gettextcuộc gọi thay vì sử dụng bộ formatlọc.

{{ gettext('Hello World!') }}
{{ gettext('Hello %(name)s!', name='World') }}
{{ ngettext('%(num)d apple', '%(num)d apples', apples|count) }}

Chuỗi định dạng của hàm ngettexttự động nhận số đếm dưới dạng numtham số bên cạnh các tham số đã cho.

Tuyên bố biểu thức 

Nếu phần mở rộng câu lệnh biểu thức được tải, một thẻ có tên dosẽ có sẵn hoạt động chính xác như biểu thức biến thông thường ( ); ngoại trừ nó không in bất cứ điều gì. Điều này có thể được sử dụng để sửa đổi danh sách:{{ ... }}

{% do navigation.append('a string') %}

Điều khiển vòng lặp 

Nếu ứng dụng bật Điều khiển vòng lặp thì có thể sử dụng vòng lặp breakand continuein. Khi breakđạt đến mức đó, vòng lặp kết thúc; nếu continueđạt được thì quá trình xử lý sẽ dừng lại và tiếp tục với lần lặp tiếp theo.

Đây là một vòng lặp bỏ qua mọi mục thứ hai:

{% for user in users %}
    {%- if loop.index is even %}{% continue %}{% endif %}
    ...
{% endfor %}

Tương tự, một vòng lặp dừng xử lý sau lần lặp thứ 10:

{% for user in users %}
    {%- if loop.index >= 10 %}{% break %}{% endif %}
{%- endfor %}

Lưu ý rằng loop.indexbắt đầu bằng 1 và loop.index0bắt đầu bằng 0 (Xem: For ).

Tuyên bố gỡ lỗi 

Nếu Tiện ích mở rộng gỡ lỗi được bật, một thẻ sẽ có sẵn để kết xuất ngữ cảnh hiện tại cũng như các bộ lọc và thử nghiệm có sẵn. Điều này rất hữu ích để xem những gì có sẵn để sử dụng trong mẫu mà không cần thiết lập trình gỡ lỗi.{% debug %}

<pre>{% debug %}</pre>
{'context': {'cycler': <class 'jinja2.utils.Cycler'>,
             ...,
             'namespace': <class 'jinja2.utils.Namespace'>},
 'filters': ['abs', 'attr', 'batch', 'capitalize', 'center', 'count', 'd',
             ..., 'urlencode', 'urlize', 'wordcount', 'wordwrap', 'xmlattr'],
 'tests': ['!=', '<', '<=', '==', '>', '>=', 'callable', 'defined',
           ..., 'odd', 'sameas', 'sequence', 'string', 'undefined', 'upper']}

Với Tuyên bố 

Nhật ký thay đổi

Câu lệnh with cho phép tạo một phạm vi bên trong mới. Các biến được đặt trong phạm vi này sẽ không hiển thị bên ngoài phạm vi.

Tóm lại:

{% with %}
    {% set foo = 42 %}
    {{ foo }}           foo is 42 here
{% endwith %}
foo is not visible here any longer

Vì thông thường việc đặt các biến ở đầu phạm vi nên bạn có thể thực hiện điều đó trong câu withlệnh. Hai ví dụ sau là tương đương:

{% with foo = 42 %}
    {{ foo }}
{% endwith %}

{% with %}
    {% set foo = 42 %}
    {{ foo }}
{% endwith %}

Một lưu ý quan trọng về phạm vi ở đây. Trong các phiên bản Jinja trước 2.9, hành vi tham chiếu biến này sang biến khác đã gây ra một số hậu quả không lường trước được. Cụ thể, một biến có thể tham chiếu đến một biến khác được xác định giống với câu lệnh mở đầu của khối. Điều này gây ra vấn đề với hành vi xác định phạm vi đã được làm sạch và từ đó đã được cải thiện. Đặc biệt trong các phiên bản Jinja mới hơn, đoạn mã sau luôn đề cập đến biến atừ bên ngoài withkhối:

{% with a={}, b=a.attribute %}...{% endwith %}

Trong các phiên bản Jinja trước đó, bthuộc tính sẽ đề cập đến kết quả của thuộc tính đầu tiên. Nếu bạn phụ thuộc vào hành vi này, bạn có thể viết lại nó để sử dụng thẻ set:

{% with a={} %}
    {% set b = a.attribute %}
{% endwith %}

Sự mở rộng

Trong các phiên bản cũ hơn của Jinja (trước 2.9), tính năng này được yêu cầu kích hoạt bằng tiện ích mở rộng. Bây giờ nó được bật theo mặc định.

Ghi đè tự động thoát 

Nhật ký thay đổi

Nếu muốn, bạn có thể kích hoạt và hủy kích hoạt tính năng tự động thoát từ bên trong các mẫu.

Ví dụ:

{% autoescape true %}
    Autoescaping is active within this block
{% endautoescape %}

{% autoescape false %}
    Autoescaping is inactive within this block
{% endautoescape %}

Sau một hành endautoescapevi, hành vi được hoàn nguyên về trạng thái trước đó.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply