حلقة التّكرار for في محرك القوالب Jinja: الاستخدامات، الميزات، والاعتبارات المتقدمة
تُعدّ حلقة التكرار for في محرك القوالب Jinja أحد المكونات الأساسية التي تمكّن المطور من إنشاء صفحات ويب ديناميكية وموجهة للبيانات باستخدام إطار عمل Python مثل Flask أو Django (عند تكامل Jinja فيه). يمثل Jinja محرك قوالب قوي يعتمد على التعبير النحوي الشبيه بلغة Python لتوليد مخرجات HTML من مصادر بيانات مختلفة. تلعب حلقة for دورًا محوريًا في التعامل مع البيانات القابلة للتكرار داخل القوالب، مثل القوائم أو القواميس، مما يتيح للمطور عرض جداول، بطاقات، عناصر قائمة، أو أي شكل من أشكال المحتوى القائم على التكرار.
يستعرض هذا المقال الطويل بشكل مفصل طبيعة حلقة التكرار for في Jinja، تركيبتها النحوية، أهم الخصائص المرفقة بها، بالإضافة إلى أفضل الممارسات والاعتبارات التي يجب أخذها بعين الاعتبار أثناء الاستخدام، مع توضيحات مدعومة بأمثلة عملية.
1. السياق العام لمحرك القوالب Jinja
محرك القوالب Jinja هو عبارة عن نظام تفسير نصي (template engine) مبني بلغة Python، صُمم لتوليد مخرجات ديناميكية غالبًا على شكل HTML. يُستخدم على نطاق واسع ضمن تطبيقات الويب المستندة إلى Flask وDjango وBottle وغيرها.
يتميز Jinja ببنية تشبه لغة Python إلى حد كبير، مما يسهل على مطوري Python الانتقال إليه وفهمه. كما يتيح Jinja استخدام المتغيرات، الشروط، الحلقات، الفلاتر، الكتل الموروثة، والعديد من الميزات التي توفر قدرة هائلة على تخصيص القوالب.
2. التركيب النحوي لحلقة for في Jinja
الصيغة الأساسية لحلقة التكرار for في Jinja تأتي على النحو التالي:
jinja{% for item in list %} {{ item }} {% endfor %}
وهذا شبيه جدًا بالصيغة التقليدية في Python:
pythonfor item in list:
print(item)
مثال تطبيقي
إذا كان لدينا المتغير التالي في السياق (context) الخاص بالقالب:
pythonusers = ["Ali", "Sara", "Youssef"]
يمكننا عرض أسماء المستخدمين في القالب Jinja على النحو التالي:
jinja{% for user in users %}
- {{ user }}
{% endfor %}
الناتج سيكون:
html<ul>
<li>Alili>
<li>Sarali>
<li>Youssefli>
ul>
3. خصائص الكائن loop في Jinja
أثناء تنفيذ حلقة for، يوفر Jinja كائنًا خاصًا يسمى loop يحتوي على مجموعة من الخصائص المفيدة داخل الحلقة. من بين هذه الخصائص:
| الخاصية | الوصف |
|---|---|
loop.index |
يعطي رقم التكرار الحالي (يبدأ من 1) |
loop.index0 |
رقم التكرار الحالي بدءًا من 0 |
loop.revindex |
رقم التكرار المتبقي حتى نهاية الحلقة (يبدأ من 1) |
loop.revindex0 |
رقم التكرار المتبقي بدءًا من 0 |
loop.first |
صحيح إذا كان العنصر الحالي هو الأول |
loop.last |
صحيح إذا كان العنصر الحالي هو الأخير |
loop.length |
عدد العناصر داخل الحلقة |
loop.cycle |
يُستخدم لتبديل القيم (مثلًا عند إنشاء صفوف بلونين متناوبين) |
مثال عملي مع خصائص loop
jinja
{% for user in users %} # الاسم {% endfor %} {{ loop.index }} {{ user }}
4. التكرار داخل القوائم المتداخلة (Nested Loops)
يُسمح باستخدام حلقات متداخلة for داخل قوالب Jinja تمامًا كما في Python. إلا أن بعض المحاذير تشمل تعقيد القراءة وفقدان دقة المؤشرات إذا لم تتم إدارة الخصائص loop بشكل صحيح.
مثال لقائمة داخل قائمة
jinja{% for category in categories %}{{ category.name }}
{% for product in category.products %}
{% endfor %}- {{ product.name }}
{% endfor %}
5. استخدام loop.cycle لتناوب الأنماط
خاصية loop.cycle هي أداة متميزة لتطبيق تأثيرات بصريّة في واجهات المستخدم. يمكنها تدوير سلسلة من القيم تلقائيًا داخل الحلقة.
مثال لتناوب الألوان بين الصفوف
jinja{% for item in items %}
{% endfor %} {{ item }}
6. الفلاتر داخل حلقة for
تدعم Jinja استخدام الفلاتر داخل الحلقات، مما يسمح بتنسيق البيانات أثناء التكرار.
مثال:
jinja{% for user in users %}{{ user|capitalize }}
{% endfor %}
7. التحقق من وجود عناصر داخل الحلقة باستخدام if
غالبًا ما يُستخدم الشرط داخل حلقة for لمعالجة حالة عدم وجود عناصر.
مثال:
jinja{% for item in items %} {{ item }} {% else %}لا توجد عناصر لعرضها.
{% endfor %}
الميزة هنا أن Jinja يدعم جملة else مرتبطة بحلقة for، وتُستخدم فقط في حال كانت القائمة فارغة، وهي طريقة فعالة لمعالجة الاستثناءات بدون استخدام منطق برمجي إضافي.
8. إلغاء التكرار بناءً على شرط معين
يمكن التحكم في عرض عناصر معينة دون غيرها داخل التكرار عبر استخدام if داخلي:
jinja{% for product in products %} {% if product.in_stock %}{{ product.name }} {% endif %} {% endfor %}
9. تكرار على القواميس (Dictionaries)
يمكن استخدام حلقة for مع القواميس عبر إسناد مفتاح وقيمة في التكرار:
jinja{% for key, value in data.items() %}{{ key }}: {{ value }}
{% endfor %}
10. ملاحظات على الأداء
رغم أن Jinja يوفر قدرة كبيرة على التكرار داخل القوالب، من المهم المحافظة على نظافة الشيفرة وقصر المنطق داخل القوالب قدر الإمكان. يجب تجنب العمليات الحسابية المعقدة داخل القوالب، والاحتفاظ بها في طبقة الـ backend في Python.
11. حالات استخدام متقدمة: تصفية البيانات أثناء التكرار
يمكن دمج التكرار مع شروط وفلاتر قوية جدًا لعرض البيانات بشكل انتقائي.
مثال:
jinja{% for item in items if item.is_active %}{{ item.name }} {% endfor %}
12. جدول ملخص خصائص التكرار في Jinja
| الخاصية | الوصف |
|---|---|
loop.index |
رقم العنصر الحالي (ابتداءً من 1) |
loop.index0 |
رقم العنصر الحالي (ابتداءً من 0) |
loop.revindex |
عدد العناصر المتبقية (ابتداءً من 1) |
loop.revindex0 |
عدد العناصر المتبقية (ابتداءً من 0) |
loop.first |
تُرجع True إذا كان العنصر الأول |
loop.last |
تُرجع True إذا كان العنصر الأخير |
loop.length |
إجمالي عدد العناصر في التكرار |
loop.cycle |
تُستخدم لتبديل القيم مثل CSS class أو الألوان |
13. استخدام حلقات for مع ملفات فرعية (Include)
في حالات التصميم المعقدة، يمكن تمرير عناصر من حلقة for إلى ملفات فرعية باستخدام {% include %}:
jinja{% for post in posts %} {% include "post_card.html" %} {% endfor %}
وفي الملف post_card.html:
jinja{{ post.title }}
{{ post.content }}
14. تكامل حلقة for مع أنظمة CSS وJavaScript
واحدة من أقوى ميزات Jinja أنه يسمح بتوليد كود HTML يتفاعل مع أنظمة التصميم الحديثة مثل Tailwind أو Bootstrap أو حتى JavaScript.
مثال لتمرير عناصر ديناميكية عبر for إلى JavaScript:
jinja
15. اعتبارات الأمان عند عرض القيم
من الجوانب المهمة عند عرض المتغيرات داخل حلقات for هو التأكد من أن القيم يتم ترشيحها بشكل آمن ضد الثغرات من نوع XSS (حقن جافاسكربت). Jinja يقوم افتراضيًا بترميز HTML (HTML Escaping)، ولكن يمكن تجاوز ذلك باستخدام |safe، وهذا يجب استخدامه بحذر شديد:
jinja{{ item.content|safe }}
المصادر
هذا المقال يوفر دليلاً متكاملاً حول آلية عمل حلقة التكرار for داخل محرك القوالب Jinja، ويغطي مختلف السيناريوهات العملية التي يحتاجها المطور لبناء واجهات ديناميكية قوية وقابلة للتوسع.

