آموزش فیلترها در Jinja2
آموزش فیلترها در Jinja2
چگونه در Flask و Jinja2 فیلتر تعریف کنیم؟
فرض کنید شما یک برنامه Flask دارید و در صفحهی HTML خود (که با قالبساز Jinja2 نوشته شده) نیاز دارید دادهها را قبل از نمایش تغییر دهید. مثلاً میخواهید یک عدد را به درصد تبدیل کنید، یا تاریخ را به فرمت دلخواه نشان دهید.
فرض کنید لیستی از نمرات دانشآموزان را از پایگاه داده گرفتهایم و میخواهیم نمرات زیر ۱۰ را قرمز نشان دهیم یا میانگین کل را محاسبه کنیم. به جای نوشتن کدهای پیچیده در فایل HTML، میتوانیم از فیلترهای سفارشی استفاده کنیم.
۱. فیلتر در Jinja2 چیست؟
فیلترها توابع کوچکی هستند که روی متغیرها اعمال میشوند تا خروجی آنها را تغییر دهند. در Jinja2 شما با استفاده از خط لوله (|) میتوانید یک فیلتر را به متغیر متصل کنید.
مثال ساده داخلی:
{{ "hello world" | upper }}
در اینجا فیلتر upper (که از قبل در Jinja2 وجود دارد) متن را به حروف بزرگ تبدیل میکند. اما ما میخواهیم فیلتر خودمان را بسازیم.
۲. روش اول: استفاده از دکوریتور @app.template_filter
این سادهترین و رایجترین روش برای تعریف فیلتر در فایل اصلی اپلیکیشن (مثلاً app.py) است.
مراحل پیادهسازی:
- یک تابع معمولی در پایتون تعریف کنید.
- قبل از آن از دکوراتور
@app.template_filter('نام_فیلتر')استفاده کنید. - این تابع میتواند ورودی بگیرد و خروجی بدهد.
کد پایتون (در app.py):
from flask import Flask, render_template
app = Flask(__name__)
# تعریف یک فیلتر سفارشی به نام 'show_status'
@app.template_filter('show_status')
def show_status(is_active):
"""
اگر مقدار True باشد 'فعال' برمیگرداند، در غیر این صورت 'غیرفعال'.
"""
if is_active:
return '✅ فعال'
else:
return '❌ غیرفعال'
@app.route('/')
def index():
# ارسال دادهها به قالب
user_active = True
return render_template('index.html', user_active=user_active)
if __name__ == '__main__':
app.run(debug=True)
کد قالب (در templates/index.html):
<h1>وضعیت کاربر</h1>
<!-- استفاده از فیلتر با علامت خط لوله -->
<p>وضعیت کاربر: {{ user_active | show_status }}</p>
'show_status') همان نامی است که در فایل HTML بعد از | استفاده میکنید.۳. روش دوم: ارسال فیلتر از طریق دیکشنری (برای پروژههای بزرگتر)
اگر پروژه شما بزرگ است و نمیخواهید تمام توابع را در app.py بریزید، میتوانید فیلترها را در یک فایل جداگانه تعریف کرده و سپس به اپلیکیشن ثبت کنید.
مراحل پیادهسازی:
- یک دیکشنری برای نگهداری فیلترها بسازید.
- توابع خود را تعریف کنید.
- در پایان، با
app.jinja_env.filters.update(...)آنها را ثبت کنید.
کد پایتون (در app.py):
from flask import Flask, render_template
app = Flask(__name__)
# ۱. تعریف توابع فیلتر
def to_reversed(text):
return text[::-1] # معکوس کردن متن
def count_words(text):
return len(text.split()) # شمارش کلمات
# ۲. ساخت دیکشنری فیلترها
custom_filters = {
'to_reversed': to_reversed,
'count_words': count_words
}
# ۳. ثبت فیلترها در محیط Jinja2 اپلیکیشن
app.jinja_env.filters.update(custom_filters)
@app.route('/')
def index():
sentence = "Flask is awesome"
return render_template('index.html', sentence=sentence)
if __name__ == '__main__':
app.run(debug=True)
کد قالب (در templates/index.html):
<h1>نمونه فیلترهای دیکشنری</h1>
<p>متن اصلی: {{ sentence }}</p>
<p>متن معکوس: {{ sentence | to_reversed }}</p>
<p>تعداد کلمات: {{ sentence | count_words }}</p>
۴. روش سوم: فیلترهای دارای آرگومان اضافی
گاهی اوقات فیلتر شما نیاز به پارامترهای بیشتر دارد. مثلاً فیلتری که یک متن را کوتاه میکند اما طول آن را کاربر تعیین کند.
کد پایتون:
@app.template_filter('truncate_custom')
def truncate_custom(text, length=10, suffix='...'):
if len(text) > length:
return text[:length] + suffix
return text
کد قالب:
<!-- ارسال طول دلخواه به فیلتر -->
<p>{{ "این یک متن بسیار طولانی است" | truncate_custom(5, "!!") }}</p>
<!-- خروجی: این یک !! -->
جمعبندی
برای تعریف فیلتر در Flask/Jinja2:
- از دکوراتور
@app.template_filter('name')برای روش سریع استفاده کنید. - از
app.jinja_env.filtersبرای مدیریت متمرکز فیلترها در پروژههای بزرگ استفاده کنید. - در فایل HTML، فیلتر را با علامت
|به متغیر متصل کنید.
با این روشها میتوانید منطق نمایش دادهها را تمیز نگه دارید و کدهای HTML خود را ساده و خوانا بنویسید.