قالب ها

فلاسک از Jinja2 به عنوان موتور قالب خود استفاده می کند. بدیهی است که شما آزاد هستید که از یک موتور قالب متفاوت استفاده کنید، اما همچنان باید Jinja2 را برای اجرای خود فلاسک نصب کنید. این نیاز برای فعال کردن افزونه‌های غنی ضروری است. یک برنامه افزودنی می تواند به حضور Jinja2 بستگی داشته باشد.

این بخش فقط یک مقدمه بسیار سریع در مورد نحوه ادغام Jinja2 در فلاسک ارائه می دهد. اگر اطلاعاتی در مورد نحو موتور قالب می‌خواهید، برای اطلاعات بیشتر به مستدات Jinja2 بروید.

راه‌اندازی Jinja

Jinja2 به صورت پیش فرض در فلاسک به صورت زیر پیکربندی می‌شود:

  • autoescaping is enabled for all templates ending in .html, .htm, .xml, .xhtml, as well as .svg when using render_template().

  • هنگام استفاده از render_template_string()، فرار خودکار برای همه رشته ها فعال است.

  • یک الگو این قابلیت را دارد که با تگ {% autoescape %} از فرار خودکار خارج شود.

  • فلاسک علاوه بر مقادیری که به طور پیش فرض وجود دارند، چند تابع و کمک کننده سراسری را در زمینه Jinja2 وارد می کند.

زمینه استاندارد(Standard Context)

متغیرهای سراسری زیر به طور پیش فرض در قالب های Jinja2 در دسترس هستند:

config

شیء پیکربندی فعلی (flask.Flask.config)

Changelog

تغییر داده شده در نسخه 0.10: این در حال حاضر همیشه در دسترس است، حتی در قالب های وارداتی.

جدید در نسخه 0.6.

request

شی درخواست فعلی (flask.request) . اگر الگو بدون زمینه درخواست فعال ارائه شده باشد، این متغیر در دسترس نیست.

session

شی جلسه فعلی (flask.session). اگر الگو بدون زمینه درخواست فعال ارائه شده باشد، این متغیر در دسترس نیست.

g

شیء محدود به درخواست برای متغیرهای سراسری (flask.g). اگر الگو بدون زمینه درخواست فعال ارائه شده باشد، این متغیر در دسترس نیست.

url_for()

تابع flask.url_for() .

get_flashed_messages()

تابع flask.get_flashed_messages() .

رفتار زمینه Jinja

این متغیرها به بافت متغیرها اضافه می شوند، متغیرهای سراسری نیستند. تفاوت این است که به طور پیش‌فرض اینها در قالب قالب‌های وارد شده نشان داده نمی‌شوند. این تا حدی ناشی از ملاحظات عملکرد است، تا حدی برای روشن نگه داشتن چیزها.

این برای شما چه معنایی دارد؟ اگر ماکرویی دارید که می‌خواهید وارد کنید، باید به شی درخواست دسترسی پیدا کند، دو امکان دارید:

  1. شما صریحاً درخواست را به ماکرو به عنوان پارامتر یا ویژگی شی درخواستی مورد علاقه خود ارسال می کنید.

  2. شما ماکرو را با «زمینه» وارد می کنید.

وارد کردن با زمینه به این شکل است:

{% from '_helpers.html' import my_macro with context %}

کنترل خودکار فرار

فرار خودکار یعنی برنامه طوری کار کند که کاراکتر های خاص در HTML عمل نکنند. کاراکترهای خاص HTML (یا XML و همچنین XHTML) & ، > ، < ، " و همچنین ' است. این کاراکتر ها به تنهایی دارای معانی خاصی در اسناد هستند. اگر میخواهید از آنها در متن استفاده کنید، باید آنها را با "entities"جایگزین کنید ولی این موجب مشکل امنیتی می شود. ( Cross-Site Scripting (XSS) را نگاه کنید. )

با این حال، گاهی اوقات لازم است که فرار خودکار در قالب ها را غیرفعال کنید. اگر بخواهید صریحاً HTML را به صفحات تزریق کنید، می‌تواند صدق کند، برای مثال اگر از سیستمی می‌آیند که HTML ایمن مانند مبدل علامت‌گذاری به HTML ایجاد می‌کند.

سه راه برای انجام آن وجود دارد:

  • In the Python code, wrap the HTML string in a Markup object before passing it to the template. This is in general the recommended way.

  • در داخل الگو، از فیلتر |safe استفاده کنید تا صریحاً یک رشته را به عنوان HTML ایمن علامت گذاری کنید ( {{ myvariable|safe }} )

  • سیستم فرار خودکار را بطور موقت غیرفعال کنید.

برای غیرفعال کردن سیستم فرار خودکار در قالب ها، می توانید از بلوک {% autoescape %} استفاده کنید:

{% autoescape false %}
    <p>autoescaping is disabled here
    <p>{{ will_not_be_escaped }}
{% endautoescape %}

هر زمان که این کار را انجام می دهید، لطفاً در مورد متغیرهایی که در این بلوک استفاده می کنید بسیار محتاط باشید.

ثبت فیلترها

اگر می خواهید فیلترهای خود را در Jinja2 ثبت کنید، دو راه برای این کار دارید. می توانید آنها را با دست در jinja_env برنامه قرار دهید یا از دکوراتور template_filter() استفاده کنید.

دو مثال زیر یکسان عمل می کنند و هر دو یک شی را معکوس می کنند:

@app.template_filter('reverse')
def reverse_filter(s):
    return s[::-1]

def reverse_filter(s):
    return s[::-1]
app.jinja_env.filters['reverse'] = reverse_filter

اگر می‌خواهید از نام تابع به عنوان نام فیلتر استفاده کنید، در مورد دکوراتور، آرگومان اختیاری است. پس از ثبت نام، می توانید از فیلتر در قالب های خود مانند فیلترهای داخلی Jinja2 استفاده کنید، برای مثال اگر یک لیست پایتون در زمینه به نام mylist دارید:

{% for x in mylist | reverse %}
{% endfor %}

پردازشگرهای زمینه

برای تزریق متغیرهای جدید به طور خودکار در زمینه یک الگو، پردازنده های زمینه در فلاسک وجود دارند. پردازنده‌های زمینه قبل از رندر شدن الگو اجرا می‌شوند و توانایی تزریق مقادیر جدید به بافت قالب را دارند. پردازنده زمینه تابعی است که یک فرهنگ لغت را برمی گرداند. سپس کلیدها و مقادیر این فرهنگ لغت با زمینه قالب، برای همه الگوهای موجود در برنامه ادغام می شوند:

@app.context_processor
def inject_user():
    return dict(user=g.user)

پردازشگر زمینه در بالا متغیری به نام user را با مقدار g.user در قالب موجود می کند. این مثال خیلی جالب نیست زیرا g به هر حال در قالب ها موجود است، اما ایده ای را ارائه می دهد که چگونه کار می کند.

متغیرها محدود به مقادیر نیستند. یک پردازنده زمینه همچنین می‌تواند توابع را برای قالب‌ها در دسترس قرار دهد (زیرا پایتون اجازه می‌دهد توابع را منتقل کند):

@app.context_processor
def utility_processor():
    def format_price(amount, currency="€"):
        return f"{amount:.2f}{currency}"
    return dict(format_price=format_price)

پردازشگر زمینه بالا تابع format_price را برای همه قالب‌ها در دسترس قرار می‌دهد:

{{ format_price(0.33) }}

همچنین می‌توانید format_price را به‌عنوان یک فیلتر قالب بسازید (به ثبت فیلترها مراجعه کنید)، اما این نشان می‌دهد که چگونه می‌توان توابع را در یک پردازنده زمینه ارسال کرد.

Streaming

It can be useful to not render the whole template as one complete string, instead render it as a stream, yielding smaller incremental strings. This can be used for streaming HTML in chunks to speed up initial page load, or to save memory when rendering a very large template.

The Jinja2 template engine supports rendering a template piece by piece, returning an iterator of strings. Flask provides the stream_template() and stream_template_string() functions to make this easier to use.

from flask import stream_template

@app.get("/timeline")
def timeline():
    return stream_template("timeline.html")

These functions automatically apply the stream_with_context() wrapper if a request is active, so that it remains available in the template.