الفرق بين المراجعتين ل"Twig/extends"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
(1.0: إضافة عنوان الصفحة.)
 
(إدخال 2.0 تمام المحتوى وانظر أيضًا والتصانيف والمصادر.)
سطر 1: سطر 1:
 
<noinclude>{{DISPLAYTITLE:الوسم extends في Twig}}</noinclude>
 
<noinclude>{{DISPLAYTITLE:الوسم extends في Twig}}</noinclude>
 +
يُ{{DISPLAYTITLE:الوسم extends في Twig}}ستخدم الوسم extends لتوسيع قالب من قالب آخر.
 +
 +
لا{{DISPLAYTITLE:الوسم extends في Twig}}حظ أن Twig لا يدعم الوراثة المتعددة شأنه في ذلك شأن لغة PHP، فلا يمكنك استدعاء إلا وسم <code>extends</code> واحد عند كل إخراج (rendering)، لكن Twig يدعم إعادة الاستخدام الأفقية، انظر وسم <code>[[Twig/use|use]]</code>.
 +
 +
لن{{DISPLAYTITLE:الوسم extends في Twig}}عرّف قالبًا أساسيًا (base template) هو <code>base.html</code>، الذي يعرّف مستند HTML هيكلي:<syntaxhighlight lang="twig">
 +
1
 +
2
 +
3
 +
4
 +
5
 +
6
 +
7
 +
8
 +
9
 +
10
 +
11
 +
12
 +
13
 +
14
 +
15
 +
16
 +
17
 +
<!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> في المثال السابق أربعة كتل تستطيع القوالب الأبناء أن تملأها، ويخبر وسم block محرك القالب أن القالب الابن قد يتخطى هذه الأجزاء من القالب.
 +
 +
== القالب الابن ==
 +
الشيفرة التالية مثال على قالب ابن (child template):<syntaxhighlight lang="twig">
 +
1
 +
2
 +
3
 +
4
 +
5
 +
6
 +
7
 +
8
 +
9
 +
10
 +
11
 +
12
 +
13
 +
14
 +
15
 +
{% 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 on my awesome homepage.
 +
    </p>
 +
{% endblock %}
 +
</syntaxhighlight>في المثال أعلاه يخبر الوسم <code>extends</code> محرك القالب أن هذا القالب يوسع قالبًا آخر، وعندما يقيّم نظام القالب هذا القالب فإنه يحدد قالبه الأب أولًا، ويجب أن يكون الوسم <code>extends</code> هو أول وسم في القالب.
 +
 +
وبما أن القالب الابن لا يعرّف كتلة <code>footer</code> فإن القيمة التي من القالب الأب هي التي تُستخدم. لا تستطيع تعريف عدة وسوم block بنفس الاسم في نفس القالب، وهذا لأن وسم block يعمل في اتجاهين، فإنه يوفر فراغًا لملئه ويعرّف المحتوى الذي يملأ ذلك الفراغ في القالب الأب في نفس الوقت، وإذا كان لدينا وسمان block في قالب واحد فإن القالب الأب لن يعرف أي الوسمين يختار كي يستخدم محتواه.
 +
 +
لكن إذا أردت طباعة كتلة عدة مرات فيمكنك استخدام دالة <code>block</code>:<syntaxhighlight lang="twig">
 +
<title>{% block title %}{% endblock %}</title>
 +
<h1>{{ block('title') }}</h1>
 +
{% block body %}{% endblock %}
 +
</syntaxhighlight>
 +
 +
== الكتلة الأب ==
 +
من الممكن إخراج محتويات الكتلة الأب باستخدام دالة parent، ويعطينا ذلك نتيجة الكتلة الأب:<syntaxhighlight lang="twig">
 +
{% block sidebar %}
 +
    <h3>Table Of Contents</h3>
 +
    ...
 +
    {{ parent() }}
 +
{% endblock %}
 +
</syntaxhighlight>
 +
 +
== وسم النهاية للكتلة المسماة ==
 +
يسمح لك Twig أن تضع اسم الكتلة بعد وسم النهاية من أجل تيسير قراءتها، ويجب أن يطابق الاسم الذي بعد كلمة <code>endblock</code> اسم الكتلة:<syntaxhighlight lang="twig">
 +
{% block sidebar %}
 +
    {% block inner_sidebar %}
 +
        ...
 +
    {% endblock inner_sidebar %}
 +
{% endblock sidebar %}
 +
</syntaxhighlight>
 +
 +
== نطاق الكتل وتشعبها ==
 +
من الممكن أن تتشعب الكتل لتنشئ بها تخطيطات معقدة، وإن لها افتراضيًا وصول إلى المتغيرات من النطاقات الخارجية :<syntaxhighlight lang="twig">
 +
{% for item in seq %}
 +
    <li>{% block loop_item %}{{ item }}{% endblock %}</li>
 +
{% endfor %}
 +
</syntaxhighlight>
 +
 +
== اختصارات الكتل ==
 +
من الممكن استخدام صياغة مختصرة في حالة الكتل التي ليس بها محتوى كبير، والبنى التالية تنفذ مثل ذلك:<syntaxhighlight lang="twig">
 +
{% block title %}
 +
    {{ page_title|title }}
 +
{% endblock %}
 +
{% block title page_title|title %}
 +
</syntaxhighlight>
 +
 +
== الوراثة الديناميكة ==
 +
يدعم Twig الوراثة الديناميكية (Dynamic Inheritance) عن طريق استخدام المتغير كقالب أساسي (base template):<syntaxhighlight lang="twig">
 +
{% extends some_var %}
 +
</syntaxhighlight>إذا كان المتغير يقيَّم إلى ‎<code>\Twig\Template</code>  أو نسخة من ‎<code>\Twig\TemplateWrapper</code> فإن Twig سيستخدمه كقالب أب:<syntaxhighlight lang="twig">
 +
// {% extends layout %}
 +
 +
$layout = $twig->load('some_layout_template.twig');
 +
 +
$twig->display('template.twig', ['layout' => $layout]);
 +
</syntaxhighlight>يمكنك توفير قائمة من القوالب التي تم التحقق من وجودها، وسيُستخدم أول قالب موجود كقالب أب:<syntaxhighlight lang="twig">
 +
{% extends ['layout.html', 'base_layout.html'] %}
 +
</syntaxhighlight>
 +
 +
== الوراثة الشرطية ==
 +
بما أن اسم القالب الأب قد يكون أي تعبير Twig صالح، فمن الممكن أن نجعل آلية الوراثة آلية شرطية:<syntaxhighlight lang="twig">
 +
{% extends standalone ? "minimum.html" : "base.html" %}
 +
</syntaxhighlight>في المثال أعلاه، يوسِّع القالب قالب التخطيط "minimum.html" إذا قُيِّم المتغير <code>standalone</code> إلى <code>true</code>، ويوسع "base.html" إن كان <code>false</code>.
 +
 +
== كيفية عمل الكتل ==
 +
توفر الكتلة طريقة لتغيير الكيفية التي يُخرَج بها جزء ما من القالب، لكن لا تتدخل في المنطق المحيط به. انظر إلى المثال التالي الذي يوضح كيف تعمل كتلة ما، والحالة التي لا تعمل فيها كذلك:<syntaxhighlight lang="twig">
 +
{# base.twig #}
 +
{% for post in posts %}
 +
    {% block post %}
 +
        <h1>{{ post.title }}</h1>
 +
        <p>{{ post.body }}</p>
 +
    {% endblock %}
 +
{% endfor %}
 +
</syntaxhighlight>إذا أخرجت هذا القالب فإن النتيجة ستكون نفسها سواء استخدمت وسم <code>block</code> أو لا، ذلك أن <code>block</code> التي داخل حلقة <code>for</code> ما هي إلا طريقة لتجعلها قابلة للتخطي بواسطة قالب ابن:<syntaxhighlight lang="twig">
 +
{# child.twig #}
 +
{% extends "base.twig" %}
 +
 +
{% block post %}
 +
    <article>
 +
        <header>{{ post.title }}</header>
 +
        <section>{{ post.text }}</section>
 +
    </article>
 +
{% endblock %}
 +
</syntaxhighlight>عند إخراج القالب الابن فإن الحلقة تستخدم الكتلة المعرفة فيه بدلًا من الكتلة المعرفة في القالب الأساس، ثم يقيَّم القالب المنفَّذ بعدها إلى التالي:<syntaxhighlight lang="twig">
 +
{% for post in posts %}
 +
    <article>
 +
        <header>{{ post.title }}</header>
 +
        <section>{{ post.text }}</section>
 +
    </article>
 +
{% endfor %}
 +
</syntaxhighlight>لنأخذ مثلًا آخر تكون فيه الكتلة مدرَجة داخل تعليمة <code>if</code>:<syntaxhighlight lang="twig">
 +
{% if posts is empty %}
 +
    {% block head %}
 +
        {{ parent() }}
 +
 +
        <meta name="robots" content="noindex, follow">
 +
    {% endblock head %}
 +
{% endif %}
 +
</syntaxhighlight>لا يعرِّف هذا القالب كتلة تعريفًا شرطيًا، على عكس ما قد يظن المرء لأول وهلة، بل يجعل الخرج قابلًا للتخطي بواسطة قالب ابن إذا كان تحقق الشرط، أي كان <code>true</code>.
 +
 +
وإذا أردت عرض الخرج عرضًا شرطيًا فاستخدم ما يلي:<syntaxhighlight lang="twig">
 +
{% block head %}
 +
    {{ parent() }}
 +
 +
    {% if posts is empty %}
 +
        <meta name="robots" content="noindex, follow">
 +
    {% endif %}
 +
{% endblock head %}
 +
</syntaxhighlight>
 +
 +
== انظر أيضًا ==
 +
[[Twig/intro|مقدمة عن محرك القوالب Twig.]]
 +
 +
[[Twig/parent|الدالة parent في Twig.]]
 +
 +
[[Twig/use|الوسم use في Twig]].
 +
 +
== المصادر ==
 +
[https://twig.symfony.com/doc/3.x/tags/extends.html صفحة الوسم extends في توثيق Twig الرسمي].
 +
[[تصنيف:Twig]]
 +
[[تصنيف:Twig Tags]]

مراجعة 20:20، 25 أبريل 2021

يُستخدم الوسم extends لتوسيع قالب من قالب آخر.

لاحظ أن Twig لا يدعم الوراثة المتعددة شأنه في ذلك شأن لغة PHP، فلا يمكنك استدعاء إلا وسم extends واحد عند كل إخراج (rendering)، لكن Twig يدعم إعادة الاستخدام الأفقية، انظر وسم use.

لنعرّف قالبًا أساسيًا (base template) هو base.html، الذي يعرّف مستند HTML هيكلي:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!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 محرك القالب أن القالب الابن قد يتخطى هذه الأجزاء من القالب.

القالب الابن

الشيفرة التالية مثال على قالب ابن (child template):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{% 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 on my awesome homepage.
    </p>
{% endblock %}

في المثال أعلاه يخبر الوسم extends محرك القالب أن هذا القالب يوسع قالبًا آخر، وعندما يقيّم نظام القالب هذا القالب فإنه يحدد قالبه الأب أولًا، ويجب أن يكون الوسم extends هو أول وسم في القالب.

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

لكن إذا أردت طباعة كتلة عدة مرات فيمكنك استخدام دالة block:

<title>{% block title %}{% endblock %}</title>
<h1>{{ block('title') }}</h1>
{% block body %}{% endblock %}

الكتلة الأب

من الممكن إخراج محتويات الكتلة الأب باستخدام دالة parent، ويعطينا ذلك نتيجة الكتلة الأب:

{% block sidebar %}
    <h3>Table Of Contents</h3>
    ...
    {{ parent() }}
{% endblock %}

وسم النهاية للكتلة المسماة

يسمح لك Twig أن تضع اسم الكتلة بعد وسم النهاية من أجل تيسير قراءتها، ويجب أن يطابق الاسم الذي بعد كلمة endblock اسم الكتلة:

{% block sidebar %}
    {% block inner_sidebar %}
        ...
    {% endblock inner_sidebar %}
{% endblock sidebar %}

نطاق الكتل وتشعبها

من الممكن أن تتشعب الكتل لتنشئ بها تخطيطات معقدة، وإن لها افتراضيًا وصول إلى المتغيرات من النطاقات الخارجية :

{% for item in seq %}
    <li>{% block loop_item %}{{ item }}{% endblock %}</li>
{% endfor %}

اختصارات الكتل

من الممكن استخدام صياغة مختصرة في حالة الكتل التي ليس بها محتوى كبير، والبنى التالية تنفذ مثل ذلك:

{% block title %}
    {{ page_title|title }}
{% endblock %}
{% block title page_title|title %}

الوراثة الديناميكة

يدعم Twig الوراثة الديناميكية (Dynamic Inheritance) عن طريق استخدام المتغير كقالب أساسي (base template):

{% extends some_var %}

إذا كان المتغير يقيَّم إلى ‎\Twig\Template أو نسخة من ‎\Twig\TemplateWrapper فإن Twig سيستخدمه كقالب أب:

// {% extends layout %}

$layout = $twig->load('some_layout_template.twig');

$twig->display('template.twig', ['layout' => $layout]);

يمكنك توفير قائمة من القوالب التي تم التحقق من وجودها، وسيُستخدم أول قالب موجود كقالب أب:

{% extends ['layout.html', 'base_layout.html'] %}

الوراثة الشرطية

بما أن اسم القالب الأب قد يكون أي تعبير Twig صالح، فمن الممكن أن نجعل آلية الوراثة آلية شرطية:

{% extends standalone ? "minimum.html" : "base.html" %}

في المثال أعلاه، يوسِّع القالب قالب التخطيط "minimum.html" إذا قُيِّم المتغير standalone إلى true، ويوسع "base.html" إن كان false.

كيفية عمل الكتل

توفر الكتلة طريقة لتغيير الكيفية التي يُخرَج بها جزء ما من القالب، لكن لا تتدخل في المنطق المحيط به. انظر إلى المثال التالي الذي يوضح كيف تعمل كتلة ما، والحالة التي لا تعمل فيها كذلك:

{# base.twig #}
{% for post in posts %}
    {% block post %}
        <h1>{{ post.title }}</h1>
        <p>{{ post.body }}</p>
    {% endblock %}
{% endfor %}

إذا أخرجت هذا القالب فإن النتيجة ستكون نفسها سواء استخدمت وسم block أو لا، ذلك أن block التي داخل حلقة for ما هي إلا طريقة لتجعلها قابلة للتخطي بواسطة قالب ابن:

{# child.twig #}
{% extends "base.twig" %}

{% block post %}
    <article>
        <header>{{ post.title }}</header>
        <section>{{ post.text }}</section>
    </article>
{% endblock %}

عند إخراج القالب الابن فإن الحلقة تستخدم الكتلة المعرفة فيه بدلًا من الكتلة المعرفة في القالب الأساس، ثم يقيَّم القالب المنفَّذ بعدها إلى التالي:

{% for post in posts %}
    <article>
        <header>{{ post.title }}</header>
        <section>{{ post.text }}</section>
    </article>
{% endfor %}

لنأخذ مثلًا آخر تكون فيه الكتلة مدرَجة داخل تعليمة if:

{% if posts is empty %}
    {% block head %}
        {{ parent() }}

        <meta name="robots" content="noindex, follow">
    {% endblock head %}
{% endif %}

لا يعرِّف هذا القالب كتلة تعريفًا شرطيًا، على عكس ما قد يظن المرء لأول وهلة، بل يجعل الخرج قابلًا للتخطي بواسطة قالب ابن إذا كان تحقق الشرط، أي كان true. وإذا أردت عرض الخرج عرضًا شرطيًا فاستخدم ما يلي:

{% block head %}
    {{ parent() }}

    {% if posts is empty %}
        <meta name="robots" content="noindex, follow">
    {% endif %}
{% endblock head %}

انظر أيضًا

مقدمة عن محرك القوالب Twig.

الدالة parent في Twig.

الوسم use في Twig.

المصادر

صفحة الوسم extends في توثيق Twig الرسمي.