البرمجة

استخدام حلقة for في Jinja

حلقة التّكرار 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:

python
for item in list: print(item)

مثال تطبيقي

إذا كان لدينا المتغير التالي في السياق (context) الخاص بالقالب:

python
users = ["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 %}
  • {{ product.name }}
  • {% endfor %}
{% 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، ويغطي مختلف السيناريوهات العملية التي يحتاجها المطور لبناء واجهات ديناميكية قوية وقابلة للتوسع.