الفرق بين المراجعتين لصفحة: «Twig/templates»

من موسوعة حسوب
1.0: إضافة عنوان الصفحة.
 
طلا ملخص تعديل
 
(14 مراجعة متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة)
سطر 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>
<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>
</syntaxhighlight>لدينا نوعان من المحدِّدات delimiters  هما <code>{% ... %}</code> و <code><nowiki>{{ ... }}</nowiki></code>، يُستخدم الأول لتنفيذ تعليمات مثل حلقات for التكرارية، أما الآخر فيخرج نتيجة تعبير ما.
 
== تكامل بيئات التطوير IDE  ==
 
تدعم بيئات تطوير عديدة تمييز التراكيب اللغوية syntax highlighting  لمحرك Twig والإكمال التلقائي، منها على سبيل المثال:
 
* Textmate الموجود في [https://github.com/Anomareh/PHP-Twig.tmbundle حزمة Twig].
* Vim من إضافة [http://jinja.pocoo.org/docs/integration/#vim Jinga Syntax] أو إضافة [https://github.com/lumiliet/vim-twig vim-twig].
* Netbeans من إضافة [http://plugins.netbeans.org/plugin/37069/php-twig Twig syntax] (ذلك حتى الإصدار 7.1، ثم صار مضمنًا منذ الإصدار 7.2).
* PhpStorm (صار مضمنًا منذ الإصدار 2.1).
* Eclipse من [https://github.com/pulse00/Twig-Eclipse-Plugin إضافة Twig].
* Sublime من [https://github.com/Anomareh/PHP-Twig.tmbundle حزمة Twig].
* GtkSourceView من [https://github.com/gabrielcorpse/gedit-twig-template-language التعريف اللغوي لـ Twig]، الذي يستخدمه gedit ومشاريع أخرى.
* Coda و SubEthaEdit من [https://github.com/bobthecow/Twig-HTML.mode وضع Twig syntax].
* Coda2 من [https://github.com/muxx/Twig-HTML.mode وضع Twig syntax] آخر.
* Komodo و Komodo Edit من وضع Twig للتحقق من البنى اللغوية وتمييزها.
* Notepad++‎  من [https://github.com/Banane9/notepadplusplus-twig مميِّز (Notepad++‎) لـ Twig].
* Emacs من [http://web-mode.org web-mode.el].
* 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].
 
كذلك فإن [https://twigfiddle.com TwigFiddle] هي خدمة ويب (أونلاين) تسمح لك بتنفيذ قوالب Twig من المتصفح، وتدعم جميع إصداراته.
 
== المتغيرات ==
يمرِّر التطبيق المتغيرات إلى القوالب من أجل التعديل داخل القالب، وقد تحتوي المتغيرات على سمات attributes  أو عناصر تستطيع الوصول إليها، ويعتمد التمثيل البصري للمتغير على التطبيق الذي يوفره.
 
استخدم النقطة <code>.</code> للوصول إلى سمات متغير ما سواء كانت توابع أو خصائص لكائن PHP أو عناصر من مصفوفة [[PHP]].<syntaxhighlight lang="twig">
{{ foo.bar }}
</syntaxhighlight>من المهم أن تعرف أن الأقواس المعقوصة ليست جزءًا من المتغير نفسه لكن من تعليمة الطباعة، وحين تريد الوصول إلى متغير داخل وسم ما فلا تضع أقواسًا حوله.
 
بداعي التبسيط، ينفذ <code>foo.bar</code> من المثال السابق ما يلي في طبقة PHP:
 
* يتحقق إن كان <code>foo</code> مصفوفة وما إذا كان <code>bar</code> عنصرًا صالحًا.
* فإن لم يكونا كذلك وكان <code>foo</code> كائنًا فيتحقق إن كان <code>bar</code> خاصية صالحة.
* فإن لم تكن وكان <code>foo</code> كائنًا فيتحقق إن كان <code>bar</code> تابعٌ صالح، حتى لو كان <code>bar</code> هو المنشئ constructor  فعندئذ استخدم <code>constructor()‎_</code>.
* فإن لم يكن وكان <code>foo</code> كائنًا فيتحقق أن <code>hasBar</code> تابع صالح.
* فإن لم يكن فيعيد <code>null</code>.
 
كذلك فإن Twig يدعم بُنية لغوية محددة للوصول إلى العناصر التي تكون في مصفوفات PHP، وهي <code>foo['bar']‎</code>:
 
* تحقق إذا كان <code>foo</code> مصفوفة و<code>bar</code> عنصرًا صالحًا، فإن لم يكن فأعد <code>null</code>.
 
إذا كان المتغير أو السمة غير موجودان فستحصل على <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 #}
{{ attribute(foo, 'data-foo') }}
</syntaxhighlight>
 
=== المتغيرات العامة Global Variables  ===
المتغيرات التالية تكون متاحة دائمًا في القوالب:
 
* <code>‎_self</code>: يشير إلى اسم القالب الحالي.
* <code>‎_context</code>: يشير إلى السياق الحالي.
* <code>‎_charset</code>: يشير إلى مجموعة المحارف charset.
 
=== ضبط المتغيرات Setting Variables  ===
تستطيع تعيين القيم إلى المتغيرات التي داخل كتل الشيفرات، وتستخدم التعيينات وسم <code>[[Twig/set|set]]</code>:<syntaxhighlight lang="twig">
{% set foo = 'foo' %}
 
{% set foo = [1, 2] %}
 
{% set foo = {'foo': 'bar'} %}
</syntaxhighlight>
 
== المرشحات Filters ==
يمكن التعديل على المتغيرات باستخدام المرشحات أو الفلاتر، ويفصل بينها وبين المتغيرات برمز الأنبوب <code>|</code>، ويمكن ربط عدة مرشحات معًا في تسلسل واحد، وحينئذ يُطبق خرج أحد تلك المرشحات على المرشح الذي يليه. انظر المثال التالي الذي يحذف جميع وسوم HTML من <code>name</code> ويجعلها على نسق العنوان:<syntaxhighlight lang="twig">
{{ name|striptags|title }}
</syntaxhighlight>ويكون للمرشحات التي تقبل الوسائط أقواسًا حول الوسائط. المثال التالي يربط بين عناصر قائمة باستخدام فاصلة إنجليزية <code>,</code>:<syntaxhighlight lang="twig">
{{ list|join(', ') }}
</syntaxhighlight>إذا أردت تطبيق مرشح على جزء من الشيفرة فغلِّفه بوسم <code>[[Twig/apply|apply]]</code>:<syntaxhighlight lang="twig">
{% apply upper %}
    This text becomes uppercase
{% endapply %}
</syntaxhighlight>انتقل إلى صفحة [[Twig/filters|المرشحات]] للتعرف على المرشحات التي يوفرها Twig.
 
== الدوال ==
يمكن استدعاء الدوال لتوليد المحتوى، وتُستدعى باسمها متبوعًا بقوسين <code>()</code> وقد تحتوي على وسائط. فمثلًا، تعيد دالة <code>range</code> قائمة تحتوي على التقدم الحسابي لأرقام:<syntaxhighlight lang="twig">
{% for i in range(0, 3) %}
    {{ i }},
{% endfor %}
</syntaxhighlight>
 
== الوسائط المسماة Named Arguments  ==
<syntaxhighlight lang="twig">
{% for i in range(low=1, high=10, step=2) %}
    {{ i }},
{% endfor %}
</syntaxhighlight>استخدام الوسائط المسماة named arguments  يجعل قوالبك أكثر وضوحًا حول معنى القيم التي تمررها كوسائط:<syntaxhighlight lang="twig">
{{ data|convert_encoding('UTF-8', 'iso-2022-jp') }}
 
{# versus #}
 
{{ data|convert_encoding(from='iso-2022-jp', to='UTF-8') }}
</syntaxhighlight>كما تسمح لك الوسائط المسماة أن تتجاوز بعض الوسائط التي لا تريد تغيير قيمتها الافتراضية:<syntaxhighlight lang="twig">
{# null الوسيط الأول هو صيغة التاريخ التي تكون على الصيغة العالمية للتاريخ إذا تم تمرير #}
{{ "now"|date(null, "Europe/Paris") }}
 
{# أو تخطى قيمة الصيغة باستخدام وسيط مسمى للمنطقة الزمنية #}
{{ "now"|date(timezone="Europe/Paris") }}
</syntaxhighlight>وتستطيع استخدام الوسائط المسماة والموضعية positional في استدعاء واحد، لكن يجب أن تكون الوسائط الموضعية في ذلك الاستدعاء قبل الوسائط المسماة:<syntaxhighlight lang="twig">
{{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }}
</syntaxhighlight>'''تذكير''': تسرد كل صفحة من صفحات المرشحات والدوال في هذا التوثيق جميع الوسائط المدعومة.
 
== هيكل التحكم ==
تشير هياكل التحكم إلى الأشياء التي تتحكم في تدفق البرنامج وسيره، مثل التعليمات الشرطية <code>if/elseif/else</code>  وحلقات <code>for</code> التكرارية، إضافة إلى الكتل مثلًا blocks، وتكون هياكل التحكم داخل كتل <code>{% ... %}</code> .
 
فمثلًا، استخدم وسم [[Twig/for|<code>for</code>]] من أجل عرض قائمة من المستخدمين الموجودين في متغير اسمه <code>users</code> :<syntaxhighlight lang="twig">
<h1>Members</h1>
<ul>
    {% for user in users %}
        <li>{{ user.username|e }}</li>
    {% endfor %}
</ul>
</syntaxhighlight>يمكن استخدام وسم [[Twig/if|<code>if</code>]] لاختبار تعبير ما:<syntaxhighlight lang="twig">
{% if users|length > 0 %}
    <ul>
        {% for user in users %}
            <li>{{ user.username|e }}</li>
        {% endfor %}
    </ul>
{% endif %}
</syntaxhighlight>اذهب إلى صفحة [[Twig/tags|الوسوم]] للمزيد عن الوسوم التي يوفرها Twig.
 
== التعليقات ==
إذا أردت تحويل جزء من سطر في قالب إلى تعليق فاستخدم <code>{# ...#}</code>، وهذا مفيد في التنقيح (debugging  لاحقًا أو إضافة معلومات لمصممي القوالب الآخرين أو لنفسك:<syntaxhighlight lang="twig">
{# note: disabled template because we no longer use this
    {% for user in users %}
        ...
    {% endfor %}
#}
</syntaxhighlight>
 
== إدراج قوالب أخرى ==
تُستخدم دالة <code>[[Twig/include function|include]]</code> لإدراج قالب ما، وتعيد المحتوى الذي يخرجه ذلك القالب إلى القالب الحالي:<syntaxhighlight lang="twig">
{{ include('sidebar.html') }}
 
</syntaxhighlight>ويجب أن يكون للقوالب المُدرَجة وصولًا إلى نفس سياق القالب الذي يحتويها، وهذا يعني أن أي متغير مُعرّف في القالب الرئيسي سيكون متاحًا في القالب المدرَج أيضًا:<syntaxhighlight lang="twig">
{% for box in boxes %}
    {{ include('render_box.html') }}
{% endfor %}
</syntaxhighlight>القالب المدرَج <code>render_box.html</code> له وصول إلى متغير <code>box</code> ، ويعتمد اسم القالب على محمِّله -أي محمل القالب-، فمثلًا، يسمح ‎<code>\Twig\Loader\FilesystemLoader</code> لك أن تصل إلى قوالب أخرى من خلال اسم الملف، فتستطيع الوصول إلى القوالب في الأدلة الفرعية باستخدام شرطة مائلة:<syntaxhighlight lang="twig">
{{ include('sections/articles/sidebar.html') }}
 
</syntaxhighlight>لكن هذا السلوك يعتمد على التطبيق الذي يحتوي Twig.
 
== وراثة القوالب ==
إن أقوى مزية في Twig هي وراثة القوالب template inheritance ، وهي تسمح لك ببناء قالب هيكلي أساسي يحتوي على جميع العناصر المشتركة في موقعك، ويعرِّف '''الوحدات والكتل blocks'''  التي تستطيع القوالب الأبناء child templates  أن ترثه وتعدل عليه وتستبدله، وسننظر في مثال الآن للتوضيح.
 
لنعرِّف قالبًا أساسيًا وليكن  <code>base.html</code> ، الذي يعرِّف مستند [[HTML]] هيكلي يمكن استخدامه لصفحة من عمودين:<syntaxhighlight lang="twig">
<!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 %}
                &copy; Copyright 2011 by <a href="http://domain.invalid/">you</a>.
            {% endblock %}
        </div>
    </body>
</html>
</syntaxhighlight>في هذا المثال فإن وسوم <code>[[Twig/block|block]]</code> تعرِّف الوحدات الأربع التي تستطيع القوالب الأبناء أن تملأها، وما يفعله وسم [[Twig/block|<code>block</code>]] هو إخبار محرك القالب أن قالبًا ابنًا قد يستبدل هذه الأجزاء من القالب، والقالب الابن قد يكون شبيهًا بما يلي:<syntaxhighlight lang="twig">
{% 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 %}
</syntaxhighlight>الوسم <code>[[Twig/extends|extends]]</code> هو الفيصل هنا إذ يخبر محركَ القالب أن هذا القالب يوسِّع قالبًا آخر ويرث منه، وحين يقيم نظام القالب هذا القالب فإنه يبحث عن القالب الأب أولًا، إذ يجب أن يكون وسم [[Twig/extends|<code>extends</code>]] هو أول وسم في القالب. وبما أن القالب الابن لا يعرِّف كتلة <code>footer</code> فإن القيمة التي من القالب الأب هي التي تُستخدم.
 
من الممكن أن تُخرِج محتويات الكتلة الأب من خلال استخدام دالة <code>[[Twig/parent|parent]]</code>، انظر:<syntaxhighlight lang="twig">
{% block sidebar %}
    <h3>Table Of Contents</h3>
    ...
    {{ parent() }}
{% endblock %}
</syntaxhighlight>ستجد أن توثيق وسم <code>[[Twig/extends|extends]]</code> يصف خصائص أكثر تقدمًا مثل تشعب الكتل والنطاق والوراثة الديناميكية والوراثة الشرطية. كذلك، لاحظ أن Twig يدعم الوراثة المتعددة من خلال إعادة الاستخدام الأفقية horizontal reuse  بمساعدة وسم <code>[[Twig/use|use]]</code>.
 
== تهريب HTML ==
حين نولد HTML من القوالب فإننا نخاطر باحتمال أن يحتوي متغير على محارف تؤثر على شيفرة HTML الناتجة، وهناك حلان لهذه المشكلة: إما بتهريب escape  كل متغير يدويًا أو تهريب كل شيء افتراضيًا.
 
وإن Twig يدعم كلا الحلين، بل إن التهريب الآلي مفعَّل افتراضيًا، ويمكن تعديل استراتيجية التهريب الآلي من خلال خيار [[Twig/autoescape|<code>autoscape</code>]]، ويكون الافتراضي على <code>html</code>.
 
=== التعامل مع التهريب اليدوي ===
إذا كان التهريب اليدوي مفعلًا فسيكون تهريب المتغيرات مسؤوليتك أنت إذا احتجت إلى ذلك، وتهرب أي متغير يأتي من مصدر غير موثوق فيه. ونستخدم مرشح <code>[[Twig/escape|escape]]</code> أو <code>e</code> اختصارًا:<syntaxhighlight lang="twig">
{{ user.username|e }}
 
</syntaxhighlight>يستخدم مرشح [[Twig/escape|<code>escape</code>]] استراتيجية <code>html</code> افتراضيًا، لكن قد تريد استخدام استراتيجية أخرى استخدامًا صريحًا، وذلك وفقًا لسياق التهريب:<syntaxhighlight lang="twig">
{{ user.username|e('js') }}
{{ user.username|e('css') }}
{{ user.username|e('url') }}
{{ user.username|e('html_attr') }}
</syntaxhighlight>
 
=== التعامل مع التهريب الآلي ===
تستطيع تحديد جزء من قالب ما ليتم تهريبه آليًا سواء كان التهريب الآلي مفعلًا أم لا، وذلك باستخدام وسم [[Twig/autoescape|<code>autoscape</code>]]:<syntaxhighlight lang="twig">
{% autoescape %}
    HTML سيهرّب كل شيء في هذه الكتلة باستخدام استراتيجية
{% endautoescape %}
</syntaxhighlight>يستخدم التهريب الآلي خطة تهريب <code>html</code> افتراضيًا، أما إذا كنت تُخرِج متغيرات في سياقات أخرى فستحتاج إلى أن تهربها صراحة بخطة التهريب المناسبة:<syntaxhighlight lang="twig">
{% autoescape 'js' %}
  JS سيُهرَّب كل شيء آليًا في هذه الكتلة باستخدام خطة
{% endautoescape %}
</syntaxhighlight>
 
== التهريب ==
قد ترغب أحيانًا -أو تضطر- إلى أن تجعل Twig يتجاهل أجزاءً كان يمكن أن تعالَج على أنها متغيرات أو كتل، فمثلًا إذا استُخدمت البنية الافتراضية وتريد استخدام <code><nowiki>}}</nowiki></code>  كسلسلة نصية خام في القالب من غير أن تبدأ متغيرًا جديدًا، فيجب أن تحتال على السلوك الافتراضي، وأسهل طريقة لذلك هي بإخراج <code><nowiki>}}</nowiki></code> المفسرة على أنها محدِّد المتغير variable delimiter  من خلال استخدام تعبير متغير:<syntaxhighlight lang="twig">
{{ '{{' }}
</syntaxhighlight>وبالنسبة للأقسام والكتل الأكبر فمن المنطق أن تحدد الكتلة بوسم [[Twig/verbatim|<code>verbatim</code>]].
 
== التعليمات الجامعة Macros  ==
يمكن موازنة التعليمات الجامعة أو الماكرو مع الدوال في لغات البرمجة العادية، وهي مفيدة في إعادة استخدام أجزاء شيفرات HTML لئلا نكرر كتابتها في كل مرة، وستجد شرحها في توثيق وسم [[Twig/macro|<code>macro</code>]].
 
== التعبيرات ==
يسمح Twig بالتعابير في أي مكان تقريبًا. لاحظ أن أسبقية العوامل operators  تكون كما يلي، مع وضع العوامل الأقل أسبقية في البداية:
 
* ‎<code>?:‎</code>
* <code>b-and</code>
* <code>b-xor</code>
* <code>b-or</code>
* <code>or</code>
* <code>and</code>
* <code>==</code>
* ‎<code>!=‎</code>
* <code><=></code>
* ‎<code><‎</code>
* ‎<code>>‎</code>
* ‎<code>>=‎</code>
* <code>‎<=‎</code>
* <code>in</code>
* <code>matches</code>
* <code>starts with</code>
* <code>ends with</code>
* <code>..</code>
* <code>+</code>
* <code>-</code>
* <code>~</code>
* <code>*</code>
* <code>/</code>
* <code>//</code>
* <code>%</code>
* <code>is</code>
* <code>**</code>
* <code>??</code>
* <code>|</code>
* <code>[]</code>
* <code>.</code>
<syntaxhighlight lang="twig">
{% set greeting = 'Hello ' %}
{% set name = 'Fabien' %}
 
{{ greeting ~ name|lower }}  {# Hello fabien #}
 
{# استخدم الأقواس لتغيير الأولوية #}
{{ (greeting ~ name)|lower }} {# hello fabien #}
</syntaxhighlight>
 
=== القيم مصنفة النوع Literals  ===
إن أبسط صورة للتعابير هي القيم مصنفة النوع، وهي تمثيل لأنواع بيانات PHP مثل السلاسل النصية والأرقام والمصفوفات، فلدينا القيم التالية مثلًا:
 
* <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>: تُنشأ الأرقام الصحيحة integers  والأرقام العشرية بكتابة الرقم فقط، فإذا وجدت نقطة <code>.</code>  في الرقم فإنه يكون عشريًا.
* <code>["foo", "bar"]</code>: تُعرَّف المصفوفات بسلسلة من التعابير مفصولة بفاصلة إنجليزية <code>,</code> وتُغلَّف بأقواس مربعة <code>[]</code>.
* <code>{"foo": "bar"}</code>: تُعرَّف الجداول بقائمة من المفاتيح والقيم المفصول بينها بفاصلة إنجليزية وتُغلَّف بأقواس معقوصة <code>{}</code> .
<syntaxhighlight lang="twig">
{# المفاتيح كسلسلة نصية #}
{ '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' }
</syntaxhighlight>
 
* <code>true</code> / <code>false</code>: تمثل <code>true</code> القيمة المتحققة أو الصحيحة، أما <code>false</code> فتمثل القيمة الخاطئة أو غير المتحققة.
* <code>null</code>: لا تمثل <code>null</code> قيمة بعينها، وتعاد إذا كان المتغير غير موجودًا، وتُستخدم <code>none</code> كاسم بديل alias  للقيمة غير المعرفة <code>null</code>.
 
كذلك، من الممكن أن تتشعب المصفوفات والجداول:<syntaxhighlight lang="twig">
{% set foo = [1, {"foo": "bar"}] %}
</syntaxhighlight>لاحظ أن استخدام السلاسل النصية ذوات علامات التنصيص المزدوجة أو المفردة ليس لها تأثير على الأداء، لكن استكمال السلاسل النصية string interpolation ليس مدعومًا إلا في السلاسل ذوات علامات التنصيص المزدوجة.
 
=== العمليات الرياضية ===
يسمح لك Twig بإجراء العمليات الرياضية في القوالب، ويدعم العوامل التالية:
 
* <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>{{ 1 / 2 }}</nowiki></code> هو <code><nowiki>{{ 0.5 }}</nowiki></code>.
* <code>%</code>: يحسب باقي قسمة عددين صحيحين، مثال: ناتج ‎<code><nowiki>{{ 11 % 7 }}</nowiki></code> هو 4.
* <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 ** 3 }}</nowiki></code> هو 8.
 
=== العمليات المنطقية ===
تستطيع جمع عدة تعابير باستخدام المعامَلات التالية:
 
* <code>and</code>: تعيد <code>true</code> إذا تحقق كلا المعامَلين operands  الأيمن والأيسر، أي إذا كانا <code>true</code> كليهما.
* <code>or</code>: تعيد <code>true</code> إذا تحقق أحد المعامَلين، إما الأيمن أو الأيسر.
* <code>not</code>: تنفي التعليمة.
* <code>(expr)</code>: تجمع تعبيرًا.
 
لاحظ أن 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>starts with</code>  أو تنتهي بواحدة <code>ends with</code>:<syntaxhighlight lang="twig">
{% if 'Fabien' starts with 'F' %}
{% endif %}
 
{% if 'Fabien' ends with 'n' %}
{% 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/ التعابير النمطية regular expressions] لموازنات السلاسل النصية المعقدة. <syntaxhighlight lang="twig">
{% if phone matches '/^[\\d\\.]+$/' %}
{% endif %}
</syntaxhighlight>
 
=== عامل الاحتواء ===
ينفذ عامل <code>in</code> اختبار احتواء ويعيد <code>true</code> إذا تم احتواء المعامَل الأيسر داخل الأيمن.<syntaxhighlight lang="twig">
{# returns true #}
 
{{ 1 in [1, 2, 3] }}
 
{{ 'cd' in 'abcde' }}
</syntaxhighlight>تستطيع استخدام هذا المرشح لإجراء اختبار احتواء على السلاسل النصية والمصفوفات أو الكائنات التي تستخدم واجهة <code>Traversable</code>. ولإجراء اختبار سلبي، استخدم عامل <code>not in</code>:<syntaxhighlight lang="twig">
{% if 1 not in [1, 2, 3] %}
 
{# يساوي #}
{% if not (1 in [1, 2, 3]) %}
</syntaxhighlight>
 
=== عامل الاختبار ===
ينفذ عامل <code>is</code> اختبارات يمكن استخدامها لنختبر متغيرًا مع تعبير شائع، ويكون المعامَل الأيمن هو اسم الاختبار:<syntaxhighlight lang="twig">
{# find out if a variable is odd #}
 
{{ name is odd }}
</syntaxhighlight>وتقبل الاختبارات الوسائط:<syntaxhighlight lang="twig">
{% if post.status is constant('Post::PUBLISHED') %}
 
</syntaxhighlight>كما يمكن نفي الاختبار باستخدام عامل <code>is not</code>:<syntaxhighlight lang="twig">
{% if post.status is not constant('Post::PUBLISHED') %}
 
{# يكافئ #}
{% if not (post.status is constant('Post::PUBLISHED')) %}
</syntaxhighlight>اذهب إلى صفحة [[Twig/tests|الاختبارات]] للمزيد عن الاختبارات التي يوفرها Twig.
 
=== العوامل الأخرى ===
العوامل التالية لا تقع تحت أي تصنيف مما سبق:
 
* <code>|</code>: تطبق مرشحًا.
* <code>..</code>: تنشئ تسلسلًا بناءً على المعامَل السابق وبعد العامِل، وهو النسخة البسيطة من دالة [[Twig/range|<code>range</code>]]:
<syntaxhighlight lang="twig">
{{ 1..5 }}
 
{# يكافئ #}
{{ range(1, 5) }}
</syntaxhighlight>لاحظ أنك يجب أن تستخدم الأقواس عند جمعها مع عامل المرشح بسبب قواعد أسبقية العوامل:<syntaxhighlight lang="twig">
(1..5)|join(', ')
 
</syntaxhighlight>
 
* <code>~</code>: تحول جميع المعامَلات إلى سلاسل نصية وتوصلها ببعضها. مثال: ‎<code><nowiki>{{ "Hello " ~ name ~ "!" }}</nowiki></code> سيعيد ‎<code>Hello Osama!‎</code> على افتراض أن الاسم هو <code>Osama</code>.
* <code>.</code>، <code>[]</code>: تجلب سمة المتغير  variable's attribute .
 
* ‎<code>?:‎</code>: العامل الثلاثي:
<syntaxhighlight lang="twig">
{{ foo ? 'yes' : 'no' }}
{{ foo ?: 'no' }} is the same as {{ foo ? foo : 'no' }}
{{ foo ? 'yes' }} is the same as {{ foo ? 'yes' : '' }}
</syntaxhighlight>
 
* <code>??</code>: عامل الأمان من المتغيرات غير المعرفة null-coalescing:
<syntaxhighlight lang="twig">
{# إذا كانت غير ذلك no إذا كانت معرفة، ويعيد foo يعيد قيمة  #}
{{ foo ?? 'no' }}
</syntaxhighlight>
 
=== إقحام السلاسل النصية ===
إقحام السلاسل النصية string interpolation  -انظر  ‎<code>#{expression}</code>- يسمح بظهور أي تعبير صالح داخل سلسلة نصية ذات علامات تنصيص مزدوجة، ونتيجة التقييم أن التعبير يُدخل في السلسلة: <syntaxhighlight lang="twig">
{{ "foo #{bar} baz" }}
{{ "foo #{1 + 2} baz" }}
</syntaxhighlight>
 
== التحكم في المسافات الفارغة ==
يزال أول سطر جديد بعد وسم القالب تلقائيًا -كما في PHP-، ولا يعدِّل محرك القالب على المسافة الفارغة بعد ذلك، وعليه تعاد كل مسافة فارغة بعد ذلك من غير تعديل، سواء كانت مسافة عادية أو مسافة جدولة tab  أو سطرًا جديدًا أو غير ذلك.
 
كما تستطيع التحكم في المسافات الفارغة على مستوى كل وسم باستخدام معدٍّلات التحكم في المسافات الفارغة على وسومك، فتقلِّم المسافات البادئة واللاحقة. ويدعم Twig نوعين من المعدِّلات:
 
* تقليم المسافات الفارغة باستخدام المعدِّل <code>-</code>: يحذف كل المسافات الفارغة بما فيها الأسطر الجديدة.
* تقليم مسافات الأسطر باستخدام المعدِّل <code>~</code>: يحذف جميع المسافات الفارغة باستثناء الأسطر الجديدة، واستخدام هذا المعدل على اليمين يعطل الإزالة الافتراضية لأول سطر جديد موروث من PHP.
 
يمكن استخدام المعدِّلات على أي جانب من جانبي الوسم  <code>{%-</code> أو <code>-%}</code>،  وتستهلك جميع المسافات الفارغة للجانب الذي تكون فيه، ومن الممكن استخدام المعدِّلات على جانب واحد من الوسم أو كلا الجانبين:<syntaxhighlight lang="twig">
{% 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>' #}
</syntaxhighlight>كذلك فإن Twig به مرشح <code>[[Twig/spaceless|spaceless]]</code> الذي يزيل المسافة الفارغة بين وسوم HTML:<syntaxhighlight lang="twig">
{% apply spaceless %}
    <div>
        <strong>foo bar</strong>
    </div>
{% endapply %}
 
{# الخرج: <div><strong>foo bar</strong></div> #}
</syntaxhighlight>
 
== التوسعات ==
اقرأ صفحة [[Twig/advanced|توسيع Twig]] لتعلم كيف تنشئ توسعاتك الخاصة بك.
 
== انظر أيضًا ==
 
* [[Twig/intro|مقدمة عن Twig]]
* [[Twig/internals|المكونات الداخلية لمحرك القوالب Twig]]
* [[Twig/coding standards|معايير كتابة الشيفرة في Twig]]
 
== مصادر ==
 
* [https://twig.symfony.com/doc/3.x/templates.html صفحة Twig for Template Designers من توثيق 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 والإكمال التلقائي، منها على سبيل المثال:

كذلك فإن 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 %}
                &copy; 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 لتعلم كيف تنشئ توسعاتك الخاصة بك.

انظر أيضًا

مصادر