Қолибҳои Jinja
Чаро қолибҳо лозиманд
Кортҳои мол ва саҳифаҳои портфолио сохтори яксон, вале додаҳои гуногун доранд. Пайвастани HTML бо + нороҳат аст: тегро фаромӯш кардан, нохунакҳоро омехтан ё HTML-и бегонаро тасодуфан ворид кардан осон аст. Қолиб намуди саҳифаро аз ҳисобҳои Python ҷудо мекунад: сохтор як бор навишта мешавад ва қиматҳо ҳангоми дархост ҷойгузин мешаванд.
Flask муҳаррики Jinja-ро истифода мебарад. Он қолиб ва додаҳоро хонда, шарту давраҳоро иҷро мекунад ва сатри тайёри HTML медиҳад. Қолиб рӯйхати додашударо тағйир намедиҳад ва худаш додаҳоро сабт намекунад. Одатан тартибдиҳӣ ва ҳисобро view иҷро мекунад, Jinja бошад, намоишро.
1. Ҷойгузинии қимат
{{ expression }} маънои «ифодаро ҳисоб карда, натиҷаро нишон деҳ»-ро дорад. Аргументҳои номдори render_template_string ба тағйирёбандаҳои қолиб табдил меёбанд. Берун аз view контексти барнома лозим аст: with app.app_context(): ба Flask мегӯяд, ки танзимот ва муҳаррики қолиб аз кадом барномаанд. Дар дархости муқаррарӣ Flask контекстро худкор месозад. Ҳамаи мисолҳои Python-и зерин мустақиланд.
from flask import Flask, render_template_string
app = Flask(__name__)
with app.app_context():
print(render_template_string("<h2>{{ name }}</h2>", name="Аня"))
Натиҷа:
<h2>Аня</h2>
Дар лоиҳа қолибҳо одатан дар ҷузвдони templates дар паҳлуи модули барнома ҳастанд. render_template("card.html", name="Аня") файлро дар ин ҷузвдон меҷӯяд. Дар курс render_template_string истифода мешавад, то ҳама чиз дар як файл бошад.
Мисоли навбатӣ ҳамин ҷустуҷӯро аз рӯйи ном бе сохтани файл нишон медиҳад: боркунанда-и Jinja бо номи DictLoader қолибҳоро аз луғат мехонад. Дар лоиҳаи муқаррарӣ он лозим нест: Flask ҷустуҷӯи файлҳоро аллакай танзим кардааст.
from flask import Flask, render_template
from jinja2 import DictLoader
app = Flask(__name__)
app.jinja_loader = DictLoader({"card.html": "<p>{{ name }}</p>"})
with app.app_context():
print(render_template("card.html", name="Python"))
Натиҷа:
<p>Python</p>
2. Шартҳо ва давраҳо
{% ... %} фармони идоракунӣ аст ва худаш чизе чоп намекунад. Ҷуфти if / endif порчаро аз рӯйи шарт интихоб мекунад; for / endfor онро такрор мекунад. Давраи for қисми else-и худро дорад: он вақте иҷро мешавад, ки давра ягон қадам накунад. Ин барои феҳристи холӣ қулай аст.
Дар дохили давра loop.first ва loop.last унсурҳои канорӣ, loop.length дарозӣ, loop.index рақам аз як ва loop.index0 индекс аз сифрро медиҳанд. Аввал муайян кунед, ки рақам барои инсон лозим аст ё индекс барои рӯйхат.
from flask import Flask, render_template_string
app = Flask(__name__)
PAGE = "{% for x in items %}{{ x }}{% if not loop.last %}, {% endif %}{% else %}Сабте нест{% endfor %}"
with app.app_context():
print(render_template_string(PAGE, items=["Python", "SQL"]))
print(render_template_string(PAGE, items=[]))
Натиҷа:
Python, SQL
Сабте нест
3. Филтрҳо ва майдонҳои додаҳо
Филтр пас аз | қиматро пеш аз намоиш табдил медиҳад. upper ҳарфҳоро калон мекунад; capitalize танҳо аввалро калон ва боқимондаро хурд мекунад; length унсурҳоро мешуморад; join сатрҳоро мепайвандад. Филтрҳоро пайдарпай истифода бурдан мумкин аст. user.name барои майдонҳои луғат қулай аст, вале агар ном бо методи луғат яксон бошад, дастрасии ошкори user["items"] беҳтар аст.
default("—") тағйирёбандаи муайяннашударо иваз мекунад, вале одатан сатри холиро не. Аргументи дуюми true ивазкуниро барои қиматҳои дурӯғин низ фаъол мекунад: сатри холӣ, сифр ва False. Онро огоҳона истифода кунед: баъзан сифр натиҷаи муҳим аст.
from flask import Flask, render_template_string
app = Flask(__name__)
PAGE = "{{ user.name|upper }}: {{ tags|join(' / ') }}; {{ tags|length }}"
with app.app_context():
print(render_template_string(PAGE, user={"name": "Аня"}, tags=["web", "api"]))
print(repr(render_template_string("{{ bio|default('—') }}", bio="")))
print(render_template_string("{{ bio|default('—', true) }}", bio=""))
Натиҷа:
АНЯ: web / api; 2
''
—
4. Гурезонидани худкор
Теги HTML ва матни ба тег монанд як чиз нестанд. Ҳангоми ҷойгузинӣ дар render_template_string Flask аломатҳои HTML-ро худкор гурезонӣ мекунад, то браузер онҳоро ҳамчун матн нишон диҳад. Дар қолибҳои файлӣ муҳофизат барои пасвандҳое мисли .html фаъол аст. Ин аз XSS муҳофизат мекунад: ҳамлагар мехоҳад скрипти бегонаро қисми сайти шумо нишон диҳад.
|safe қиматро ҳамчун нишонагузории боэътимоди HTML (markup) нишон дода, ин муҳофизатро хомӯш мекунад. Ном, шарҳ ё матни URL худ аз худ боэътимод намешаванд. Дар мисоли навбатӣ матни одӣ дода мешавад ва тегҳои он иҷро намешаванд.
from flask import Flask, render_template_string
app = Flask(__name__)
with app.app_context():
print(render_template_string("<p>{{ text }}</p>", text='<b>Python</b> & "SQL"'))
Натиҷа:
<p><b>Python</b> & "SQL"</p>
Намоиш дар дохил чӣ тавр кор мекунад
Қолиб ба варақа монанд аст: нишонагузорӣ шаклро муайян мекунад, аргументҳо майдонҳоро пур мекунанд. Jinja ифодаҳо ва фармонҳоро таҳлил мекунад, тағйирёбандаҳоро аз додаҳо меёбад, шохаҳо ва давраҳоро иҷро карда, филтрҳо ва гурезониро истифода мебарад. Ба ҷавоб HTML-и тайёр меравад: браузер {{ ... }}-ро намебинад. Тағйирёбандаи фаромӯшшуда дар ҷойгузинии сода аксар вақт сатри холӣ медиҳад, аз ин рӯ номҳои аргументҳоро санҷед.
Хатоҳои маъмул ва ислоҳи онҳо
{% name %}ба ҷойи{{ name }}: Jinja фармони ношинос меҷӯяд ва хатои қолиб медиҳад. Ислоҳ: қиматро байни{{ва}}нависед.{% if items %}бе{% endif %}блоки нотамом месозад ва тарҷумаи қолиб ноком мешавад. Ислоҳ: ҳар if ва for-ро бо фармони мувофиқ бандед.{{ text|safe }}барои додаҳои форма тегро ба нишонагузории HTML табдил дода, XSS имконпазир мекунад. Ислоҳ: safe-ро бардоред ва гурезонидани худкорро нигоҳ доред.{{ bio|default("—") }}ҳангомиbio=""чизе нишон намедиҳад. Ислоҳ: агар қимати холиро низ иваз кардан лозим бошад, аргументи дуюмиtrueдиҳед.
Ёддошт
| Мақсад | Навишт |
|---|---|
| Файл / сатр | render_template / render_template_string |
| Қимат / фармон | {{ value }} / {% ... %} |
| Шарт | {% if flag %}...{% else %}...{% endif %} |
| Давра | {% for x in items %}...{% endfor %} |
| Рақам / индекс | loop.index / loop.index0 |
| Табдил | upper, capitalize, length, join, default |
Ҳам сатри тайёри HTML ва ҳам маҷмӯи холии додаҳоро санҷед. Ин ба ёфтани контейнерҳои зиёдатӣ, рақамгузории нодуруст ва гурезонии тасодуфан хомӯшшуда ёрӣ медиҳад.