مُقدّمة
بعد أن تعرّفنا على جزء من أهمّ المُرشّحات التّي يُمكنك استعمالها لتفادي تكرار شيفرة عدّة مرّات والحصول على تجربة تطوير أحسن، سنُكمل في هذا الدّرس ما بدأناه بالتّعرفّ على قائمة مُرشّحات أخرى لتكون لديك فكرة أفضل عن كيفيّة استخدام مُحرّك القوالب Jinja والمُرشّحات المتواجدة به.
المُرشّح length لقياس عدد عناصر مجموعة من القيم
في لغة بايثون، يُمكنك استخدام الدّالة len
لحساب عدد عناصر قائمة أو مجموعة من القيم.
في مُحرّك القوالب Jinja، يُمكنك استخدام المُرشّح length
للحصول على نفس النّتيجة.
يُمكنك استخدام هذا المُرشّح كما يلي:
{{ list | length }}
مع استبدال المُتغيّر list
بالمُتغيّر الذي يحمل القائمة التي ترغب بحساب عدد عناصرها.
المثال التّالي عبارة عن توضيح لكيفيّة استعمال المُرشّح length
للحصول على عدد عناصر القائمة comments
لمنح المُستخدم فكرة عن عدد التّعليقات المُتوفّرة:
{% set comments = ['Comment 1', 'Comment 2', 'Comment 3', 'Comment 4', 'Comment 5'] %} Comments({{ comments | length }}): {% for comment in comments %} <p> {{ comment }} </p> {% endfor %}
إن جرّبت المثال في ملفّ filters.html
فستُلاحظ نتيجة مُشابهة لما يلي:
Comments(5): Comment 1 Comment 2 Comment 3 Comment 4 Comment 5
يُمكنك استخدام هذه الفكرة للإشارة إلى عدد التّعليقات في مقال مُعيّن (كما هو مُلاحظ في المثال أعلاه) أو الإشارة إلى عدد الرّسائل الجديدة أو عدد التّنبيهات أو أي مجموعة أخرى من القيم التّي سيُساهم الإشارة إلى عددها في تسهيل تجربة المُستخدم مع تطبيقك.
مُلاحظة: يُمكنك كذلك استخدام المُرشّح count
للحصول على نفس النّتيجة.
المُرشّح list
هذا المُرشّح يُحوّل قيمة ما إلى قائمة كما تفعل الدّالة list()
في لغة بايثون. وإذا كانت القيمة عبارة عن سلسلة نصيّة فالنّتيجة ستكون عبارة عن قائمة من الحروف المتواجدة بالسّلسلة النّصيّة.
المثال التّالي عبارة عن توضيح لكيفيّة تحويل الكلمة Hello
إلى قائمة تحتوي على خمسة عناصر، كل عنصر منها يُمثّل حرفا من الكلمة Hello
:
{{ 'Hello' | list() }}
ستكون النّتيجة كما يلي:
['H', 'e', 'l', 'l', 'o']
المُرشّح random
المُرشّح random
يختار عنصرا عشوائيّا من مجموعة قيم وتكون نتيجته مُختلفة في كل مرّة بدون ترتيب مُعيّن.
يُمكنك استخدام هذا المُرشّح كما يلي:
{{ ['One', 'Two', 'Three'] | random() }}
إذا جرّبت المثال أعلاه في الملفّ filters.html
وتوجّهت إلى العنوان http://127.0.0.1:5000/filters فستحصل على أحد عناصر القائمة أعلاه بشكل غير مُرتّب وغير مُتوقّع وكلّما أعدت تحميل الصّفحة ستتغيّر القيمة إلى قيمة أخرى وقد تحصل أحيانا على نفس القيمة أكثر من مرّة.
يُمكنك استخدام هذا المُرشّح في تطبيقاتك لإضافة تفاعل أكثر إلى التّطبيق، فإن كان مثلا تطبيقك عبارة عن مُدوّنة فقد تعرض مقالا من المقالات بشكل عشوائي أو تعليقا من أحد المقالات أو غير ذلك.
يُمكنك كذلك أن تعرض مقولة بشكل عشوائي في كل مرّة يُعاد فيها تحميل الصّفحة، والمثال التّالي يُوضّح هذه الفكرة:
{% set quotes = ['Quote 1', 'Quote 2', 'Quote 3', 'Quote 4', 'Quote 5'] %} <div class="quote"> {{ quotes | random() }} </div>
إذا ما قمت بتجريب هذا المثال فستحصل على أحد عناصر القائمة quotes
في كلّ مرّة تُعيد فيها تحميل الصّفحة، و مع افتراض أنّ القائمة quotes
تحتوي على مقولات شهيرة ومُميّزة فإنّ إضافة هذه الميّزة إلى مُدوّنتك أو تطبيق مُشابه سيُشكّل فرقا كبيرا.
مُلاحظة: استعمال المُرشّح random
يعني بأنّك ستقوم بجلب العديد من السّجلات من قاعدة البيانات لتُرجع سجّلا واحدا فقط على المُتصفّح للمُستخدم، ومُعظم قواعد البيانات من نوع SQL أو NoSQL تستطيع جلب سجل واحد فقط بشكل عشوائيّ، لذا فإنّ استعمال هذا المُرشّح في بعض الحالات غير مُجد، ومن المُفضّل استخدام قاعدة بياناتك للحصول على سجل بشكل عشوائيّ عوضا عن جلب جميع السّجلات وتطبيق المُرشّح random
عليها.
المُرشّح replace
لتغيير قيمة إلى قيمة أخرى
هذا مُرشّح آخر من المُرشّحات التّي استوحيت من لغة بايثون، إذ أنّ المُرشّح replace
يعمل بنفس طريقة عمل التّابع replace
في لغة بايثون، وذلك بأخذ قيمتين كمُعاملات، المُعامل الأول عبارة عن القيمة القديمة، والمُعامل الثّاني يُمثّل القيمة الجديدة.
المثال التّالي يُوضّح كيفيّة عمل هذا المُرشّح:
{{ 'Hello World' | replace('Hello', 'Hi') }}
إذا قمت بتجربة المثال أعلاه فالنّتيجة ستكون Hi World
بدل Hello World
.
يُمكنك كذلك استعمال المُرشّح replace
مع مجموعة من القيم عوضا عن سلسلة نصيّة واحدة.
المثال التّالي يُوضّح كيفيّة استخدام المُرشّح replace
مع قائمة تحتوي على ثلاثة عناصر:
{% set list = ['One', 'Two', 'Three'] %} {{ list | replace('One', 1) }}
كما تُلاحظ، فقد استعملنا المُرشّح replace
لاستبدال القيمة One
بالقيمة 1
، لذا فإنّ النّتيجة ستكون كالآتي:
['1', 'Two', 'Three']
المُرشّح reverse
لعكس قيمة ما
يُمكن أن تحتاج في بعض الأحيان إلى طريقة سريعة لعكس سلسلة نصّية. يُمكنك القيام بالأمر ببساطة باستعمال المُرشّح reverse
كما في المثال التّالي:
{{ "Hello World!" | reverse() }}
ستُلاحظ بأنّ نتيجة المثال أعلاه هي كما يلي:
!dlroW olleH
أمّا بالنّسبة لمجموعات القيم مثل القوائم وغيرها فالأمر مُختلف قليلا، إذ أنّ تطبيق المُرشّح على قائمة سيُنتج كائنا من النّوع Iterator وهو نوع خاص يُمكنك استخدام حلقة for
معه للوصول إلى كل عنصر على حدة وللوصول إلى جميع العناصر في آن واحد فسيتوجّب عليك تحويله إلى قائمة باستعمال المُرشّح list
.
لتتوضّح الصّورة، جرّب المثال التّالي في ملفّ filters.html
:
{% set list = ['One', 'Two', 'Three'] %} {{ list | reverse() }}
ستُلاحظ نتيجة مُشابهة لما يلي:
<list_reverseiterator object at 0x7fc0b6262518>
لكن بعد استخدام المُرشّح list
على النّتيجة كما هو مُوضّح في السّطر التّالي:
{{ list | reverse() | list() }}
فستحصل على النّتيجة التّاليّة:
['Three', 'Two', 'One']
وهي قائمة عناصرها مُرتّبة ترتيبا عكسيّا للقائمة list
التّي عرّفناها من قبل:
['One', 'Two', 'Three']
مع التّأكيد على أنّك تستطيع الدّوران على نتيجة المُرشّح reverse
بحلقة for
دون الحاجة إلى تحويلها إلى قائمة بالمُرشّح list
، بل من الأفضل الدّوران على نتيجة المُرشّح reverse
مُباشرة لأنّ الدّوران عليها يتم بالوصول إلى كل عنصر على حدة عوضا عن تجميع كل عناصر قائمة ومن ثم الدّوران حولها.
إليك مثالا على كيفيّة استخدام الحلقة for
مُباشرة مع نتيجة المُرشّح reverse
:
{% set list = ['One', 'Two', 'Three'] %} <ul> {% for item in list | reverse() %} <li>{{ item }}</li> {% endfor %} </ul>
النّتيجة:
- Three - Two - One
المُرشّح safe
هذا المُرشّح مُهم ومُفيد جدّا، كما أنّ استعماله خطير كذلك، إذ يسمح لشيفرات HTML بالظّهور على أنّها آمنة، ما يعني بأنّها ستظهر في المُتصفّح كما كتبتها.
لتوضيح الأمر، جرّب ما يلي:
{{ "<h1>Hello World!</h1>" }}
ستُلاحظ في المُتصفّح ما يلي بخط عادي:
<h1>Hello World!</h1>
هذا لأنّ مُحرّك القوالب Jinja لا يسمح بأن تُترجم شيفرات HTML مُباشرة إلى المُتصفّح لما في ذلك من أخطار أمنيّة.
لكن إن كنت مُتأكّدا من أنّ شيفرة HTML المُتواجدة في مُتغيّر ما آمنة ولا تحتاج إلى إجراءات احتياطيّة، فيُمكنك استخدام المُرشّح safe
لتُترجم الشّيفرة وتظهر على المُتصفّح بشكل عادي.
لذا فالمثال التّالي سيُظهر الجملة Hello World!
بخط كبير داخل الوسم <h1>
:
{{ "<h1>Hello World!</h1>" | safe }}
المثال أعلاه قليل الورود لأنّ الهدف من المُرشّح safe
هو إعلام مُحرّك القوالب Jinja بأنّ هذه القيمة عبارة عن شيفرة HTML آمنة، والقيمة عادة ما تكون داخل مُتغيّر أو على شكل عنصر من مجموعة عناصر.
المثال التّالي يُوضّح كيفيّة استعمال المُرشّح safe
لعرض قائمة تحتوي على شيفرات HTML:
{% set list = ['<span div=list-item>One</span>', '<span div=list-item>Two</span>', '<span div=list-item>Three</span>'] %} <ul> {% for item in list %} <li>{{ item | safe }}</li> {% endfor %} </ul>
كما تُلاحظ، فإنّ القائمة list
تحتوي على عدّة عناصر، كل عنصر يحتوي على شيفرة HTML.
لو قمنا بالدّوران حول القائمة وعرضنا كل عنصر دون استعمال المُرشّح safe
، فستكون النّتيجة في المُتصفّح كما يلي:
<span div=list-item>One</span> <span div=list-item>Two</span> <span div=list-item>Three</span>
وهذه ليست النّتيجة التّي نُريدها، بل نُريد أن تُترجم الشّيفرة إلى لغة HTML يفهمها المُتصفّح.
أمّا عند استعمال المُرشّح safe
، فشيفرة HTML ستُترجم ليفهمها المُتصفّح وسيكون مصدر الصّفحة كما يلي:
<ul> <li><span div=list-item>One</span></li> <li><span div=list-item>Two</span></li> <li><span div=list-item>Three</span></li> </ul>
مُلاحظة: كن حذرا في استعمالك للمُرشّح safe
وتأكّد أولا من أنّ شيفرة HTML التّي تُريد عرضها في المُتصفّح آمنة بشكل تام، فإن حدث وأن أسأت استعمال هذا المُرشّح فقد تفتح مجالا لهجمات XSS ما قد يُخرّب تطبيقك أو يسمح للمُهاجم بالوصول إلى قاعدة بيانات التّطبيق أو غير ذلك من الأعمال الخبيثة.
خاتمة
تعرّفنا في هذا الدّرس على المزيد من المُرشّحات التّي يُوفرّها مُحرّك القوالب Jinja لتتمكّن من تطوير قوالب HTML بشكل أسرع وبأقل تكرار ممكن للشّيفرة. لكنّنا لم ننته بعد، إذ لا تزال في جعبة مُحرّك القوالب Jinja المزيد من المُرشّحات المُفيدة والتّي سنتعرّف عليها في الدّرس المُقبل.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.