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
, .xml
hoặ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:
{% ... %}
cho các báo cáo{{ ... }}
để Biểu thức in ra đầu ra mẫu{# ... #}
cho các Nhận xét không có trong đầu ra của mẫu
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_prefix
vàline_comment_prefix
khi 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 .jinja
tiện ích mở rộng, chẳng hạn như user.html.jinja
có 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 templates
thư 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.bar
Jinja thực hiện những việc sau trên lớp Python:
- kiểm tra thuộc tính có tên
bar
trênfoo
( )getattr(foo, 'bar')
- nếu không có, hãy kiểm tra mục
'bar'
trongfoo
(foo.__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'
trongfoo
. (foo.__getitem__('bar')
) - nếu không có, hãy kiểm tra thuộc tính được gọi
bar
trênfoo
. ( )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 }}
name
title(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 is
dấ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 defined
name
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_blocks
cũ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_blocks
và 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_blocks
và 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_blocks
và 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_blocks
hà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_blocks
hà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 seq
là 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ư for
, if
, elif
v.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 %} © 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
block
cá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ể if
khố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ụ: FileSystemLoader
cho 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 footer
nê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 self
biế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 %}
super
super.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.tmpl
sẽ chobody: Hi from child. Hi from parent.
Kết xuất grandchild1.tmpl
sẽ chobody: Hi from grandchild1.
Kết xuất grandchild2.tmpl
sẽ 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 endblock
từ 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ì item
khô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 scoped
cụ 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, scoped
khô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.
{% block body required %}{% endblock %}
{% extends "page.txt" %}
{% extends "issue.txt" %} {% block body %}Provide steps to demonstrate the bug.{% endblock %}
Hiển thị page.txt
hoặc issue.txt
sẽ tăng TemplateRuntimeError
vì chúng không ghi đè body
khối. Kết xuất bug_report.txt
sẽ thành công vì nó ghi đè lên khối.
Khi kết hợp với scoped
, required
cô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
extends
, include
và import
có 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 extends
truyề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:
- thoát từng biến theo cách thủ công; hoặc
- 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 |e
bộ 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:
- Từ điển ngữ cảnh của ứng dụng với
markupsafe.Markup
- Mẫu, với bộ
|safe
lọ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 Markup
hoặc sử dụng |safe
bộ lọc.
Các hàm Jinja (macro, super
, self.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ộ |dictsort
lọ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 đổi | Sự miêu tả |
---|---|
loop.index | Sự lặp lại hiện tại của vòng lặp. (1 được lập chỉ mục) |
loop.index0 | Sự lặp lại hiện tại của vòng lặp. (0 được lập chỉ mục) |
loop.revindex | Số lần lặp từ cuối vòng lặp (1 chỉ số) |
loop.revindex0 | Số 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.length | Số lượng mục trong chuỗi. |
loop.cycle | Mộ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.depth | Cho 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.depth0 | Cho 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.previtem | Mụ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.nextitem | Mụ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.cycle
trợ 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 break
trong continue
mộ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à loop
biế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, else
cá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 break
nên hành vi hơi khác của else
từ 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 recursive
cụ sửa đổi vào định nghĩa vòng lặp và gọi loop
biế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 loop
luô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 loop
bằ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 previtem
and 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 changed
thậ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 if
lệ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 elif
và else
có 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 varargs
biến đặc biệt dưới dạng danh sách các giá trị.kwargs
Giống như varargs
như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 }}
input
arguments
Một bộ tên của các đối số mà macro chấp nhận.catch_kwargs
Đây là true
nếu macro chấp nhận các đối số từ khóa bổ sung (tức là: truy cập vào kwargs
biến đặc biệt).catch_varargs
Điều này xảy ra true
nếu macro chấp nhận các đối số vị trí bổ sung (tức là: truy cập vào varargs
biến đặc biệt).caller
Điều này xảy ra true
nếu macro truy cập vào caller
biế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”.
{% macro foo() %}LAYOUT{% endmacro %} {% block body %}{% endblock %}
{% 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 call
khố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 filter
phầ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 set
thẻ 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 loop
biế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.attr
ký hiệu trong set
thẻ 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 navigation
chứ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ẻ extends
có thể được sử dụng để mở rộng mẫu này sang mẫu khác. Bạn có thể có nhiều extends
thẻ 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ẻ include
hiể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 context
with context
Mẫu đi kèm có thể là extend
mẫ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 context
without 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.html
không thể truy cập được box
trong Jinja 2.0. Kể từ Jinja 2.1, render_box.html
có 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.23
/ 42.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
true
luôn đúng và false
luôn sai.
Ghi chú
Các hằng số đặc biệt true
, false
và none
thự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 ( True
, False
, 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)**3
3**(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.>
true
nếu vế trái lớn hơn vế phải.>=
true
nếu vế trái lớn hơn hoặc bằng vế phải.<
true
nếu phía bên trái thấp hơn phía bên phải.<=
true
nếu vế trái thấp hơn hoặc bằng vế phải.
Hợp lý
Đối với if
các câu lệnh, for
lọc và if
biể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ử is
và cũng in
hỗ 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 bar
foo not in bar
not foo is bar
not foo in bar
not (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 if
cá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 else
là 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 undefined
trong 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.title
có 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 f
loại Foo
có 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 .format
phươ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
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.bar
luô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ư slice
cá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, ' ') %} <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_variable
nế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
d
bộ 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 Markup
chuỗi có văn bản thoát.Bí danh :
e
bộ 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 True
tiề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 User
các đối tượng có city
thuộc tính có thể được hiển thị theo nhóm. Trong ví dụ này, grouper
đề cập đến city
giá 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>
groupby
mang 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)
grouper
list
<ul>{% for group in users|groupby("city") %} <li>{{ group.grouper }}: {{ group.list|join(", ") }} {% endfor %}</ul>
Bạn có thể chỉ định một default
giá 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 key
vớ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_sensitive
số. 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|items
giống như x.items()
, ngoại trừ nếu x
khô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 :
count
bộ 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 default
giá 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ỉ count
nhữ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 Markup
chuỗ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('<User 1>') >>> escape(str(value)) Markup('&lt;User 1&gt;') >>> escape(soft_str(value)) Markup('<User 1>')
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 |forceescape
bộ lọc.Thông số :
- value – Đối tượng cần tuần tự hóa thành JSON.
- thụt lề –
indent
Tham số được truyền tớidumps
, để 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à true
bộ 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=nofollow
tính vào liên kết. - target – Thêm thuộc
target
tính vào liên kết. - rel – Thêm thuộc
rel
tí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 none
hoặ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
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 :
==
,equalto
jinja-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 :
>
,greaterthan
jinja-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 :
<
,lessthan
jinja-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]
0
range(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 current
sang 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ư dict
hà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 trans
khố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 trans
thẻ để 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, notrimmed
cô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 pgettext
và npgettext
sẽ lấy một context
chuỗ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 trans
thẻ để sử dụng pgettext
và npgettext
.
Có thể dịch các chuỗi trong biểu thức bằng các hàm sau:
_(message)
: Bí danh chogettext
.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ộ format
lọ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 gettext
cuộc gọi thay vì sử dụng bộ format
lọ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 ngettext
tự động nhận số đếm dưới dạng num
tham 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 do
sẽ 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 break
and continue
in. 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.index
bắt đầu bằng 1 và loop.index0
bắ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 with
lệ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 a
từ bên ngoài with
khối:
{% with a={}, b=a.attribute %}...{% endwith %}
Trong các phiên bản Jinja trước đó, b
thuộ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 endautoescape
vi, hành vi được hoàn nguyên về trạng thái trước đó.