الفرق بين المراجعتين لصفحة: «Twig/internals»
أسامه-دمراني (نقاش | مساهمات) إدخال 2.0 تمام المحتوى وانظر أيضًا والتصانيف والمصادر. |
جميل-بيلوني (نقاش | مساهمات) طلا ملخص تعديل |
||
(3 مراجعات متوسطة بواسطة نفس المستخدم غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:المكونات الداخلية لمحرك القوالب Twig}}</noinclude> | <noinclude>{{DISPLAYTITLE:المكونات الداخلية لمحرك القوالب Twig}}</noinclude> | ||
يتميز محرك القوالب Twig بأنه قابل للتوسيع ويمكن تطويره وتحسينه، لكن انتبه إلى وجوب إنشاء [[Twig/advanced|توسعة extension]] أولًا قبل التعديل على النواة core، ذلك أن التوسعات يمكنها التعديل على أغلب المزايا والخصائص الموجودة. كذلك فإن هذه الصفحة مفيدة لمن يرغب في معرفة كيف يعمل Twig في الحقيقة. | |||
== كيفية عمل Twig == | == كيفية عمل Twig == | ||
{{DISPLAYTITLE:المكونات الداخلية لمحرك القوالب Twig}} | |||
يمكن تلخيص عملية تصيير القالب template rendering في Twig في أربع خطوات أساسية: | |||
* أولًا، يقطِّع المعجم | * حمِّل القالب: إذا كان القالب مصرَّفًا compiled فحمِّله وانتقل إلى خطوة التقييم Evaluation، وإلا فقم بما يلي: | ||
* ثم يحول المحلل | ** أولًا، يقطِّع المعجم lexer شيفرة القالب المصدرية إلى وحدات صغيرة tokens من أجل تسهيل المعالجة. | ||
* وأخيرًا، يحول المصرِّف تلك الشجرة إلى شيفرة PHP. | ** ثم يحول المحلل parser مجرى تلك الوحدات إلى شجرة عقد مفيدة، وهي شجرة البنية اللغوية المجردة Abstract syntax tree. | ||
** وأخيرًا، يحول المصرِّف تلك الشجرة إلى شيفرة [[PHP]]. | |||
والآن، قيِّم القالب، بمعنى أن تستدعي التابع <code>display()</code> من القالب المصرَّف وتمرر السياق إليه. | * والآن، قيِّم القالب، بمعنى أن تستدعي التابع <code>display()</code> من القالب المصرَّف وتمرر السياق إليه. | ||
== المعجم | == المعجم The Lexer == | ||
يقطِّع المعجم شيفرة القالب المصدرية إلى مجرى الوحدات -كل وحدة هي نسخة من <code>\Twig\Token</code>، والمجرى نفسه نسخة من <code>\Twig\TokenStream</code>، والمعجم الافتراضي يتعرف على 13 نوع مختلف من أنواع الوحدات: | يقطِّع المعجم شيفرة القالب المصدرية إلى مجرى الوحدات -كل وحدة هي نسخة من <code>\Twig\Token</code>، والمجرى نفسه نسخة من <code>\Twig\TokenStream</code>، والمعجم الافتراضي يتعرف على 13 نوع مختلف من أنواع الوحدات:<syntaxhighlight lang="php"> | ||
# محدد Delimiter لكتل الشيفرات {% %} | |||
\Twig\Token::BLOCK_START_TYPE | |||
\Twig\Token::BLOCK_END_TYPE | |||
# محدد للمتغيرات {{ }} | |||
\Twig\Token::VAR_START_TYPE | |||
\Twig\Token::VAR_END_TYPE | |||
تستطيع تحويل الشيفرة المصدرية يدويًا إلى مجرى وحدات من خلال استدعاء التابع <code>tokenize()</code> الخاص بالبيئة:<syntaxhighlight lang=" | # نص خارج تعبير ما | ||
\Twig\Token::TEXT_TYPE | |||
# اسم داخل التعبير | |||
\Twig\Token::NAME_TYPE | |||
# عدد داخل التعبير | |||
\Twig\Token::NUMBER_TYPE | |||
# سلسلة نصية داخل التعبير | |||
\Twig\Token::STRING_TYPE | |||
# عامل Operator | |||
\Twig\Token::OPERATOR_TYPE | |||
# علامة ترقيم | |||
\Twig\Token::PUNCTUATION_TYPE | |||
# محددات لإقحام النصوص string interpolation | |||
\Twig\Token::INTERPOLATION_START_TYPE | |||
\Twig\Token::INTERPOLATION_END_TYPE: | |||
# نهاية القالب | |||
\Twig\Token::EOF_TYPE | |||
</syntaxhighlight>تستطيع تحويل الشيفرة المصدرية يدويًا إلى مجرى وحدات من خلال استدعاء التابع <code>tokenize()</code> الخاص بالبيئة:<syntaxhighlight lang="php"> | |||
$stream = $twig->tokenize(new \Twig\Source($source, $identifier)); | $stream = $twig->tokenize(new \Twig\Source($source, $identifier)); | ||
</syntaxhighlight>وبما أن المجرى به التابع <code>__toString()</code> فتستطيع الحصول على تمثيل نصي له بترديد الكائن باستخدام أمر <code>echo</code>: <syntaxhighlight lang=" | </syntaxhighlight>وبما أن المجرى به التابع <code>__toString()</code> فتستطيع الحصول على تمثيل نصي له بترديد الكائن باستخدام أمر <code>echo</code>: <syntaxhighlight lang="php"> | ||
echo $stream."\n"; | echo $stream."\n"; | ||
</syntaxhighlight>ويكون خرج قالب | </syntaxhighlight>ويكون خرج قالب <code>Hello <nowiki>{{ name }}</nowiki></code>:<syntaxhighlight lang="php"> | ||
TEXT_TYPE(Hello ) | TEXT_TYPE(Hello ) | ||
VAR_START_TYPE() | VAR_START_TYPE() | ||
سطر 37: | سطر 58: | ||
VAR_END_TYPE() | VAR_END_TYPE() | ||
EOF_TYPE() | EOF_TYPE() | ||
</syntaxhighlight>لاحظ أن المعجم الافتراضي <code>\Twig\Lexer</code> يمكن تغييره باستدعاء التابع <code>setLexer()</code>:<syntaxhighlight lang=" | </syntaxhighlight>لاحظ أن المعجم الافتراضي <code>\Twig\Lexer</code> يمكن تغييره باستدعاء التابع <code>setLexer()</code>:<syntaxhighlight lang="php"> | ||
$twig->setLexer($lexer); | $twig->setLexer($lexer); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== المحلل | == المحلل Parser == | ||
يحوِّل المحلل مجرى الوحدات إلى شجرة بُنى مجردة كما ذكرنا أعلاه، أو شجرة من العقد تكون نسخة من <code>\Twig\Node\ModuleNode</code>، | يحوِّل المحلل مجرى الوحدات إلى شجرة بُنى مجردة كما ذكرنا أعلاه، أو شجرة من العقد تكون نسخة من <code>\Twig\Node\ModuleNode</code>، وتعرِّف توسعة <code>core</code> العقد الأساسية مثل <code>[[Twig/for|for]]</code> و <code>[[Twig/if|if]]</code> وغيرهما، إضافة إلى عقد التعبير. | ||
تستطيع تحويل مجرى الوحدات يدويًا إلى شجرة عقد باستدعاء التابع <code>parse()</code> الخاص بالبيئة:<syntaxhighlight lang=" | تستطيع تحويل مجرى الوحدات يدويًا إلى شجرة عقد باستدعاء التابع <code>parse()</code> الخاص بالبيئة:<syntaxhighlight lang="php"> | ||
$nodes = $twig->parse($stream); | $nodes = $twig->parse($stream); | ||
</syntaxhighlight>إذا استخدمت أمر echo على كائن العقدة فسيعطيك تمثيلًا جميلًا للشجرة:<syntaxhighlight lang=" | </syntaxhighlight>إذا استخدمت أمر <code>echo</code> على كائن العقدة فسيعطيك تمثيلًا جميلًا للشجرة:<syntaxhighlight lang="php"> | ||
echo $nodes."\n"; | echo $nodes."\n"; | ||
</syntaxhighlight>انظر خرج القالب <code>Hello <nowiki>{{ name }}</nowiki></code>:<syntaxhighlight lang=" | </syntaxhighlight>انظر خرج القالب <code>Hello <nowiki>{{ name }}</nowiki></code>:<syntaxhighlight lang="php"> | ||
\Twig\Node\ModuleNode( | \Twig\Node\ModuleNode( | ||
\Twig\Node\TextNode(Hello ) | \Twig\Node\TextNode(Hello ) | ||
سطر 55: | سطر 76: | ||
) | ) | ||
) | ) | ||
</syntaxhighlight>لاحظ أن المحلل الافتراضي <code>\Twig\TokenParser\AbstractTokenParser</code> يمكن تغييره باستدعاء التابع <code>setParser()</code>:<syntaxhighlight lang=" | </syntaxhighlight>لاحظ أن المحلل الافتراضي <code>\Twig\TokenParser\AbstractTokenParser</code> يمكن تغييره باستدعاء التابع <code>setParser()</code>:<syntaxhighlight lang="php"> | ||
$twig->setParser($parser); | $twig->setParser($parser); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== المصرِّف == | == المصرِّف Compiler == | ||
تتم آخر خطوة باستخدام المصرِّف، إذ يأخذ شجرة العقد كمدخَل ويولد شيفرة PHP قابلة للاستخدام | تتم آخر خطوة باستخدام المصرِّف، إذ يأخذ شجرة العقد كمدخَل ويولد شيفرة PHP قابلة للاستخدام من أجل التنفيذ وقت التشغيل runtime execution الخاص بالقالب. تستطيع تصريف شجرة عقد يدويًا إلى شيفرة PHP باستخدام التابع <code>compile()</code> الخاص بالبيئة:<syntaxhighlight lang="php"> | ||
$php = $twig->compile($nodes); | $php = $twig->compile($nodes); | ||
</syntaxhighlight>ويكون القالب المولَّد لقالب <code>Hello <nowiki>{{ name }}</nowiki></code> كما يلي أدناه، وقد يختلف الخرج الحقيقي وفقًا لنسخة Twig التي تستخدمها:<syntaxhighlight lang=" | </syntaxhighlight>ويكون القالب المولَّد لقالب <code>Hello <nowiki>{{ name }}</nowiki></code> كما يلي أدناه، وقد يختلف الخرج الحقيقي وفقًا لنسخة Twig التي تستخدمها:<syntaxhighlight lang="php"> | ||
/* Hello {{ name }} */ | /* Hello {{ name }} */ | ||
class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Template | class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Template | ||
سطر 87: | سطر 96: | ||
// شيفرة إضافية هنا | // شيفرة إضافية هنا | ||
} | } | ||
</syntaxhighlight>لاحظ أن المصرِّف الافتراضي <code>\Twig\Compiler</code> يمكن تغييره من خلال استدعاء التابع <code>setCompiler()</code>:<syntaxhighlight lang=" | </syntaxhighlight>لاحظ أن المصرِّف الافتراضي <code>\Twig\Compiler</code> يمكن تغييره من خلال استدعاء التابع <code>setCompiler()</code>:<syntaxhighlight lang="php"> | ||
$twig->setCompiler($compiler); | $twig->setCompiler($compiler); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
سطر 93: | سطر 102: | ||
== انظر أيضًا == | == انظر أيضًا == | ||
* [[Twig/advanced|توسيع Twig]] | * [[Twig/advanced|توسيع عمل محرك Twig]] | ||
* [[Twig/intro|مقدمة عن محرك القوالب Twig]] | * [[Twig/intro|مقدمة عن محرك القوالب Twig]] | ||
== المصادر == | == المصادر == | ||
* [https://twig.symfony.com/doc/3.x/internals.html صفحة المكونات الداخلية لمحرك القوالب Twig من توثيق Twig الرسمي]. | * [https://twig.symfony.com/doc/3.x/internals.html صفحة المكونات الداخلية لمحرك القوالب Twig من توثيق Twig الرسمي]. | ||
[[تصنيف:Twig]] | [[تصنيف:Twig]] | ||
[[تصنيف:Twig | [[تصنيف:Twig Intro]] | ||
المراجعة الحالية بتاريخ 10:56، 7 أكتوبر 2022
يتميز محرك القوالب Twig بأنه قابل للتوسيع ويمكن تطويره وتحسينه، لكن انتبه إلى وجوب إنشاء توسعة extension أولًا قبل التعديل على النواة core، ذلك أن التوسعات يمكنها التعديل على أغلب المزايا والخصائص الموجودة. كذلك فإن هذه الصفحة مفيدة لمن يرغب في معرفة كيف يعمل Twig في الحقيقة.
كيفية عمل Twig
يمكن تلخيص عملية تصيير القالب template rendering في Twig في أربع خطوات أساسية:
- حمِّل القالب: إذا كان القالب مصرَّفًا compiled فحمِّله وانتقل إلى خطوة التقييم Evaluation، وإلا فقم بما يلي:
- أولًا، يقطِّع المعجم lexer شيفرة القالب المصدرية إلى وحدات صغيرة tokens من أجل تسهيل المعالجة.
- ثم يحول المحلل parser مجرى تلك الوحدات إلى شجرة عقد مفيدة، وهي شجرة البنية اللغوية المجردة Abstract syntax tree.
- وأخيرًا، يحول المصرِّف تلك الشجرة إلى شيفرة PHP.
- والآن، قيِّم القالب، بمعنى أن تستدعي التابع
display()
من القالب المصرَّف وتمرر السياق إليه.
المعجم The Lexer
يقطِّع المعجم شيفرة القالب المصدرية إلى مجرى الوحدات -كل وحدة هي نسخة من \Twig\Token
، والمجرى نفسه نسخة من \Twig\TokenStream
، والمعجم الافتراضي يتعرف على 13 نوع مختلف من أنواع الوحدات:
# محدد Delimiter لكتل الشيفرات {% %}
\Twig\Token::BLOCK_START_TYPE
\Twig\Token::BLOCK_END_TYPE
# محدد للمتغيرات {{ }}
\Twig\Token::VAR_START_TYPE
\Twig\Token::VAR_END_TYPE
# نص خارج تعبير ما
\Twig\Token::TEXT_TYPE
# اسم داخل التعبير
\Twig\Token::NAME_TYPE
# عدد داخل التعبير
\Twig\Token::NUMBER_TYPE
# سلسلة نصية داخل التعبير
\Twig\Token::STRING_TYPE
# عامل Operator
\Twig\Token::OPERATOR_TYPE
# علامة ترقيم
\Twig\Token::PUNCTUATION_TYPE
# محددات لإقحام النصوص string interpolation
\Twig\Token::INTERPOLATION_START_TYPE
\Twig\Token::INTERPOLATION_END_TYPE:
# نهاية القالب
\Twig\Token::EOF_TYPE
تستطيع تحويل الشيفرة المصدرية يدويًا إلى مجرى وحدات من خلال استدعاء التابع tokenize()
الخاص بالبيئة:
$stream = $twig->tokenize(new \Twig\Source($source, $identifier));
وبما أن المجرى به التابع __toString()
فتستطيع الحصول على تمثيل نصي له بترديد الكائن باستخدام أمر echo
:
echo $stream."\n";
ويكون خرج قالب Hello {{ name }}
:
TEXT_TYPE(Hello )
VAR_START_TYPE()
NAME_TYPE(name)
VAR_END_TYPE()
EOF_TYPE()
لاحظ أن المعجم الافتراضي \Twig\Lexer
يمكن تغييره باستدعاء التابع setLexer()
:
$twig->setLexer($lexer);
المحلل Parser
يحوِّل المحلل مجرى الوحدات إلى شجرة بُنى مجردة كما ذكرنا أعلاه، أو شجرة من العقد تكون نسخة من \Twig\Node\ModuleNode
، وتعرِّف توسعة core
العقد الأساسية مثل for
و if
وغيرهما، إضافة إلى عقد التعبير.
تستطيع تحويل مجرى الوحدات يدويًا إلى شجرة عقد باستدعاء التابع parse()
الخاص بالبيئة:
$nodes = $twig->parse($stream);
إذا استخدمت أمر echo
على كائن العقدة فسيعطيك تمثيلًا جميلًا للشجرة:
echo $nodes."\n";
انظر خرج القالب Hello {{ name }}
:
\Twig\Node\ModuleNode(
\Twig\Node\TextNode(Hello )
\Twig\Node\PrintNode(
\Twig\Node\Expression\NameExpression(name)
)
)
لاحظ أن المحلل الافتراضي \Twig\TokenParser\AbstractTokenParser
يمكن تغييره باستدعاء التابع setParser()
:
$twig->setParser($parser);
المصرِّف Compiler
تتم آخر خطوة باستخدام المصرِّف، إذ يأخذ شجرة العقد كمدخَل ويولد شيفرة PHP قابلة للاستخدام من أجل التنفيذ وقت التشغيل runtime execution الخاص بالقالب. تستطيع تصريف شجرة عقد يدويًا إلى شيفرة PHP باستخدام التابع compile()
الخاص بالبيئة:
$php = $twig->compile($nodes);
ويكون القالب المولَّد لقالب Hello {{ name }}
كما يلي أدناه، وقد يختلف الخرج الحقيقي وفقًا لنسخة Twig التي تستخدمها:
/* Hello {{ name }} */
class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Template
{
protected function doDisplay(array $context, array $blocks = [])
{
// سطر 1
echo "Hello ";
echo twig_escape_filter($this->env, (isset($context["name"]) ? $context["name"] : null), "html", null, true);
}
// شيفرة إضافية هنا
}
لاحظ أن المصرِّف الافتراضي \Twig\Compiler
يمكن تغييره من خلال استدعاء التابع setCompiler()
:
$twig->setCompiler($compiler);