flask_cms أهم المرشحات المتوفرة بشكل قياسي في محرك القوالب Jinja - الجزء الثاني


عبدالهادي الديوري

مُقدّمة

بعد أن تعرّفنا على جزء من أهمّ المُرشّحات التّي يُمكنك استعمالها لتفادي تكرار شيفرة عدّة مرّات والحصول على تجربة تطوير أحسن، سنُكمل في هذا الدّرس ما بدأناه بالتّعرفّ على قائمة مُرشّحات أخرى لتكون لديك فكرة أفضل عن كيفيّة استخدام مُحرّك القوالب Jinja والمُرشّحات المتواجدة به.

main2.png

المُرشّح 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 المزيد من المُرشّحات المُفيدة والتّي سنتعرّف عليها في الدّرس المُقبل.





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن