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


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

مُقدّمة

تعرّفنا في الدّرس السّابق على بعض من مُرشّحات مُحرّك القوالب Jinja، مثل المُرشّح length لحساب عدد عناصر مجموعة ما، والمُرشّح list لتحويل القيم إلى قائمة، والمُرشّح replace لتعويض قيمة من نص ما بقيمة أخرى، وكذلك المُرشّح reverse لعكس قيمة نصيّة أو مجموعة من القيم، وانتهينا بالتّعرف على المُرشّح safe لإعلام Jinja بأنّ القيمة عبارة عن شيفرة HTML آمنة، في هذا الدّرس سنُكمل ما بدأناه بالتّعرف على المزيد من المُرشّحات المهمّة لننتقل بعد ذلك إلى كيفيّة إنشاء مُرشّح خاص بك مع مجموعة من الأمثلة في درس مُقبل.

main2.png

المُرشّح sort لترتيب قيمة قابلة للدّوران عليها

يُمكنك استخدام المُرشّح sort لترتيب أي قيمة من النّوع Iterable، بمعنى آخر، أي قيمة يُمكنك الدّوران عليها والوصول إلى كل عنصر من عناصرها باستعمال حلقة for، وتشمل هذه القيم القوائم والمجموعات والسّلاسل النّصيّة وقيما أخرى.

التّرتيب يكون من الأصغر إلى الأكبر بالنّسبة للأعداد، وبشكل أبجدي عند التّعامل مع السّلاسل النّصيّة.

المثال التّالي يُوضّح كيفيّة ترتيب الأعداد من أصغر عدد إلى أكبر عدد:

{{ "3241" | sort}}

ستُلاحظ بأنّ النتيجة عبارة عن قائمة كما يلي:

['1', '2', '3', '4'] 

والمثال التّالي يوضّح كيفيّة استعمال المُرشّح مع سلسلة نصيّة لترتيبها أبجديّا:

{{ "adbc" | sort}}

النّتيجة ستكون عبارة عن قائمة أيضا:


['a', 'b', 'c', 'd'] 

وبما أنّ قائمة عاديّة عبارة عن Iterable كذلك، فيُمكنك استخدام المُرشّح sort مع القوائم بنفس الطّريقة:


{{ ['c', 'b', 'd', 'a'] | sort() }}

النّتيجة:


['a', 'b', 'c', 'd']   

يُمكنك كذلك ترتيب كلمات كاملة:


{{ ['Ali', 'Do', 'Flask', 'Ball'] | sort() }}

النّتيجة:


['Ali', 'Ball', 'Do', 'Flask'] 

 

وعند جمع السّلاسل النّصيّة مع الأعداد فالنّتيجة ستبدأ أولا بالأعداد ثمّ السّلاسل النّصيّة بشكل مُرتّب ترتيبا أبجديّا:


{{ '41532dabec' | sort() }}

النّتيجة:


['1', '2', '3', '4', '5', 'a', 'b', 'c', 'd', 'e']

 

بعد بضعة تجارب، لاحظت بأنّ التّرتيب ممكن كذلك مع الكلمات العربيّة، ويُمكنك تجربة المثال التّالي لتتأكّد:


{{ ['أب', 'جبل', 'ثلاثة', 'ترجم'] | sort() }}

النّتيجة ستكون كما يلي:


['أب', 'ترجم', 'ثلاثة', 'جبل']

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

المُرشّح sum للحصول على جمع أعداد من مجموعة من القيم

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

لنضرب مثالا لقائمة مُشتريات، كل عنصر يُمثّل سعر بضاعة ما، وسيتوجّب عليك عرض القيمة الإجماليّة لقائمة المُشتريات وذلك بجمع الأسعار. لنضع القائمة التّالية كمثال لأسعار ثلاثة سلع:


[12, 14, 2]

للوصول إلى السّعر الإجمالي، سيتوجّب عليك جمع كل من 12 مع 14 ثمّ إضافة 2 للنّتيجة. وهذا بالضّبط ما يقوم به المُرشّح sum.

إليك المثال التّالي:


{% set prices = [12, 14, 2]  %}

{{ prices | sum() }}

النّتيجة ستكون العدد 28 وهي نتيجة العمليّة الحسابيّة 12 + 14 + 2.

يُمكنك كذلك جمع الأعداد إن كانت مُتواجدة في خاصيّة، وذلك لأنّ سعر سلعة أو بضاعة مُعيّنة قد يكون داخل خاصيّة مثل price أو اسم آخر، لذا فللوصول إلى سعر سلعة ما سيتوجّب عليك القيام بذلك كما يلي:


item.price

لذا فطريقة استعمال المُرشّح sum في هذه الحالة مُختلفة قليلا، إذ سيتوجّب عليك تمرير اسم الخاصيّة إلى المُعامل attribute كما يلي:


{{ items | sum(attribute='price') }}

المثال التّالي سيقوم بالدّوران حول عناصر المتغيّر items والوصول إلى سعر كل عنصر عبر الخاصيّة price ومن ثمّ جمعها للحصول على السّعر الإجمالي.

 

 

المُرشّح truncate لعرض جزء صغير من نص طويل

إذا تصفّحت بعض المُدوّنات ومواقع الدّروس المكتوبة فستُلاحظ بأنّ الصّفحة التّي تعرض قائمة المقالات والدّروس تتميّز بكونها مُتناسقة بحيث تعرض جزءا صغيرا فقط من المقال الكامل لتتمكّن من الوصول إلى صفحته وقراءته كاملا عبر زر "اقرأ المزيد” أو ما شابه ذلك.

يُمكننا أن نقوم بهذه المُهمّة ببساطة باستعمال المُرشّح truncate، كما يُمكنك التّحكم بحجم النّص المُختصر بكل سهولة.

المثال التّالي يُوضّح كيفيّة استخدام المُرشّح مع نص طويل:


{{ "مقال طويل يحتاج إلى تقصيره وعرض جزء صغير منه فقط ليكون تنسيق الصّفحة التّي تعرض عناوين المقالات أحسن" | truncate(length=50) }}

النّتيجة:


مقال طويل يحتاج إلى تقصيره وعرض جزء صغير منه ... 

يُمكنك تغيير طول النّص النّاتج بتغيير قيمة المُعامل length:


{{ "مقال طويل يحتاج إلى تقصيره وعرض جزء صغير منه فقط ليكون تنسيق الصّفحة التّي تعرض عناوين المقالات أحسن" | truncate(length=25) }}

هنا غيّرنا قيمة المُعامل length وجعلناها 25 عوضا عن 50، لذا فالنّتيجة ستكون هذه المرّة كما يلي:


مقال طويل يحتاج إلى ... 

المُرشّح urlize لتحويل الروابط النّصيّة إلى روابط قابلة للضّغط عليها

 

المُرشّح urlize مُرشّح مُفيد جدّا، إذ يقوم بتحويل أي رابط نصيّ إلى رابط يُمكنك الضّغط عليه للوصول إلى الموقع المُرتبط بذلك الرّابط.

 

لتفهم أكثر، جرّب المثال التّالي:


{{ "https://academy.hsoub.com/" }}

النّتيجة مُتوقّعة، السّلسلة النّصيّة أعلاه ستظهر بشكل نص عادي ولا يُمكنك الضّغط عليها للوصول إلى موقع الأكاديميّة.

الآن، حاول استعمال المُرشّح urlize مع النّص السّابق:


{{ "https://academy.hsoub.com/" | urlize() }}

ستُلاحظ بأنّ الرّابط في المُتصفّح أصبح مُختلفا وستتمكّن الآن من الضّغط عليه للوصول إلى موقع الأكاديميّة، وإن اطّلعت على مصدر الصّفحة فستُلاحظ ما يلي:


<a href="https://academy.hsoub.com/">https://academy.hsoub.com/</a>

ويُمكنك كذلك تجاهل الجزء http:// أو https:// ووضع رابط عادي كما يلي:


{{ "academy.hsoub.com" | urlize() }}

رغم ذلك الرّابط سيكون قابلا للضّغط عليه وسيوصلك إلى موقع الأكاديميّة.

يُمكنك كذلك تقصير طول الرّابط الذي يظهر في المُتصفّح إلى طول تستطيع التّحكم به، وذلك بتمرير الطّول إلى المُرشّح كمُعامل كما يلي:


{{ "https://academy.hsoub.com/tags/flask%20101/" | urlize(21) }}

النّتيجة ستكون كما يلي:


https://academy.hsoub... 

وعند النّقر على الرّابط ستتوجّه إلى صفحة سلسلة دروس Flask للمُبتدئين.

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

إليك المثال التّالي لتتوضّح الفكرة:



{{ " اضغط على الرّابط التّالي للوصول إلى سلسلة دروس إطار العمل فلاسك للمُبتدئين: https://academy.hsoub.com/tags/flask%20101/ أو تابع دروس بايثون عبر النّقر على الرّابط التّالي: https://academy.hsoub.com/programming/python/ " | urlize() }}

ستُلاحظ بأنّ كلّا من الرّابطين يعملان بشكل صحيح وأنّ النّصوص الأخرى عاديّة.

يُمكنك كذلك تقصير الرّوابط عبر تمرير طول إلى المُرشّح وسيُطبَّق على جميع الرّوابط، فمثلا نتيجة تمرير العدد 30 كمُعامل للمُرشّح urlize إلى المثال أعلاه هي كالتّالي:


اضغط على الرّابط التّالي للوصول إلى سلسلة دروس إطار العمل فلاسك للمُبتدئين: https://academy.hsoub.com/tags... أو تابع دروس بايثون عبر النّقر على الرّابط التّالي: https://academy.hsoub.com/prog...

المُرشّح wordcount لحساب عدد كلمات نص معيّن

هذا المُرشّح لا يحتاج إلى الكثير من الشّرح، إذ أنّ فكرته بسيطة، إذا ما طبّقته على نص مُعيّن فستحصل على عدد الكلمات في النّص.

مثال:


{{ 'واحد اثنان ثلاثة' | wordcount() }}

النّتيجة ستكون 3 لأنّ النّص أعلاه يحتوي على ثلاثة كلمات.

المُرشّح wordwrap لنسيق النّصوص الطّويلة.

المُرشّح wordwrap يقوم بتنسيق النّصوص الطّويلة بتقسيمها على عدّة أسطر، كل سطر لا يتعدّى 79 حرفا (يُمكنك تغيير هذا الطّول).

إليك مثالا على كيفيّة استخدام المُرشّح مع نص طويل نفترض أنّه مُتواجد داخل المُتغيّر text:


{{ text | wordwrap() }}

لكن رغم تطبيق المُرشّح على النّص فالنّتيجة لن تظهر إلّا عند تصفّحك لمصدر الصّفحة، وذلك لأنّ المُرشّح لا يُقسّم الأسطر باستعمال الوسم <br> افتراضيّا، بل يجب عليك أن تقوم بتحديد نوع التّقسيم الذي تُريده أولا عبر تمرير الفاصل إلى المُعامل wrapstring.

لذا للفصل بين الأسطر باستعمال الوسم <br> سيتوجّب علينا أن نُمرّره أولا إلى المُعامل wrapstring ثمّ تطبيق المُرشّح safe لإعلام Jinja بأنّ شيفرة HTML بداخل النّص آمنة (مُجدّدا، تأكّد أولا من أنّ النّص آمن بالفعل قبل تطبيق هذا المُرشّح).

 

لذا فالمثال أعلاه سيكون كما يلي:


{{ text  |  wordwrap(wrapstring='<br>') | safe() }}

وكما قلت سابقا، فالمُرشّح يقوم بالفصل بين سطر وسطر آخر حسب طول مُحدّد، والقيمة الافتراضيّة لهذا الطّول هو 79 ويُمكنك تغييره إلى ما تشاء عبر تمرير القيمة التّي تُريدها إلى المُعامل width كما يلي:


{{ text  |  wordwrap(width=20, wrapstring='<br>') | safe() }}

 

 

المُرشّح select لعرض نتيجة حسب اختبار ما

الاختبارات Tests في مُحرّك القوالب Jinja طريقة أخرى لمُعالجة القيم، وسنتطرّق إليها بشكل مُفصّل لاحقا، ما يجب أن تعرفه الآن هو أنّ المُرشّح select يُمكّنك من تطبيق اختبار على مجموعة من القيم لتُعرَض العناصر التّي تجتاز الاختبار وتُتجاهل العناصر الأخرى.

سنُلقي نظرة على عدّة أمثلة لتفهم الأمر.

أولا، سنُطبّق الاختبار odd على قائمة أعداد لاختيار الأعداد الفرديّة منها.

المثال الأول:


{% set numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9] %}
{{ numbers | select("odd") | list() }}

لاحظ بأنّنا استعملنا المُرشّح list على النّتيجة لتحويلها إلى قائمة وذلك لأنّها في الأصل كائن من النّوع Generator وهو نوع شبيه بالنّوع Iterator، أي أنّك تستطيع استخدام حلقة for عليه للوصول إلى كل عنصر على حدة، لكن لرؤية العناصر كاملة فسيتوجّب عليك تحويل النّتيجة إلى قائمة.

النّتيجة:


[1, 3, 5, 7, 9]

لابدّ أنّك لاحظت بأنّ النّتيجة لا تحتوي سوى على الأعداد الفرديّة من القائمة numbers، وهذا لأنّنا طبّقنا عليها المُرشّح select والاختبار odd (الذي يختبر ما إذا كانت قيمة عددا فرديّا أم لا).

المثال الثّاني:

في المثال الثّاني سنستعمل الاختبار string الذي يتحقّق ما إذا كانت القيمة سلسلة نصيّة أو لا.

في هذا المثال، سنُطبّق المُرشّح select مع الاختبار string على قائمة تحتوي على خليط من الأعداد والسّلاسل النّصيّة:


{% set numbers = [1, 'Flask', 3, 42, 'Python', 'Hello World!', 2312, 2017, 'Jinja'] %}

{{ numbers | select("string") | list() }}

النّتيجة:


['Flask', 'Python', 'Hello World!', 'Jinja'] 

ستُلاحظ بأنّ الاختبار تجاهل جميع الأعداد لأنّها ليست سلاسل نصيّة، وفي المُقابل النّتيجة تحتوي على السّلاسل النّصيّة فقط.

 

خاتمة

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





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


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



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

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

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


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

تسجيل الدخول

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


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