التعامل مع محرك القوالب Jinja: الدوال والمرشحات
يُعتبر محرك القوالب Jinja من أكثر المحركات استخداماً في بيئات تطوير تطبيقات الويب، وخصوصاً في إطار العمل Flask بلغة Python. يُمكِّن هذا المحرك المطورين من فصل منطق التطبيق عن واجهة العرض، مما يسهم في تنظيم الكود وتحسين قابلية الصيانة. يعتمد Jinja على أسلوب مشابه في البنية لمحركات القوالب الأخرى مثل Django Template Language وTwig في PHP، لكنه يتفوق في البساطة والمرونة والديناميكية.
من أهم مكونات Jinja القابلة للتخصيص والاستخدام اليومي الدوال والمرشحات (Functions & Filters)، واللتان تشكلان أدوات فعالة للتحكم بالمخرجات وعرض البيانات بالشكل المناسب. يتناول هذا المقال بالتفصيل كيفية استخدام هذه الأدوات بكفاءة داخل قوالب Jinja، مع التركيز على الجوانب التقنية المتقدمة التي تهم المطورين والمبرمجين الباحثين عن بناء واجهات ديناميكية عالية الأداء.
أساسيات محرك القوالب Jinja
قبل التعمق في الدوال والمرشحات، من الضروري تقديم لمحة تقنية موجزة عن كيفية عمل Jinja:
-
محرك Jinja يُفسر القوالب المكتوبة بلغة HTML مع شيفرات برمجية خاصة تكتب ضمن قوسين مزدوجين
{{ ... }}للطباعة و{% ... %}لتنفيذ التعليمات البرمجية. -
الترميز الآمن: يدعم Jinja الترميز التلقائي للنصوص المخرجة لمنع هجمات XSS.
-
يدعم التكرار والشروط: مثل
forوifوغيرها. -
قابلية التوسعة: يمكن إنشاء دوال ومرشحات مخصصة بسهولة.
الدوال في Jinja
أنواع الدوال
تنقسم الدوال في Jinja إلى فئتين رئيسيتين:
-
دوال المعرفة ضمن القالب: وهي الدوال المعرفة من قبل محرك Jinja أو التي يتم تمريرها من التطبيق إلى القالب.
-
الدوال المخصصة: وهي الدوال التي يُمكن للمطور إنشاؤها داخل التطبيق وتمريرها إلى Jinja.
استخدام الدوال في القوالب
الدوال تُستخدم داخل {{ }} لإرجاع قيمة، مثال:
jinja{{ range(1, 5) }}
هذا المثال يطبع قائمة الأرقام من 1 إلى 4.
الدوال المدمجة (Built-in Functions)
يوفر Jinja مجموعة من الدوال الجاهزة مثل:
| الدالة | الوصف |
|---|---|
range |
توليد قائمة من الأعداد |
dict |
إنشاء قاموس |
lipsum |
توليد نصوص عشوائية للاختبار |
cycler |
توليد كائن يقوم بالدوران في قائمة من العناصر |
مثال على استخدام cycler:
jinja{% set colors = cycler('red', 'green', 'blue') %}عنصر 1 عنصر 2 عنصر 3
إنشاء دوال مخصصة
في إطار Flask على سبيل المثال:
pythondef say_hello(name):
return f"مرحبا، {name}!"
app.jinja_env.globals.update(say_hello=say_hello)
في القالب:
jinja{{ say_hello('أحمد') }}
المرشحات (Filters) في Jinja
ما هي المرشحات؟
المرشحات في Jinja هي وظائف تُطبق على البيانات المعدة للطباعة بهدف تحويلها أو تنسيقها. تُستخدم باستخدام الحرف | بعد المتغير.
مثال:
jinja{{ username|upper }}
المرشحات المدمجة
يحتوي Jinja على مجموعة كبيرة من المرشحات الجاهزة، ومنها:
| المرشح | الوصف |
|---|---|
lower |
تحويل النص إلى أحرف صغيرة |
upper |
تحويل النص إلى أحرف كبيرة |
capitalize |
جعل أول حرف كبيرًا والبقية صغيرة |
title |
تحويل كل الكلمات إلى حالة العنوان |
length |
إرجاع عدد العناصر في متغير |
replace |
استبدال جزء من النص |
join |
دمج قائمة بعناصر محددة |
default |
عرض قيمة افتراضية إذا كان المتغير غير معرف |
safe |
عرض HTML كما هو دون ترميز |
round |
تقريب رقم عشري |
date |
تنسيق التاريخ |
مثال:
jinja{{ ['أحمد', 'علي', 'منى']|join(', ') }}
الناتج: أحمد, علي, منى
مرشحات السلاسل النصية
المرشحات تلعب دوراً محورياً في التعامل مع النصوص:
-
trim: لإزالة المسافات البيضاء من البداية والنهاية.
-
striptags: لإزالة الوسوم HTML من السلسلة.
-
wordcount: لعدّ عدد الكلمات في النص.
-
truncate: لاقتطاع النص لعدد معين من الحروف.
مثال على truncate:
jinja{{ long_text|truncate(100) }}
إنشاء مرشحات مخصصة
يمكن تعريف مرشحات جديدة بإضافة دوال إلى jinja_env.filters:
pythondef reverse_string(value):
return value[::-1]
app.jinja_env.filters['reverse'] = reverse_string
في القالب:
jinja{{ 'مرحباً'|reverse }}
الناتج: ًاحبمر
استخدام الدوال والمرشحات معًا
يمكن مزج الدوال والمرشحات للحصول على نتائج معقدة:
jinja{{ range(1, 6)|list|join(' - ') }}
الناتج: 1 – 2 – 3 – 4 – 5
جداول مقارنة بين المرشحات والدوال
| العنصر | الدوال (Functions) | المرشحات (Filters) |
|---|---|---|
| طريقة الاستخدام | {{ func(args) }} |
`{{ value |
| القابلية للتسلسل | لا | نعم، يمكن ربط أكثر من مرشح بسلسلة |
| الهدف الرئيسي | تنفيذ عمليات معقدة | تنسيق أو تحويل المخرجات |
| القابلية للتخصيص | عالية | عالية |
| التداخل | يمكن استخدامها داخل بعضها البعض | يمكن دمجها بشكل متسلسل مع قيم متعددة |
التطبيقات العملية في مشاريع Flask
عند استخدام Flask، فإن Jinja يأتي مدمجاً بشكل افتراضي. هذا يسمح للمطور بكتابة واجهات HTML ديناميكية دون الحاجة إلى التعامل مع تعقيدات جافاسكريبت أو معالجة البيانات على الواجهة الأمامية.
أمثلة عملية:
-
تنسيق التاريخ داخل القالب:
jinja{{ post.created_at|date("d-m-Y") }} -
عرض نصوص قصيرة من المقالات:
jinja{{ article.content|truncate(200) }} -
استخدام دوال مخصصة لإضافة شارة (badge) بجانب اسم المستخدم بناءً على الدور:
pythondef user_badge(role): if role == 'admin': return '🛡️' return '👤' app.jinja_env.globals.update(user_badge=user_badge)jinja{{ user_badge(user.role) }} {{ user.name }}
استخدام مرشحات ودوال مع الحلقات الشرطية
في حالات عرض جداول ديناميكية أو قوائم تصفية، يمكن استخدام الدوال والمرشحات داخل الحلقات:
jinja{% for product in products %}{% endfor %} {{ product.name|title }} {{ product.price|round(2) }} {{ product.description|truncate(50) }}
الأداء وتحسين الاستخدام
-
تجنب الحسابات المكثفة داخل القالب: لأن Jinja يُستخدم فقط لعرض البيانات وليس لمعالجتها.
-
تصفية HTML باستخدام
safeبحذر: لتفادي الثغرات الأمنية. -
استخدام
setلتخزين نتائج العمليات المعقدة: لتفادي تكرارها عدة مرات داخل القالب.
الخاتمة
إن فهم كيفية استخدام الدوال والمرشحات في Jinja يمثل عنصراً حيوياً لتطوير تطبيقات ويب ديناميكية وعالية الكفاءة. فالتكامل بين منطق التطبيق وقالب العرض يُعزز من تجربة المستخدم ويسهم في كتابة كود نظيف ومنظم وسهل الصيانة. كما أن التوسع في تعريف مرشحات ودوال مخصصة يفتح آفاقاً واسعة لتخصيص طريقة عرض البيانات وتسهيل العمل الجماعي بين فرق المطورين والمصممين.
المراجع:
-
Jinja Official Documentation – https://jinja.palletsprojects.com
-
Flask Official Documentation – https://flask.palletsprojects.com

