الفرق بين المراجعتين لصفحة: «Twig/templates»
أسامه-دمراني (نقاش | مساهمات) إدخال 2.1: تمام المحتوى - انظر أيضًا - المصادر |
جميل-بيلوني (نقاش | مساهمات) طلا ملخص تعديل |
||
(11 مراجعة متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE: Twig لمصممي القوالب}}</noinclude> | <noinclude>{{DISPLAYTITLE:محرك Twig لمصممي القوالب}}</noinclude> | ||
تشرح هذه الصفحةُ البنيةَ اللغوية لمحرك القوالب ودلالياته symantics وسيكون ذا نفع عظيم كمرجع لأولئك الذين ينشئون قوالب Twig. | |||
== مقدمة == | |||
القالب هو ملف نصي عادي يستطيع أن يولّد أي صيغة نصية مثل HTML - XML - CSV - LaTex أو غيرها، وليس له امتداد محدد خاص به، فيصلح له امتداد html أو xml مثلًا. | |||
ويحتوي القالب على متغيرات variables أو تعابير expressions، تُستبدَل القيم بها عند تقييم القالب، ووسوم tags تتحكم في منطق القالب. وفيما يلي قالب بسيط يوضح بعض الأساسيات، وسننظر في باقي التفاصيل لاحقًا.<syntaxhighlight lang="html"> | |||
ويحتوي القالب على متغيرات | |||
<!DOCTYPE html> | <!DOCTYPE html> | ||
<html> | <html> | ||
سطر 21: | سطر 21: | ||
</body> | </body> | ||
</html> | </html> | ||
</syntaxhighlight>لدينا نوعان من المحدِّدات | </syntaxhighlight>لدينا نوعان من المحدِّدات delimiters هما <code>{% ... %}</code> و <code><nowiki>{{ ... }}</nowiki></code>، يُستخدم الأول لتنفيذ تعليمات مثل حلقات for التكرارية، أما الآخر فيخرج نتيجة تعبير ما. | ||
== تكامل بيئات التطوير IDE == | |||
تدعم بيئات تطوير عديدة تمييز التراكيب اللغوية | تدعم بيئات تطوير عديدة تمييز التراكيب اللغوية syntax highlighting لمحرك Twig والإكمال التلقائي، منها على سبيل المثال: | ||
* Textmate الموجود في [https://github.com/Anomareh/PHP-Twig.tmbundle حزمة Twig]. | * Textmate الموجود في [https://github.com/Anomareh/PHP-Twig.tmbundle حزمة Twig]. | ||
سطر 38: | سطر 37: | ||
* Coda2 من [https://github.com/muxx/Twig-HTML.mode وضع Twig syntax] آخر. | * Coda2 من [https://github.com/muxx/Twig-HTML.mode وضع Twig syntax] آخر. | ||
* Komodo و Komodo Edit من وضع Twig للتحقق من البنى اللغوية وتمييزها. | * Komodo و Komodo Edit من وضع Twig للتحقق من البنى اللغوية وتمييزها. | ||
* | * Notepad++ من [https://github.com/Banane9/notepadplusplus-twig مميِّز (Notepad++) لـ Twig]. | ||
* Emacs من [http://web-mode.org web-mode.el]. | * Emacs من [http://web-mode.org web-mode.el]. | ||
* Atom من [https://github.com/reesef/php-twig PHP-twig for atom]. | * Atom من [https://github.com/reesef/php-twig PHP-twig for atom]. | ||
* Visual Studio Code من [https://marketplace.visualstudio.com/items?itemName=bajdzis.vscode-twig-pack Twig pack]. | * Visual Studio Code من [https://marketplace.visualstudio.com/items?itemName=bajdzis.vscode-twig-pack Twig pack]. | ||
كذلك فإن [https://twigfiddle.com TwigFiddle] هي خدمة أونلاين تسمح لك بتنفيذ قوالب Twig من المتصفح، وتدعم جميع إصداراته. | كذلك فإن [https://twigfiddle.com TwigFiddle] هي خدمة ويب (أونلاين) تسمح لك بتنفيذ قوالب Twig من المتصفح، وتدعم جميع إصداراته. | ||
== المتغيرات == | == المتغيرات == | ||
يمرِّر التطبيق المتغيرات إلى القوالب من أجل التعديل داخل القالب، وقد تحتوي المتغيرات على سمات | يمرِّر التطبيق المتغيرات إلى القوالب من أجل التعديل داخل القالب، وقد تحتوي المتغيرات على سمات attributes أو عناصر تستطيع الوصول إليها، ويعتمد التمثيل البصري للمتغير على التطبيق الذي يوفره. | ||
استخدم النقطة | استخدم النقطة <code>.</code> للوصول إلى سمات متغير ما سواء كانت توابع أو خصائص لكائن PHP أو عناصر من مصفوفة [[PHP]].<syntaxhighlight lang="twig"> | ||
{{ foo.bar }} | {{ foo.bar }} | ||
</syntaxhighlight>من المهم أن تعرف أن الأقواس المعقوصة ليست جزءًا من المتغير نفسه لكن من تعليمة الطباعة، وحين تريد الوصول إلى متغير داخل وسم ما فلا تضع أقواسًا حوله. | </syntaxhighlight>من المهم أن تعرف أن الأقواس المعقوصة ليست جزءًا من المتغير نفسه لكن من تعليمة الطباعة، وحين تريد الوصول إلى متغير داخل وسم ما فلا تضع أقواسًا حوله. | ||
بداعي التبسيط، ينفذ <code>foo.bar</code> من المثال السابق ما يلي في طبقة PHP: | |||
بداعي التبسيط، ينفذ <code>foo.bar</code> ما يلي في طبقة PHP: | |||
* يتحقق إن كان <code>foo</code> مصفوفة وما إذا كان <code>bar</code> عنصرًا صالحًا. | * يتحقق إن كان <code>foo</code> مصفوفة وما إذا كان <code>bar</code> عنصرًا صالحًا. | ||
* فإن لم يكونا كذلك وكان <code>foo</code> كائنًا فيتحقق إن كان <code>bar</code> خاصية صالحة. | * فإن لم يكونا كذلك وكان <code>foo</code> كائنًا فيتحقق إن كان <code>bar</code> خاصية صالحة. | ||
* فإن لم تكن وكان <code>foo</code> كائنًا فيتحقق إن كان <code>bar</code> تابعٌ صالح، حتى لو كان <code>bar</code> هو المنشئ | * فإن لم تكن وكان <code>foo</code> كائنًا فيتحقق إن كان <code>bar</code> تابعٌ صالح، حتى لو كان <code>bar</code> هو المنشئ constructor فعندئذ استخدم <code>constructor()_</code>. | ||
* فإن لم يكن وكان <code>foo</code> كائنًا فيتحقق أن <code>hasBar</code> تابع صالح. | * فإن لم يكن وكان <code>foo</code> كائنًا فيتحقق أن <code>hasBar</code> تابع صالح. | ||
* فإن لم يكن فيعيد <code>null</code>. | * فإن لم يكن فيعيد <code>null</code>. | ||
سطر 65: | سطر 63: | ||
* تحقق إذا كان <code>foo</code> مصفوفة و<code>bar</code> عنصرًا صالحًا، فإن لم يكن فأعد <code>null</code>. | * تحقق إذا كان <code>foo</code> مصفوفة و<code>bar</code> عنصرًا صالحًا، فإن لم يكن فأعد <code>null</code>. | ||
إذا كان المتغير أو السمة غير موجودان فستحصل على <code>null</code> حين يكون خيار <code>strict_variables</code> على <code>false</code>، أما إذا تم ضبط <code>strict_variables</code> فإن Twig سيرفع خطأ (انظر [[Twig/api|خيارات البيئة]] في صفحة واجهة برمجة التطبيقات). | إذا كان المتغير أو السمة غير موجودان فستحصل على <code>null</code> حين يكون خيار <code>strict_variables</code> على <code>false</code>، أما إذا تم ضبط <code>strict_variables</code> على القيمة <code>true</code> فإن Twig سيرفع خطأ (انظر [[Twig/api|خيارات البيئة]] في صفحة واجهة برمجة التطبيقات). | ||
لاحظ أنك إذا أردت أن تصل إلى سمة ديناميكية لمتغير ما، فإن عليك استخدام دالة [ | لاحظ أنك إذا أردت أن تصل إلى سمة ديناميكية لمتغير ما، فإن عليك استخدام دالة [[Twig/attribute|<code>attribute</code>]]، وهي مفيدة حين تحتوي السمة على محارف خاصة مثل <code>-</code> التي ستُفسَّر على أنها عامل السالب.<syntaxhighlight lang="twig"> | ||
{# equivalent to the non-working foo.data-foo #} | {# equivalent to the non-working foo.data-foo #} | ||
{{ attribute(foo, 'data-foo') }} | {{ attribute(foo, 'data-foo') }} | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== المتغيرات العامة | === المتغيرات العامة Global Variables === | ||
المتغيرات التالية تكون متاحة دائمًا في القوالب: | المتغيرات التالية تكون متاحة دائمًا في القوالب: | ||
* <code>_self</code>: يشير إلى اسم القالب الحالي. | * <code>_self</code>: يشير إلى اسم القالب الحالي. | ||
* <code>_context</code>: يشير إلى السياق الحالي. | * <code>_context</code>: يشير إلى السياق الحالي. | ||
* <code>_charset</code>: يشير إلى مجموعة المحارف | * <code>_charset</code>: يشير إلى مجموعة المحارف charset. | ||
== ضبط المتغيرات | === ضبط المتغيرات Setting Variables === | ||
تستطيع تعيين القيم إلى المتغيرات التي داخل كتل الشيفرات، وتستخدم التعيينات وسم <code>set</code>:<syntaxhighlight lang="twig"> | تستطيع تعيين القيم إلى المتغيرات التي داخل كتل الشيفرات، وتستخدم التعيينات وسم <code>[[Twig/set|set]]</code>:<syntaxhighlight lang="twig"> | ||
{% set foo = 'foo' %} | {% set foo = 'foo' %} | ||
سطر 88: | سطر 86: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== | == المرشحات Filters == | ||
يمكن التعديل على المتغيرات باستخدام الفلاتر، ويفصل بينها وبين المتغيرات برمز الأنبوب <code>|</code>، ويمكن ربط عدة | يمكن التعديل على المتغيرات باستخدام المرشحات أو الفلاتر، ويفصل بينها وبين المتغيرات برمز الأنبوب <code>|</code>، ويمكن ربط عدة مرشحات معًا في تسلسل واحد، وحينئذ يُطبق خرج أحد تلك المرشحات على المرشح الذي يليه. انظر المثال التالي الذي يحذف جميع وسوم HTML من <code>name</code> ويجعلها على نسق العنوان:<syntaxhighlight lang="twig"> | ||
{{ name|striptags|title }} | {{ name|striptags|title }} | ||
</syntaxhighlight>ويكون | </syntaxhighlight>ويكون للمرشحات التي تقبل الوسائط أقواسًا حول الوسائط. المثال التالي يربط بين عناصر قائمة باستخدام فاصلة إنجليزية <code>,</code>:<syntaxhighlight lang="twig"> | ||
{{ list|join(', ') }} | {{ list|join(', ') }} | ||
</syntaxhighlight>إذا أردت تطبيق | </syntaxhighlight>إذا أردت تطبيق مرشح على جزء من الشيفرة فغلِّفه بوسم <code>[[Twig/apply|apply]]</code>:<syntaxhighlight lang="twig"> | ||
{% apply upper %} | {% apply upper %} | ||
This text becomes uppercase | This text becomes uppercase | ||
{% endapply %} | {% endapply %} | ||
</syntaxhighlight> | </syntaxhighlight>انتقل إلى صفحة [[Twig/filters|المرشحات]] للتعرف على المرشحات التي يوفرها Twig. | ||
== الدوال == | == الدوال == | ||
سطر 106: | سطر 104: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== الوسائط المسماة | == الوسائط المسماة Named Arguments == | ||
<syntaxhighlight lang="twig"> | <syntaxhighlight lang="twig"> | ||
{% for i in range(low=1, high=10, step=2) %} | {% for i in range(low=1, high=10, step=2) %} | ||
{{ i }}, | {{ i }}, | ||
{% endfor %} | {% endfor %} | ||
</syntaxhighlight>استخدام الوسائط المسماة | </syntaxhighlight>استخدام الوسائط المسماة named arguments يجعل قوالبك أكثر وضوحًا حول معنى القيم التي تمررها كوسائط:<syntaxhighlight lang="twig"> | ||
{{ data|convert_encoding('UTF-8', 'iso-2022-jp') }} | {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }} | ||
سطر 123: | سطر 121: | ||
{# أو تخطى قيمة الصيغة باستخدام وسيط مسمى للمنطقة الزمنية #} | {# أو تخطى قيمة الصيغة باستخدام وسيط مسمى للمنطقة الزمنية #} | ||
{{ "now"|date(timezone="Europe/Paris") }} | {{ "now"|date(timezone="Europe/Paris") }} | ||
</syntaxhighlight>وتستطيع استخدام الوسائط المسماة والموضعية | </syntaxhighlight>وتستطيع استخدام الوسائط المسماة والموضعية positional في استدعاء واحد، لكن يجب أن تكون الوسائط الموضعية في ذلك الاستدعاء قبل الوسائط المسماة:<syntaxhighlight lang="twig"> | ||
{{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }} | {{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }} | ||
</syntaxhighlight> | </syntaxhighlight>'''تذكير''': تسرد كل صفحة من صفحات المرشحات والدوال في هذا التوثيق جميع الوسائط المدعومة. | ||
== هيكل التحكم == | == هيكل التحكم == | ||
تشير هياكل التحكم إلى الأشياء التي تتحكم في تدفق البرنامج وسيره، مثل التعليمات الشرطية | تشير هياكل التحكم إلى الأشياء التي تتحكم في تدفق البرنامج وسيره، مثل التعليمات الشرطية <code>if/elseif/else</code> وحلقات <code>for</code> التكرارية، إضافة إلى الكتل مثلًا blocks، وتكون هياكل التحكم داخل كتل <code>{% ... %}</code> . | ||
فمثلًا، استخدم وسم [[Twig/for|for]] من أجل عرض قائمة من المستخدمين الموجودين في متغير اسمه <code>users</code> :<syntaxhighlight lang="twig"> | فمثلًا، استخدم وسم [[Twig/for|<code>for</code>]] من أجل عرض قائمة من المستخدمين الموجودين في متغير اسمه <code>users</code> :<syntaxhighlight lang="twig"> | ||
<h1>Members</h1> | <h1>Members</h1> | ||
<ul> | <ul> | ||
سطر 137: | سطر 135: | ||
{% endfor %} | {% endfor %} | ||
</ul> | </ul> | ||
</syntaxhighlight>يمكن استخدام وسم [[Twig/if|if]] لاختبار تعبير ما:<syntaxhighlight lang="twig"> | </syntaxhighlight>يمكن استخدام وسم [[Twig/if|<code>if</code>]] لاختبار تعبير ما:<syntaxhighlight lang="twig"> | ||
{% if users|length > 0 %} | {% if users|length > 0 %} | ||
<ul> | <ul> | ||
سطر 145: | سطر 143: | ||
</ul> | </ul> | ||
{% endif %} | {% endif %} | ||
</syntaxhighlight>اذهب إلى صفحة [[Twig/tags | </syntaxhighlight>اذهب إلى صفحة [[Twig/tags|الوسوم]] للمزيد عن الوسوم التي يوفرها Twig. | ||
== التعليقات == | == التعليقات == | ||
إذا أردت تحويل جزء من سطر في قالب إلى تعليق فاستخدم <code>{# ...#}</code>، وهذا مفيد في التنقيح (debugging | إذا أردت تحويل جزء من سطر في قالب إلى تعليق فاستخدم <code>{# ...#}</code>، وهذا مفيد في التنقيح (debugging لاحقًا أو إضافة معلومات لمصممي القوالب الآخرين أو لنفسك:<syntaxhighlight lang="twig"> | ||
{# note: disabled template because we no longer use this | {# note: disabled template because we no longer use this | ||
{% for user in users %} | {% for user in users %} | ||
سطر 157: | سطر 155: | ||
== إدراج قوالب أخرى == | == إدراج قوالب أخرى == | ||
تُستخدم دالة <code>include</code> لإدراج قالب ما، وتعيد المحتوى الذي يخرجه ذلك القالب إلى القالب الحالي:<syntaxhighlight lang="twig"> | تُستخدم دالة <code>[[Twig/include function|include]]</code> لإدراج قالب ما، وتعيد المحتوى الذي يخرجه ذلك القالب إلى القالب الحالي:<syntaxhighlight lang="twig"> | ||
{{ include('sidebar.html') }} | {{ include('sidebar.html') }} | ||
</syntaxhighlight>ويجب أن يكون للقوالب المُدرَجة | </syntaxhighlight>ويجب أن يكون للقوالب المُدرَجة وصولًا إلى نفس سياق القالب الذي يحتويها، وهذا يعني أن أي متغير مُعرّف في القالب الرئيسي سيكون متاحًا في القالب المدرَج أيضًا:<syntaxhighlight lang="twig"> | ||
{% for box in boxes %} | {% for box in boxes %} | ||
{{ include('render_box.html') }} | {{ include('render_box.html') }} | ||
سطر 170: | سطر 168: | ||
== وراثة القوالب == | == وراثة القوالب == | ||
إن أقوى مزية في Twig هي وراثة القوالب | إن أقوى مزية في Twig هي وراثة القوالب template inheritance ، وهي تسمح لك ببناء قالب هيكلي أساسي يحتوي على جميع العناصر المشتركة في موقعك، ويعرِّف '''الوحدات والكتل blocks''' التي تستطيع القوالب الأبناء child templates أن ترثه وتعدل عليه وتستبدله، وسننظر في مثال الآن للتوضيح. | ||
لنعرِّف قالبًا أساسيًا وليكن <code>base.html</code> ، الذي يعرِّف مستند HTML هيكلي يمكن استخدامه لصفحة من عمودين:<syntaxhighlight lang="twig"> | لنعرِّف قالبًا أساسيًا وليكن <code>base.html</code> ، الذي يعرِّف مستند [[HTML]] هيكلي يمكن استخدامه لصفحة من عمودين:<syntaxhighlight lang="twig"> | ||
<!DOCTYPE html> | <!DOCTYPE html> | ||
<html> | <html> | ||
سطر 190: | سطر 188: | ||
</body> | </body> | ||
</html> | </html> | ||
</syntaxhighlight>في هذا المثال فإن وسوم <code>[[Twig/block|block]]</code> تعرِّف الوحدات الأربع التي تستطيع القوالب الأبناء أن تملأها، وما يفعله وسم <code>block</code> هو إخبار محرك القالب أن قالبًا ابنًا قد | </syntaxhighlight>في هذا المثال فإن وسوم <code>[[Twig/block|block]]</code> تعرِّف الوحدات الأربع التي تستطيع القوالب الأبناء أن تملأها، وما يفعله وسم [[Twig/block|<code>block</code>]] هو إخبار محرك القالب أن قالبًا ابنًا قد يستبدل هذه الأجزاء من القالب، والقالب الابن قد يكون شبيهًا بما يلي:<syntaxhighlight lang="twig"> | ||
{% extends "base.html" %} | {% extends "base.html" %} | ||
سطر 206: | سطر 204: | ||
</p> | </p> | ||
{% endblock %} | {% endblock %} | ||
</syntaxhighlight>الوسم <code>[[Twig/extends|extends]]</code> هو الفيصل هنا إذ يخبر محركَ القالب أن هذا القالب يوسِّع قالبًا | </syntaxhighlight>الوسم <code>[[Twig/extends|extends]]</code> هو الفيصل هنا إذ يخبر محركَ القالب أن هذا القالب يوسِّع قالبًا آخر ويرث منه، وحين يقيم نظام القالب هذا القالب فإنه يبحث عن القالب الأب أولًا، إذ يجب أن يكون وسم [[Twig/extends|<code>extends</code>]] هو أول وسم في القالب. وبما أن القالب الابن لا يعرِّف كتلة <code>footer</code> فإن القيمة التي من القالب الأب هي التي تُستخدم. | ||
من الممكن أن تُخرِج محتويات الكتلة الأب من خلال استخدام دالة <code>[[Twig/parent|parent]]</code>، انظر:<syntaxhighlight lang="twig"> | من الممكن أن تُخرِج محتويات الكتلة الأب من خلال استخدام دالة <code>[[Twig/parent|parent]]</code>، انظر:<syntaxhighlight lang="twig"> | ||
سطر 214: | سطر 212: | ||
{{ parent() }} | {{ parent() }} | ||
{% endblock %} | {% endblock %} | ||
</syntaxhighlight>ستجد أن توثيق وسم <code>[[Twig/extends|extends]]</code> يصف خصائص أكثر تقدمًا مثل تشعب الكتل والنطاق والوراثة الديناميكية والوراثة الشرطية. كذلك، لاحظ أن Twig يدعم الوراثة المتعددة من خلال إعادة الاستخدام الأفقية بمساعدة وسم <code>[[Twig/use|use]]</code>. | </syntaxhighlight>ستجد أن توثيق وسم <code>[[Twig/extends|extends]]</code> يصف خصائص أكثر تقدمًا مثل تشعب الكتل والنطاق والوراثة الديناميكية والوراثة الشرطية. كذلك، لاحظ أن Twig يدعم الوراثة المتعددة من خلال إعادة الاستخدام الأفقية horizontal reuse بمساعدة وسم <code>[[Twig/use|use]]</code>. | ||
== تهريب HTML == | == تهريب HTML == | ||
حين نولد HTML من القوالب فإننا نخاطر باحتمال أن يحتوي متغير على محارف تؤثر على شيفرة HTML الناتجة، وهناك حلان لهذه المشكلة: إما بتهريب | حين نولد HTML من القوالب فإننا نخاطر باحتمال أن يحتوي متغير على محارف تؤثر على شيفرة HTML الناتجة، وهناك حلان لهذه المشكلة: إما بتهريب escape كل متغير يدويًا أو تهريب كل شيء افتراضيًا. | ||
وإن Twig يدعم كلا الحلين، بل إن التهريب الآلي مفعَّل افتراضيًا، ويمكن تعديل استراتيجية التهريب الآلي من خلال خيار [[Twig/autoescape|autoscape]]، ويكون الافتراضي على <code>html</code>. | وإن Twig يدعم كلا الحلين، بل إن التهريب الآلي مفعَّل افتراضيًا، ويمكن تعديل استراتيجية التهريب الآلي من خلال خيار [[Twig/autoescape|<code>autoscape</code>]]، ويكون الافتراضي على <code>html</code>. | ||
=== التعامل مع التهريب اليدوي === | === التعامل مع التهريب اليدوي === | ||
إذا كان التهريب اليدوي مفعلًا فسيكون تهريب المتغيرات مسؤوليتك أنت إذا احتجت إلى ذلك، وتهرب أي متغير يأتي من مصدر غير موثوق فيه. ونستخدم | إذا كان التهريب اليدوي مفعلًا فسيكون تهريب المتغيرات مسؤوليتك أنت إذا احتجت إلى ذلك، وتهرب أي متغير يأتي من مصدر غير موثوق فيه. ونستخدم مرشح <code>[[Twig/escape|escape]]</code> أو <code>e</code> اختصارًا:<syntaxhighlight lang="twig"> | ||
{{ user.username|e }} | {{ user.username|e }} | ||
</syntaxhighlight>يستخدم | </syntaxhighlight>يستخدم مرشح [[Twig/escape|<code>escape</code>]] استراتيجية <code>html</code> افتراضيًا، لكن قد تريد استخدام استراتيجية أخرى استخدامًا صريحًا، وذلك وفقًا لسياق التهريب:<syntaxhighlight lang="twig"> | ||
{{ user.username|e('js') }} | {{ user.username|e('js') }} | ||
{{ user.username|e('css') }} | {{ user.username|e('css') }} | ||
سطر 233: | سطر 231: | ||
=== التعامل مع التهريب الآلي === | === التعامل مع التهريب الآلي === | ||
تستطيع تحديد جزء من قالب ما ليتم تهريبه آليًا سواء كان التهريب الآلي مفعلًا أم لا، وذلك باستخدام وسم [[Twig/autoescape|autoscape]]:<syntaxhighlight lang="twig"> | تستطيع تحديد جزء من قالب ما ليتم تهريبه آليًا سواء كان التهريب الآلي مفعلًا أم لا، وذلك باستخدام وسم [[Twig/autoescape|<code>autoscape</code>]]:<syntaxhighlight lang="twig"> | ||
{% autoescape %} | {% autoescape %} | ||
HTML سيهرّب كل شيء في هذه الكتلة باستخدام استراتيجية | HTML سيهرّب كل شيء في هذه الكتلة باستخدام استراتيجية | ||
سطر 244: | سطر 242: | ||
== التهريب == | == التهريب == | ||
قد ترغب أحيانًا -أو تضطر- إلى أن تجعل Twig يتجاهل أجزاءً كان يمكن أن تعالَج على أنها متغيرات أو كتل، فمثلًا إذا استُخدمت البنية الافتراضية وتريد استخدام | قد ترغب أحيانًا -أو تضطر- إلى أن تجعل Twig يتجاهل أجزاءً كان يمكن أن تعالَج على أنها متغيرات أو كتل، فمثلًا إذا استُخدمت البنية الافتراضية وتريد استخدام <code><nowiki>}}</nowiki></code> كسلسلة نصية خام في القالب من غير أن تبدأ متغيرًا جديدًا، فيجب أن تحتال على السلوك الافتراضي، وأسهل طريقة لذلك هي بإخراج <code><nowiki>}}</nowiki></code> المفسرة على أنها محدِّد المتغير variable delimiter من خلال استخدام تعبير متغير:<syntaxhighlight lang="twig"> | ||
{{ '{{' }} | {{ '{{' }} | ||
</syntaxhighlight>وبالنسبة للأقسام والكتل الأكبر فمن المنطق أن تحدد الكتلة بوسم [[Twig/verbatim|verbatim]]. | </syntaxhighlight>وبالنسبة للأقسام والكتل الأكبر فمن المنطق أن تحدد الكتلة بوسم [[Twig/verbatim|<code>verbatim</code>]]. | ||
== التعليمات الجامعة | == التعليمات الجامعة Macros == | ||
يمكن موازنة التعليمات الجامعة مع الدوال في لغات البرمجة العادية، وهي مفيدة في إعادة استخدام أجزاء شيفرات HTML لئلا نكرر كتابتها في كل مرة، وستجد شرحها في توثيق وسم [[macro]]. | يمكن موازنة التعليمات الجامعة أو الماكرو مع الدوال في لغات البرمجة العادية، وهي مفيدة في إعادة استخدام أجزاء شيفرات HTML لئلا نكرر كتابتها في كل مرة، وستجد شرحها في توثيق وسم [[Twig/macro|<code>macro</code>]]. | ||
== التعبيرات == | == التعبيرات == | ||
يسمح Twig بالتعابير في أي مكان تقريبًا. لاحظ أن أسبقية العوامل | يسمح Twig بالتعابير في أي مكان تقريبًا. لاحظ أن أسبقية العوامل operators تكون كما يلي، مع وضع العوامل الأقل أسبقية في البداية: | ||
* <code>?:</code> | * <code>?:</code> | ||
* <code>b-and</code> | * <code>b-and</code> | ||
* <code>b-xor</code> | * <code>b-xor</code> | ||
سطر 261: | سطر 259: | ||
* <code>and</code> | * <code>and</code> | ||
* <code>==</code> | * <code>==</code> | ||
* <code>!=</code> | * <code>!=</code> | ||
* <code><=></code> | * <code><=></code> | ||
* <code><</code> | * <code><</code> | ||
* <code>></code> | * <code>></code> | ||
* <code>>=</code> | * <code>>=</code> | ||
* <code><=</code> | |||
* <code>in</code> | * <code>in</code> | ||
* <code>matches</code> | * <code>matches</code> | ||
سطر 290: | سطر 289: | ||
{{ greeting ~ name|lower }} {# Hello fabien #} | {{ greeting ~ name|lower }} {# Hello fabien #} | ||
{# | {# استخدم الأقواس لتغيير الأولوية #} | ||
{{ (greeting ~ name)|lower }} {# hello fabien #} | {{ (greeting ~ name)|lower }} {# hello fabien #} | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== القيم مصنفة النوع | === القيم مصنفة النوع Literals === | ||
إن أبسط صورة للتعابير هي القيم مصنفة النوع، وهي تمثيل لأنواع بيانات PHP مثل السلاسل النصية والأرقام والمصفوفات، فلدينا القيم التالية مثلًا: | إن أبسط صورة للتعابير هي القيم مصنفة النوع، وهي تمثيل لأنواع بيانات PHP مثل السلاسل النصية والأرقام والمصفوفات، فلدينا القيم التالية مثلًا: | ||
* "Hello World": أي شيء بين علامتي تنصيص مفردتين أو مزدوجتين فإنه سلسلة نصية، وهذه السلاسل مفيدة إذا أردت إضافة سلسلة نصية في القالب كوسيط في استدعاء دالة مثلًا أو | * <code>"Hello World"</code>: أي شيء بين علامتي تنصيص مفردتين أو مزدوجتين فإنه سلسلة نصية، وهذه السلاسل مفيدة إذا أردت إضافة سلسلة نصية في القالب كوسيط في استدعاء دالة مثلًا أو مرشح أو حتى لتوسيع القالب أو إدراجه. وقد تحتوي السلسلة النصية على محدِّد إذا سُبقت بشرطة مائلة خلفية <code>\</code> كما في <code>'It\'s good'</code>، أما إذا احتوت السلسلة النصية على شرطة مائلة خلفية كما في <code>'c:\Program Files'</code> فهرِّبها بتكرارها <code>'c:\\Program Files'</code> . | ||
* <code>42</code> / <code>42.23</code>: تُنشأ الأرقام الصحيحة | * <code>42</code> / <code>42.23</code>: تُنشأ الأرقام الصحيحة integers والأرقام العشرية بكتابة الرقم فقط، فإذا وجدت نقطة <code>.</code> في الرقم فإنه يكون عشريًا. | ||
* ["foo", "bar"]: تُعرَّف المصفوفات بسلسلة من التعابير مفصولة بفاصلة إنجليزية <code>,</code> وتُغلَّف بأقواس مربعة <code>[]</code>. | * <code>["foo", "bar"]</code>: تُعرَّف المصفوفات بسلسلة من التعابير مفصولة بفاصلة إنجليزية <code>,</code> وتُغلَّف بأقواس مربعة <code>[]</code>. | ||
* {"foo": "bar"}: تُعرَّف الجداول بقائمة من المفاتيح والقيم المفصول بينها بفاصلة إنجليزية وتُغلَّف بأقواس معقوصة <code>{}</code> . | * <code>{"foo": "bar"}</code>: تُعرَّف الجداول بقائمة من المفاتيح والقيم المفصول بينها بفاصلة إنجليزية وتُغلَّف بأقواس معقوصة <code>{}</code> . | ||
<syntaxhighlight lang="twig"> | <syntaxhighlight lang="twig"> | ||
{# المفاتيح كسلسلة نصية #} | {# المفاتيح كسلسلة نصية #} | ||
سطر 322: | سطر 321: | ||
* <code>true</code> / <code>false</code>: تمثل <code>true</code> القيمة المتحققة أو الصحيحة، أما <code>false</code> فتمثل القيمة الخاطئة أو غير المتحققة. | * <code>true</code> / <code>false</code>: تمثل <code>true</code> القيمة المتحققة أو الصحيحة، أما <code>false</code> فتمثل القيمة الخاطئة أو غير المتحققة. | ||
* <code>null</code>: لا تمثل <code>null</code> قيمة بعينها، وتعاد إذا كان المتغير غير موجودًا، وتُستخدم <code>none</code> كاسم بديل | * <code>null</code>: لا تمثل <code>null</code> قيمة بعينها، وتعاد إذا كان المتغير غير موجودًا، وتُستخدم <code>none</code> كاسم بديل alias للقيمة غير المعرفة <code>null</code>. | ||
كذلك، من الممكن أن تتشعب المصفوفات والجداول:<syntaxhighlight lang="twig"> | كذلك، من الممكن أن تتشعب المصفوفات والجداول:<syntaxhighlight lang="twig"> | ||
{% set foo = [1, {"foo": "bar"}] %} | {% set foo = [1, {"foo": "bar"}] %} | ||
</syntaxhighlight>لاحظ أن استخدام السلاسل النصية ذوات علامات التنصيص المزدوجة أو المفردة ليس لها تأثير على الأداء، لكن استكمال السلاسل النصية | </syntaxhighlight>لاحظ أن استخدام السلاسل النصية ذوات علامات التنصيص المزدوجة أو المفردة ليس لها تأثير على الأداء، لكن استكمال السلاسل النصية string interpolation ليس مدعومًا إلا في السلاسل ذوات علامات التنصيص المزدوجة. | ||
=== العمليات الرياضية === | === العمليات الرياضية === | ||
يسمح لك Twig بإجراء العمليات الرياضية في القوالب، ويدعم العوامل التالية: | يسمح لك Twig بإجراء العمليات الرياضية في القوالب، ويدعم العوامل التالية: | ||
* <code>+</code>: يضيف عددًا إلى آخر وتُرسل المعامَلات | * <code>+</code>: يضيف عددًا إلى آخر وتُرسل المعامَلات operands إلى الأرقام، مثال: ناتج <code><nowiki>{{</nowiki> <nowiki>1 + 1 }}</nowiki></code> مثلًا يساوي 2. | ||
* <code>-</code>: يطرح العدد الثاني من الأول، مثال: ناتج<code><nowiki>{{ 3 - 2 }}</nowiki></code> يساوي 1. | * <code>-</code>: يطرح العدد الثاني من الأول، مثال: ناتج<code><nowiki>{{ 3 - 2 }}</nowiki></code> يساوي 1. | ||
* <code>/</code>: يقسم عددًا على آخر، والقيمة المعادة ستكون عددًا عشريًا، مثال: ناتج <code><nowiki>{{ 1 / 2 }}</nowiki></code> هو <code><nowiki>{{ 0.5 }}</nowiki></code>. | * <code>/</code>: يقسم عددًا على آخر، والقيمة المعادة ستكون عددًا عشريًا، مثال: ناتج <code><nowiki>{{ 1 / 2 }}</nowiki></code> هو <code><nowiki>{{ 0.5 }}</nowiki></code>. | ||
* <code>%</code>: يحسب باقي قسمة عددين صحيحين، مثال: ناتج <code><nowiki>{{ 11 % 7 }}</nowiki></code> هو 4. | * <code>%</code>: يحسب باقي قسمة عددين صحيحين، مثال: ناتج <code><nowiki>{{ 11 % 7 }}</nowiki></code> هو 4. | ||
* <code>//</code>: يقسم عددين ويعيد أكبر عدد صحيح في ناتج القسمة، فإما يكون أصغر من أو يساوي ناتج القسمة. مثال: ناتج <code><nowiki>{{ 20 // 7 }}</nowiki></code> هو 2، و <code><nowiki>{{ -20 // 7 }}</nowiki></code> هو | * <code>//</code>: يقسم عددين ويعيد أكبر عدد صحيح في ناتج القسمة، فإما يكون أصغر من أو يساوي ناتج القسمة. مثال: ناتج <code><nowiki>{{ 20 // 7 }}</nowiki></code> هو 2، و <code><nowiki>{{ -20 // 7 }}</nowiki></code> هو -3 ، وهذا لمجرد تبسيط لمرشح [[Twig/round|<code>round</code>]]. | ||
* <code>*</code>: يضرب المعامَل الأيسر بالمعامَل الأيمن. مثال: ناتج <code><nowiki>{{ 2 * 2 }}</nowiki></code> هو 4. | * <code>*</code>: يضرب المعامَل الأيسر بالمعامَل الأيمن. مثال: ناتج <code><nowiki>{{ 2 * 2 }}</nowiki></code> هو 4. | ||
* <code>**</code>: يرفع المعامَل الأيسر إلى أس المعامَل الأيمن. مثال: ناتج <code><nowiki>{{ 2 ** 3 }}</nowiki></code> هو 8. | * <code>**</code>: يرفع المعامَل الأيسر إلى أس المعامَل الأيمن. مثال: ناتج <code><nowiki>{{ 2 ** 3 }}</nowiki></code> هو 8. | ||
سطر 342: | سطر 341: | ||
تستطيع جمع عدة تعابير باستخدام المعامَلات التالية: | تستطيع جمع عدة تعابير باستخدام المعامَلات التالية: | ||
* <code>and</code>: تعيد <code>true</code> إذا تحقق كلا المعامَلين الأيمن والأيسر، أي إذا كانا <code>true</code> كليهما. | * <code>and</code>: تعيد <code>true</code> إذا تحقق كلا المعامَلين operands الأيمن والأيسر، أي إذا كانا <code>true</code> كليهما. | ||
* <code>or</code>: تعيد <code>true</code> إذا تحقق أحد المعامَلين، إما الأيمن أو الأيسر. | * <code>or</code>: تعيد <code>true</code> إذا تحقق أحد المعامَلين، إما الأيمن أو الأيسر. | ||
* <code>not</code>: تنفي التعليمة. | * <code>not</code>: تنفي التعليمة. | ||
* <code>(expr)</code>: تجمع تعبيرًا. | * <code>(expr)</code>: تجمع تعبيرًا. | ||
لاحظ أن Twig يدعم العوامل الثنائية | لاحظ أن Twig يدعم العوامل الثنائية bitwise operators التي هي <code>b-and</code> و <code>b-xor</code> و <code>b-or</code>. كذلك فإن العوامل حساسة لحالة الأحرف. | ||
=== الموازنات | === الموازنات Comparisons === | ||
عوامل الموازنة التالية مدعومة في أي تعبير: | عوامل الموازنة التالية مدعومة في أي تعبير: | ||
* <code>==</code> | * <code>==</code> | ||
* <code>!=</code> | * <code>!=</code> | ||
* | * <code>>=</code> | ||
* <code><</code> | * <code><</code> | ||
* <code>></code> | * <code>></code> | ||
* <code><=</code> | * <code><=</code> | ||
سطر 365: | سطر 364: | ||
{% if 'Fabien' ends with 'n' %} | {% if 'Fabien' ends with 'n' %} | ||
{% endif %} | {% endif %} | ||
</syntaxhighlight>يسمح لك عامل <code>matches</code> باستخدام [https://academy.hsoub.com/devops/linux/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D9%81%D9%8A-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D8%A8%D9%8A%D8%B1-%D8%A7%D9%84%D9%86%D9%85%D8%B7%D9%8A%D8%A9-regular-expressions-r63/ التعابير النمطية | </syntaxhighlight>يسمح لك عامل <code>matches</code> باستخدام [https://academy.hsoub.com/devops/linux/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D9%81%D9%8A-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D8%A8%D9%8A%D8%B1-%D8%A7%D9%84%D9%86%D9%85%D8%B7%D9%8A%D8%A9-regular-expressions-r63/ التعابير النمطية regular expressions] لموازنات السلاسل النصية المعقدة. <syntaxhighlight lang="twig"> | ||
{% if phone matches '/^[\\d\\.]+$/' %} | {% if phone matches '/^[\\d\\.]+$/' %} | ||
{% endif %} | {% endif %} | ||
سطر 371: | سطر 370: | ||
=== عامل الاحتواء === | === عامل الاحتواء === | ||
ينفذ عامل <code>in</code> اختبار احتواء ويعيد true إذا تم احتواء المعامَل الأيسر داخل الأيمن.<syntaxhighlight lang="twig"> | ينفذ عامل <code>in</code> اختبار احتواء ويعيد <code>true</code> إذا تم احتواء المعامَل الأيسر داخل الأيمن.<syntaxhighlight lang="twig"> | ||
{# returns true #} | {# returns true #} | ||
سطر 377: | سطر 376: | ||
{{ 'cd' in 'abcde' }} | {{ 'cd' in 'abcde' }} | ||
</syntaxhighlight>تستطيع استخدام هذا | </syntaxhighlight>تستطيع استخدام هذا المرشح لإجراء اختبار احتواء على السلاسل النصية والمصفوفات أو الكائنات التي تستخدم واجهة <code>Traversable</code>. ولإجراء اختبار سلبي، استخدم عامل <code>not in</code>:<syntaxhighlight lang="twig"> | ||
{% if 1 not in [1, 2, 3] %} | {% if 1 not in [1, 2, 3] %} | ||
سطر 397: | سطر 396: | ||
{# يكافئ #} | {# يكافئ #} | ||
{% if not (post.status is constant('Post::PUBLISHED')) %} | {% if not (post.status is constant('Post::PUBLISHED')) %} | ||
</syntaxhighlight>اذهب إلى صفحة [[Twig/tests | </syntaxhighlight>اذهب إلى صفحة [[Twig/tests|الاختبارات]] للمزيد عن الاختبارات التي يوفرها Twig. | ||
=== العوامل الأخرى === | === العوامل الأخرى === | ||
العوامل التالية لا تقع تحت أي تصنيف مما سبق: | العوامل التالية لا تقع تحت أي تصنيف مما سبق: | ||
* <code>|</code>: تطبق | * <code>|</code>: تطبق مرشحًا. | ||
* <code>..</code>: تنشئ تسلسلًا بناءً على المعامَل السابق وبعد العامِل، وهو النسخة البسيطة من دالة [[Twig/range|range]]: | * <code>..</code>: تنشئ تسلسلًا بناءً على المعامَل السابق وبعد العامِل، وهو النسخة البسيطة من دالة [[Twig/range|<code>range</code>]]: | ||
<syntaxhighlight lang="twig"> | <syntaxhighlight lang="twig"> | ||
{{ 1..5 }} | {{ 1..5 }} | ||
سطر 409: | سطر 408: | ||
{# يكافئ #} | {# يكافئ #} | ||
{{ range(1, 5) }} | {{ range(1, 5) }} | ||
</syntaxhighlight>لاحظ أنك يجب أن تستخدم الأقواس عند جمعها مع عامل | </syntaxhighlight>لاحظ أنك يجب أن تستخدم الأقواس عند جمعها مع عامل المرشح بسبب قواعد أسبقية العوامل:<syntaxhighlight lang="twig"> | ||
(1..5)|join(', ') | (1..5)|join(', ') | ||
سطر 415: | سطر 414: | ||
* <code>~</code>: تحول جميع المعامَلات إلى سلاسل نصية وتوصلها ببعضها. مثال: <code><nowiki>{{ "Hello " ~ name ~ "!" }}</nowiki></code> سيعيد <code>Hello Osama!</code> على افتراض أن الاسم هو <code>Osama</code>. | * <code>~</code>: تحول جميع المعامَلات إلى سلاسل نصية وتوصلها ببعضها. مثال: <code><nowiki>{{ "Hello " ~ name ~ "!" }}</nowiki></code> سيعيد <code>Hello Osama!</code> على افتراض أن الاسم هو <code>Osama</code>. | ||
* <code>.</code>، <code>[]</code>: تجلب سمة المتغير | * <code>.</code>، <code>[]</code>: تجلب سمة المتغير variable's attribute . | ||
* <code>?:</code>: العامل الثلاثي: | * <code>?:</code>: العامل الثلاثي: | ||
سطر 424: | سطر 423: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
* <code>??</code>: عامل | * <code>??</code>: عامل الأمان من المتغيرات غير المعرفة null-coalescing: | ||
<syntaxhighlight lang="twig"> | <syntaxhighlight lang="twig"> | ||
{# إذا كانت غير ذلك no إذا كانت معرفة، ويعيد foo يعيد قيمة #} | {# إذا كانت غير ذلك no إذا كانت معرفة، ويعيد foo يعيد قيمة #} | ||
سطر 431: | سطر 430: | ||
=== إقحام السلاسل النصية === | === إقحام السلاسل النصية === | ||
إقحام السلاسل النصية | إقحام السلاسل النصية string interpolation -انظر <code>#{expression}</code>- يسمح بظهور أي تعبير صالح داخل سلسلة نصية ذات علامات تنصيص مزدوجة، ونتيجة التقييم أن التعبير يُدخل في السلسلة: <syntaxhighlight lang="twig"> | ||
{{ "foo #{bar} baz" }} | {{ "foo #{bar} baz" }} | ||
{{ "foo #{1 + 2} baz" }} | {{ "foo #{1 + 2} baz" }} | ||
سطر 437: | سطر 436: | ||
== التحكم في المسافات الفارغة == | == التحكم في المسافات الفارغة == | ||
يزال أول سطر جديد بعد وسم القالب تلقائيًا -كما في PHP-، ولا يعدِّل محرك القالب على المسافة الفارغة بعد ذلك، وعليه تعاد كل مسافة فارغة بعد ذلك من غير تعديل، سواء كانت مسافة عادية أو مسافة | يزال أول سطر جديد بعد وسم القالب تلقائيًا -كما في PHP-، ولا يعدِّل محرك القالب على المسافة الفارغة بعد ذلك، وعليه تعاد كل مسافة فارغة بعد ذلك من غير تعديل، سواء كانت مسافة عادية أو مسافة جدولة tab أو سطرًا جديدًا أو غير ذلك. | ||
كما تستطيع التحكم في المسافات الفارغة على مستوى كل وسم باستخدام معدٍّلات التحكم في المسافات الفارغة على وسومك، فتقلِّم المسافات البادئة واللاحقة. ويدعم Twig نوعين من المعدِّلات: | كما تستطيع التحكم في المسافات الفارغة على مستوى كل وسم باستخدام معدٍّلات التحكم في المسافات الفارغة على وسومك، فتقلِّم المسافات البادئة واللاحقة. ويدعم Twig نوعين من المعدِّلات: | ||
سطر 463: | سطر 462: | ||
{{~ value }} </li> | {{~ value }} </li> | ||
{# يخرج '<li>\nno spaces </li>' #} | {# يخرج '<li>\nno spaces </li>' #} | ||
</syntaxhighlight>كذلك فإن Twig به | </syntaxhighlight>كذلك فإن Twig به مرشح <code>[[Twig/spaceless|spaceless]]</code> الذي يزيل المسافة الفارغة بين وسوم HTML:<syntaxhighlight lang="twig"> | ||
{% apply spaceless %} | {% apply spaceless %} | ||
<div> | <div> | ||
سطر 478: | سطر 477: | ||
== انظر أيضًا == | == انظر أيضًا == | ||
* [[Twig/intro|مقدمة عن Twig]] | * [[Twig/intro|مقدمة عن Twig]] | ||
* [[Twig/internals|المكونات الداخلية لمحرك القوالب Twig]] | |||
* [[Twig/coding standards|معايير كتابة الشيفرة في Twig]] | |||
== مصادر == | == مصادر == | ||
* [https://twig.symfony.com/doc/3.x/templates.html توثيق | * [https://twig.symfony.com/doc/3.x/templates.html صفحة Twig for Template Designers من توثيق Twig الرسمي]. | ||
[[تصنيف:Twig]] | [[تصنيف:Twig]] | ||
[[تصنيف: | [[تصنيف:Twig Intro]] | ||
المراجعة الحالية بتاريخ 10:55، 7 أكتوبر 2022
تشرح هذه الصفحةُ البنيةَ اللغوية لمحرك القوالب ودلالياته symantics وسيكون ذا نفع عظيم كمرجع لأولئك الذين ينشئون قوالب Twig.
مقدمة
القالب هو ملف نصي عادي يستطيع أن يولّد أي صيغة نصية مثل HTML - XML - CSV - LaTex أو غيرها، وليس له امتداد محدد خاص به، فيصلح له امتداد html أو xml مثلًا.
ويحتوي القالب على متغيرات variables أو تعابير expressions، تُستبدَل القيم بها عند تقييم القالب، ووسوم tags تتحكم في منطق القالب. وفيما يلي قالب بسيط يوضح بعض الأساسيات، وسننظر في باقي التفاصيل لاحقًا.
<!DOCTYPE html>
<html>
<head>
<title>My Webpage</title>
</head>
<body>
<ul id="navigation">
{% for item in navigation %}
<li><a href="{{ item.href }}">{{ item.caption }}</a></li>
{% endfor %}
</ul>
<h1>My Webpage</h1>
{{ a_variable }}
</body>
</html>
لدينا نوعان من المحدِّدات delimiters هما {% ... %}
و {{ ... }}
، يُستخدم الأول لتنفيذ تعليمات مثل حلقات for التكرارية، أما الآخر فيخرج نتيجة تعبير ما.
تكامل بيئات التطوير IDE
تدعم بيئات تطوير عديدة تمييز التراكيب اللغوية syntax highlighting لمحرك Twig والإكمال التلقائي، منها على سبيل المثال:
- Textmate الموجود في حزمة Twig.
- Vim من إضافة Jinga Syntax أو إضافة vim-twig.
- Netbeans من إضافة Twig syntax (ذلك حتى الإصدار 7.1، ثم صار مضمنًا منذ الإصدار 7.2).
- PhpStorm (صار مضمنًا منذ الإصدار 2.1).
- Eclipse من إضافة Twig.
- Sublime من حزمة Twig.
- GtkSourceView من التعريف اللغوي لـ Twig، الذي يستخدمه gedit ومشاريع أخرى.
- Coda و SubEthaEdit من وضع Twig syntax.
- Coda2 من وضع Twig syntax آخر.
- Komodo و Komodo Edit من وضع Twig للتحقق من البنى اللغوية وتمييزها.
- Notepad++ من مميِّز (Notepad++) لـ Twig.
- Emacs من web-mode.el.
- Atom من PHP-twig for atom.
- Visual Studio Code من Twig pack.
كذلك فإن TwigFiddle هي خدمة ويب (أونلاين) تسمح لك بتنفيذ قوالب Twig من المتصفح، وتدعم جميع إصداراته.
المتغيرات
يمرِّر التطبيق المتغيرات إلى القوالب من أجل التعديل داخل القالب، وقد تحتوي المتغيرات على سمات attributes أو عناصر تستطيع الوصول إليها، ويعتمد التمثيل البصري للمتغير على التطبيق الذي يوفره.
استخدم النقطة .
للوصول إلى سمات متغير ما سواء كانت توابع أو خصائص لكائن PHP أو عناصر من مصفوفة PHP.
{{ foo.bar }}
من المهم أن تعرف أن الأقواس المعقوصة ليست جزءًا من المتغير نفسه لكن من تعليمة الطباعة، وحين تريد الوصول إلى متغير داخل وسم ما فلا تضع أقواسًا حوله.
بداعي التبسيط، ينفذ foo.bar
من المثال السابق ما يلي في طبقة PHP:
- يتحقق إن كان
foo
مصفوفة وما إذا كانbar
عنصرًا صالحًا. - فإن لم يكونا كذلك وكان
foo
كائنًا فيتحقق إن كانbar
خاصية صالحة. - فإن لم تكن وكان
foo
كائنًا فيتحقق إن كانbar
تابعٌ صالح، حتى لو كانbar
هو المنشئ constructor فعندئذ استخدمconstructor()_
. - فإن لم يكن وكان
foo
كائنًا فيتحقق أنhasBar
تابع صالح. - فإن لم يكن فيعيد
null
.
كذلك فإن Twig يدعم بُنية لغوية محددة للوصول إلى العناصر التي تكون في مصفوفات PHP، وهي foo['bar']
:
- تحقق إذا كان
foo
مصفوفة وbar
عنصرًا صالحًا، فإن لم يكن فأعدnull
.
إذا كان المتغير أو السمة غير موجودان فستحصل على null
حين يكون خيار strict_variables
على false
، أما إذا تم ضبط strict_variables
على القيمة true
فإن Twig سيرفع خطأ (انظر خيارات البيئة في صفحة واجهة برمجة التطبيقات).
لاحظ أنك إذا أردت أن تصل إلى سمة ديناميكية لمتغير ما، فإن عليك استخدام دالة attribute
، وهي مفيدة حين تحتوي السمة على محارف خاصة مثل -
التي ستُفسَّر على أنها عامل السالب.
{# equivalent to the non-working foo.data-foo #}
{{ attribute(foo, 'data-foo') }}
المتغيرات العامة Global Variables
المتغيرات التالية تكون متاحة دائمًا في القوالب:
_self
: يشير إلى اسم القالب الحالي._context
: يشير إلى السياق الحالي._charset
: يشير إلى مجموعة المحارف charset.
ضبط المتغيرات Setting Variables
تستطيع تعيين القيم إلى المتغيرات التي داخل كتل الشيفرات، وتستخدم التعيينات وسم set
:
{% set foo = 'foo' %}
{% set foo = [1, 2] %}
{% set foo = {'foo': 'bar'} %}
المرشحات Filters
يمكن التعديل على المتغيرات باستخدام المرشحات أو الفلاتر، ويفصل بينها وبين المتغيرات برمز الأنبوب |
، ويمكن ربط عدة مرشحات معًا في تسلسل واحد، وحينئذ يُطبق خرج أحد تلك المرشحات على المرشح الذي يليه. انظر المثال التالي الذي يحذف جميع وسوم HTML من name
ويجعلها على نسق العنوان:
{{ name|striptags|title }}
ويكون للمرشحات التي تقبل الوسائط أقواسًا حول الوسائط. المثال التالي يربط بين عناصر قائمة باستخدام فاصلة إنجليزية ,
:
{{ list|join(', ') }}
إذا أردت تطبيق مرشح على جزء من الشيفرة فغلِّفه بوسم apply
:
{% apply upper %}
This text becomes uppercase
{% endapply %}
انتقل إلى صفحة المرشحات للتعرف على المرشحات التي يوفرها Twig.
الدوال
يمكن استدعاء الدوال لتوليد المحتوى، وتُستدعى باسمها متبوعًا بقوسين ()
وقد تحتوي على وسائط. فمثلًا، تعيد دالة range
قائمة تحتوي على التقدم الحسابي لأرقام:
{% for i in range(0, 3) %}
{{ i }},
{% endfor %}
الوسائط المسماة Named Arguments
{% for i in range(low=1, high=10, step=2) %}
{{ i }},
{% endfor %}
استخدام الوسائط المسماة named arguments يجعل قوالبك أكثر وضوحًا حول معنى القيم التي تمررها كوسائط:
{{ data|convert_encoding('UTF-8', 'iso-2022-jp') }}
{# versus #}
{{ data|convert_encoding(from='iso-2022-jp', to='UTF-8') }}
كما تسمح لك الوسائط المسماة أن تتجاوز بعض الوسائط التي لا تريد تغيير قيمتها الافتراضية:
{# null الوسيط الأول هو صيغة التاريخ التي تكون على الصيغة العالمية للتاريخ إذا تم تمرير #}
{{ "now"|date(null, "Europe/Paris") }}
{# أو تخطى قيمة الصيغة باستخدام وسيط مسمى للمنطقة الزمنية #}
{{ "now"|date(timezone="Europe/Paris") }}
وتستطيع استخدام الوسائط المسماة والموضعية positional في استدعاء واحد، لكن يجب أن تكون الوسائط الموضعية في ذلك الاستدعاء قبل الوسائط المسماة:
{{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }}
تذكير: تسرد كل صفحة من صفحات المرشحات والدوال في هذا التوثيق جميع الوسائط المدعومة.
هيكل التحكم
تشير هياكل التحكم إلى الأشياء التي تتحكم في تدفق البرنامج وسيره، مثل التعليمات الشرطية if/elseif/else
وحلقات for
التكرارية، إضافة إلى الكتل مثلًا blocks، وتكون هياكل التحكم داخل كتل {% ... %}
.
فمثلًا، استخدم وسم for
من أجل عرض قائمة من المستخدمين الموجودين في متغير اسمه users
:
<h1>Members</h1>
<ul>
{% for user in users %}
<li>{{ user.username|e }}</li>
{% endfor %}
</ul>
يمكن استخدام وسم if
لاختبار تعبير ما:
{% if users|length > 0 %}
<ul>
{% for user in users %}
<li>{{ user.username|e }}</li>
{% endfor %}
</ul>
{% endif %}
اذهب إلى صفحة الوسوم للمزيد عن الوسوم التي يوفرها Twig.
التعليقات
إذا أردت تحويل جزء من سطر في قالب إلى تعليق فاستخدم {# ...#}
، وهذا مفيد في التنقيح (debugging لاحقًا أو إضافة معلومات لمصممي القوالب الآخرين أو لنفسك:
{# note: disabled template because we no longer use this
{% for user in users %}
...
{% endfor %}
#}
إدراج قوالب أخرى
تُستخدم دالة include
لإدراج قالب ما، وتعيد المحتوى الذي يخرجه ذلك القالب إلى القالب الحالي:
{{ include('sidebar.html') }}
ويجب أن يكون للقوالب المُدرَجة وصولًا إلى نفس سياق القالب الذي يحتويها، وهذا يعني أن أي متغير مُعرّف في القالب الرئيسي سيكون متاحًا في القالب المدرَج أيضًا:
{% for box in boxes %}
{{ include('render_box.html') }}
{% endfor %}
القالب المدرَج render_box.html
له وصول إلى متغير box
، ويعتمد اسم القالب على محمِّله -أي محمل القالب-، فمثلًا، يسمح \Twig\Loader\FilesystemLoader
لك أن تصل إلى قوالب أخرى من خلال اسم الملف، فتستطيع الوصول إلى القوالب في الأدلة الفرعية باستخدام شرطة مائلة:
{{ include('sections/articles/sidebar.html') }}
لكن هذا السلوك يعتمد على التطبيق الذي يحتوي Twig.
وراثة القوالب
إن أقوى مزية في Twig هي وراثة القوالب template inheritance ، وهي تسمح لك ببناء قالب هيكلي أساسي يحتوي على جميع العناصر المشتركة في موقعك، ويعرِّف الوحدات والكتل blocks التي تستطيع القوالب الأبناء child templates أن ترثه وتعدل عليه وتستبدله، وسننظر في مثال الآن للتوضيح.
لنعرِّف قالبًا أساسيًا وليكن base.html
، الذي يعرِّف مستند HTML هيكلي يمكن استخدامه لصفحة من عمودين:
<!DOCTYPE html>
<html>
<head>
{% block head %}
<link rel="stylesheet" href="style.css"/>
<title>{% block title %}{% endblock %} - My Webpage</title>
{% endblock %}
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %}
© Copyright 2011 by <a href="http://domain.invalid/">you</a>.
{% endblock %}
</div>
</body>
</html>
في هذا المثال فإن وسوم block
تعرِّف الوحدات الأربع التي تستطيع القوالب الأبناء أن تملأها، وما يفعله وسم block
هو إخبار محرك القالب أن قالبًا ابنًا قد يستبدل هذه الأجزاء من القالب، والقالب الابن قد يكون شبيهًا بما يلي:
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{{ parent() }}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}
<h1>Index</h1>
<p class="important">
Welcome to my awesome homepage.
</p>
{% endblock %}
الوسم extends
هو الفيصل هنا إذ يخبر محركَ القالب أن هذا القالب يوسِّع قالبًا آخر ويرث منه، وحين يقيم نظام القالب هذا القالب فإنه يبحث عن القالب الأب أولًا، إذ يجب أن يكون وسم extends
هو أول وسم في القالب. وبما أن القالب الابن لا يعرِّف كتلة footer
فإن القيمة التي من القالب الأب هي التي تُستخدم.
من الممكن أن تُخرِج محتويات الكتلة الأب من خلال استخدام دالة parent
، انظر:
{% block sidebar %}
<h3>Table Of Contents</h3>
...
{{ parent() }}
{% endblock %}
ستجد أن توثيق وسم extends
يصف خصائص أكثر تقدمًا مثل تشعب الكتل والنطاق والوراثة الديناميكية والوراثة الشرطية. كذلك، لاحظ أن Twig يدعم الوراثة المتعددة من خلال إعادة الاستخدام الأفقية horizontal reuse بمساعدة وسم use
.
تهريب HTML
حين نولد HTML من القوالب فإننا نخاطر باحتمال أن يحتوي متغير على محارف تؤثر على شيفرة HTML الناتجة، وهناك حلان لهذه المشكلة: إما بتهريب escape كل متغير يدويًا أو تهريب كل شيء افتراضيًا.
وإن Twig يدعم كلا الحلين، بل إن التهريب الآلي مفعَّل افتراضيًا، ويمكن تعديل استراتيجية التهريب الآلي من خلال خيار autoscape
، ويكون الافتراضي على html
.
التعامل مع التهريب اليدوي
إذا كان التهريب اليدوي مفعلًا فسيكون تهريب المتغيرات مسؤوليتك أنت إذا احتجت إلى ذلك، وتهرب أي متغير يأتي من مصدر غير موثوق فيه. ونستخدم مرشح escape
أو e
اختصارًا:
{{ user.username|e }}
يستخدم مرشح escape
استراتيجية html
افتراضيًا، لكن قد تريد استخدام استراتيجية أخرى استخدامًا صريحًا، وذلك وفقًا لسياق التهريب:
{{ user.username|e('js') }}
{{ user.username|e('css') }}
{{ user.username|e('url') }}
{{ user.username|e('html_attr') }}
التعامل مع التهريب الآلي
تستطيع تحديد جزء من قالب ما ليتم تهريبه آليًا سواء كان التهريب الآلي مفعلًا أم لا، وذلك باستخدام وسم autoscape
:
{% autoescape %}
HTML سيهرّب كل شيء في هذه الكتلة باستخدام استراتيجية
{% endautoescape %}
يستخدم التهريب الآلي خطة تهريب html
افتراضيًا، أما إذا كنت تُخرِج متغيرات في سياقات أخرى فستحتاج إلى أن تهربها صراحة بخطة التهريب المناسبة:
{% autoescape 'js' %}
JS سيُهرَّب كل شيء آليًا في هذه الكتلة باستخدام خطة
{% endautoescape %}
التهريب
قد ترغب أحيانًا -أو تضطر- إلى أن تجعل Twig يتجاهل أجزاءً كان يمكن أن تعالَج على أنها متغيرات أو كتل، فمثلًا إذا استُخدمت البنية الافتراضية وتريد استخدام }}
كسلسلة نصية خام في القالب من غير أن تبدأ متغيرًا جديدًا، فيجب أن تحتال على السلوك الافتراضي، وأسهل طريقة لذلك هي بإخراج }}
المفسرة على أنها محدِّد المتغير variable delimiter من خلال استخدام تعبير متغير:
{{ '{{' }}
وبالنسبة للأقسام والكتل الأكبر فمن المنطق أن تحدد الكتلة بوسم verbatim
.
التعليمات الجامعة Macros
يمكن موازنة التعليمات الجامعة أو الماكرو مع الدوال في لغات البرمجة العادية، وهي مفيدة في إعادة استخدام أجزاء شيفرات HTML لئلا نكرر كتابتها في كل مرة، وستجد شرحها في توثيق وسم macro
.
التعبيرات
يسمح Twig بالتعابير في أي مكان تقريبًا. لاحظ أن أسبقية العوامل operators تكون كما يلي، مع وضع العوامل الأقل أسبقية في البداية:
-
?:
b-and
b-xor
b-or
or
and
==
-
!=
<=>
-
<
-
>
-
>=
<=
in
matches
starts with
ends with
..
+
-
~
*
/
//
%
is
**
??
|
[]
.
{% set greeting = 'Hello ' %}
{% set name = 'Fabien' %}
{{ greeting ~ name|lower }} {# Hello fabien #}
{# استخدم الأقواس لتغيير الأولوية #}
{{ (greeting ~ name)|lower }} {# hello fabien #}
القيم مصنفة النوع Literals
إن أبسط صورة للتعابير هي القيم مصنفة النوع، وهي تمثيل لأنواع بيانات PHP مثل السلاسل النصية والأرقام والمصفوفات، فلدينا القيم التالية مثلًا:
"Hello World"
: أي شيء بين علامتي تنصيص مفردتين أو مزدوجتين فإنه سلسلة نصية، وهذه السلاسل مفيدة إذا أردت إضافة سلسلة نصية في القالب كوسيط في استدعاء دالة مثلًا أو مرشح أو حتى لتوسيع القالب أو إدراجه. وقد تحتوي السلسلة النصية على محدِّد إذا سُبقت بشرطة مائلة خلفية\
كما في'It\'s good'
، أما إذا احتوت السلسلة النصية على شرطة مائلة خلفية كما في'c:\Program Files'
فهرِّبها بتكرارها'c:\\Program Files'
.42
/42.23
: تُنشأ الأرقام الصحيحة integers والأرقام العشرية بكتابة الرقم فقط، فإذا وجدت نقطة.
في الرقم فإنه يكون عشريًا.["foo", "bar"]
: تُعرَّف المصفوفات بسلسلة من التعابير مفصولة بفاصلة إنجليزية,
وتُغلَّف بأقواس مربعة[]
.{"foo": "bar"}
: تُعرَّف الجداول بقائمة من المفاتيح والقيم المفصول بينها بفاصلة إنجليزية وتُغلَّف بأقواس معقوصة{}
.
{# المفاتيح كسلسلة نصية #}
{ 'foo': 'foo', 'bar': 'bar' }
{# المفاتيح كأسماء مكافئة للجدول السابق #}
{ foo: 'foo', bar: 'bar' }
{# المفاتيح كأرقام #}
{ 2: 'foo', 4: 'bar' }
{# يمكن إهمال المفاتيح إذا طابقت اسم المتغير #}
{ foo }
{# مطابق لما يلي #}
{ 'foo': foo }
{# المفاتيح كتعابير، يجب أن يُغلَّف التعبير بأقواس #}
{% set foo = 'foo' %}
{ (foo): 'foo', (1 + 1): 'bar', (foo ~ 'b'): 'baz' }
true
/false
: تمثلtrue
القيمة المتحققة أو الصحيحة، أماfalse
فتمثل القيمة الخاطئة أو غير المتحققة.null
: لا تمثلnull
قيمة بعينها، وتعاد إذا كان المتغير غير موجودًا، وتُستخدمnone
كاسم بديل alias للقيمة غير المعرفةnull
.
كذلك، من الممكن أن تتشعب المصفوفات والجداول:
{% set foo = [1, {"foo": "bar"}] %}
لاحظ أن استخدام السلاسل النصية ذوات علامات التنصيص المزدوجة أو المفردة ليس لها تأثير على الأداء، لكن استكمال السلاسل النصية string interpolation ليس مدعومًا إلا في السلاسل ذوات علامات التنصيص المزدوجة.
العمليات الرياضية
يسمح لك Twig بإجراء العمليات الرياضية في القوالب، ويدعم العوامل التالية:
+
: يضيف عددًا إلى آخر وتُرسل المعامَلات operands إلى الأرقام، مثال: ناتج{{ 1 + 1 }}
مثلًا يساوي 2.-
: يطرح العدد الثاني من الأول، مثال: ناتج{{ 3 - 2 }}
يساوي 1./
: يقسم عددًا على آخر، والقيمة المعادة ستكون عددًا عشريًا، مثال: ناتج {{ 1 / 2 }}
هو{{ 0.5 }}
.%
: يحسب باقي قسمة عددين صحيحين، مثال: ناتج {{ 11 % 7 }}
هو 4.//
: يقسم عددين ويعيد أكبر عدد صحيح في ناتج القسمة، فإما يكون أصغر من أو يساوي ناتج القسمة. مثال: ناتج{{ 20 // 7 }}
هو 2، و {{ -20 // 7 }}
هو -3 ، وهذا لمجرد تبسيط لمرشحround
.*
: يضرب المعامَل الأيسر بالمعامَل الأيمن. مثال: ناتج {{ 2 * 2 }}
هو 4.**
: يرفع المعامَل الأيسر إلى أس المعامَل الأيمن. مثال: ناتج {{ 2 ** 3 }}
هو 8.
العمليات المنطقية
تستطيع جمع عدة تعابير باستخدام المعامَلات التالية:
and
: تعيدtrue
إذا تحقق كلا المعامَلين operands الأيمن والأيسر، أي إذا كاناtrue
كليهما.or
: تعيدtrue
إذا تحقق أحد المعامَلين، إما الأيمن أو الأيسر.not
: تنفي التعليمة.(expr)
: تجمع تعبيرًا.
لاحظ أن Twig يدعم العوامل الثنائية bitwise operators التي هي b-and
و b-xor
و b-or
. كذلك فإن العوامل حساسة لحالة الأحرف.
الموازنات Comparisons
عوامل الموازنة التالية مدعومة في أي تعبير:
==
-
!=
-
>=
-
<
-
>
-
<=
وتستطيع التحقق إن كانت سلسلة نصية تبدأ بسلسلة أخرى starts with
أو تنتهي بواحدة ends with
:
{% if 'Fabien' starts with 'F' %}
{% endif %}
{% if 'Fabien' ends with 'n' %}
{% endif %}
يسمح لك عامل matches
باستخدام التعابير النمطية regular expressions لموازنات السلاسل النصية المعقدة.
{% if phone matches '/^[\\d\\.]+$/' %}
{% endif %}
عامل الاحتواء
ينفذ عامل in
اختبار احتواء ويعيد true
إذا تم احتواء المعامَل الأيسر داخل الأيمن.
{# returns true #}
{{ 1 in [1, 2, 3] }}
{{ 'cd' in 'abcde' }}
تستطيع استخدام هذا المرشح لإجراء اختبار احتواء على السلاسل النصية والمصفوفات أو الكائنات التي تستخدم واجهة Traversable
. ولإجراء اختبار سلبي، استخدم عامل not in
:
{% if 1 not in [1, 2, 3] %}
{# يساوي #}
{% if not (1 in [1, 2, 3]) %}
عامل الاختبار
ينفذ عامل is
اختبارات يمكن استخدامها لنختبر متغيرًا مع تعبير شائع، ويكون المعامَل الأيمن هو اسم الاختبار:
{# find out if a variable is odd #}
{{ name is odd }}
وتقبل الاختبارات الوسائط:
{% if post.status is constant('Post::PUBLISHED') %}
كما يمكن نفي الاختبار باستخدام عامل is not
:
{% if post.status is not constant('Post::PUBLISHED') %}
{# يكافئ #}
{% if not (post.status is constant('Post::PUBLISHED')) %}
اذهب إلى صفحة الاختبارات للمزيد عن الاختبارات التي يوفرها Twig.
العوامل الأخرى
العوامل التالية لا تقع تحت أي تصنيف مما سبق:
|
: تطبق مرشحًا...
: تنشئ تسلسلًا بناءً على المعامَل السابق وبعد العامِل، وهو النسخة البسيطة من دالةrange
:
{{ 1..5 }}
{# يكافئ #}
{{ range(1, 5) }}
لاحظ أنك يجب أن تستخدم الأقواس عند جمعها مع عامل المرشح بسبب قواعد أسبقية العوامل:
(1..5)|join(', ')
~
: تحول جميع المعامَلات إلى سلاسل نصية وتوصلها ببعضها. مثال: {{ "Hello " ~ name ~ "!" }}
سيعيد Hello Osama!
على افتراض أن الاسم هوOsama
..
،[]
: تجلب سمة المتغير variable's attribute .
-
?:
: العامل الثلاثي:
{{ foo ? 'yes' : 'no' }}
{{ foo ?: 'no' }} is the same as {{ foo ? foo : 'no' }}
{{ foo ? 'yes' }} is the same as {{ foo ? 'yes' : '' }}
??
: عامل الأمان من المتغيرات غير المعرفة null-coalescing:
{# إذا كانت غير ذلك no إذا كانت معرفة، ويعيد foo يعيد قيمة #}
{{ foo ?? 'no' }}
إقحام السلاسل النصية
إقحام السلاسل النصية string interpolation -انظر #{expression}
- يسمح بظهور أي تعبير صالح داخل سلسلة نصية ذات علامات تنصيص مزدوجة، ونتيجة التقييم أن التعبير يُدخل في السلسلة:
{{ "foo #{bar} baz" }}
{{ "foo #{1 + 2} baz" }}
التحكم في المسافات الفارغة
يزال أول سطر جديد بعد وسم القالب تلقائيًا -كما في PHP-، ولا يعدِّل محرك القالب على المسافة الفارغة بعد ذلك، وعليه تعاد كل مسافة فارغة بعد ذلك من غير تعديل، سواء كانت مسافة عادية أو مسافة جدولة tab أو سطرًا جديدًا أو غير ذلك.
كما تستطيع التحكم في المسافات الفارغة على مستوى كل وسم باستخدام معدٍّلات التحكم في المسافات الفارغة على وسومك، فتقلِّم المسافات البادئة واللاحقة. ويدعم Twig نوعين من المعدِّلات:
- تقليم المسافات الفارغة باستخدام المعدِّل
-
: يحذف كل المسافات الفارغة بما فيها الأسطر الجديدة. - تقليم مسافات الأسطر باستخدام المعدِّل
~
: يحذف جميع المسافات الفارغة باستثناء الأسطر الجديدة، واستخدام هذا المعدل على اليمين يعطل الإزالة الافتراضية لأول سطر جديد موروث من PHP.
يمكن استخدام المعدِّلات على أي جانب من جانبي الوسم {%-
أو -%}
، وتستهلك جميع المسافات الفارغة للجانب الذي تكون فيه، ومن الممكن استخدام المعدِّلات على جانب واحد من الوسم أو كلا الجانبين:
{% set value = 'no spaces' %}
{#- لا مسافات بادئة أو لاحقة -#}
{%- if true -%}
{{- value -}}
{%- endif -%}
{# 'no spaces' يخرج #}
<li>
{{ value }} </li>
{# يخرج '<li>\n no spaces </li>' #}
<li>
{{- value }} </li>
{# يخرج '<li>no spaces </li>' #}
<li>
{{~ value }} </li>
{# يخرج '<li>\nno spaces </li>' #}
كذلك فإن Twig به مرشح spaceless
الذي يزيل المسافة الفارغة بين وسوم HTML:
{% apply spaceless %}
<div>
<strong>foo bar</strong>
</div>
{% endapply %}
{# الخرج: <div><strong>foo bar</strong></div> #}
التوسعات
اقرأ صفحة توسيع Twig لتعلم كيف تنشئ توسعاتك الخاصة بك.