همانطور که در بخش های قبلی توضیح داده شده است، کنترل کننده مسئول رسیدگی به هر درخواستی است که به یک برنامه Symfony می آید و معمولا پاسخ ها را در یک قالب قرار داده و به عنوان پاسخ تولید می کند.

در حقیقت، کنترل کننده بیشتر کارهای سنگین را به بخشهای دیگر محول می کند تا کدها ساده تر شده و بتواند راحت تر تست شده و یا  استفاده مجدد شود. هنگامی که یک کنترل کننده نیاز به تولید HTML، CSS یا هر محتوای دیگر دارد، کار را به موتور قالب محول می کند.

در این مقاله، نحوه نوشتن قالب های قدرتمندی را آموزش می دهیم که می توانید برای ارائه محتوا به به کاربر، ارسال به آدرس پست الکترونیک و غیره استفاده کنید.با کلید های میانبر، روش های هوشمندانه برای گسترش قالب ها و نحوه استفاده از کدهای قالب را خواهید آموخت.

قالب ها در سیمفونی

یک قالب به سادگی یک فایل متنی است که می تواند هر فرمت مبتنی بر متن (HTML، XML، CSV، LaTeX …) را تولید کند. آشنا ترین نوع قالب یک قالب PHP است – یک فایل متنی که توسط پی اچ پی تفسیرشده و حاوی ترکیبی از متن و کد پی اچ پی است.

<!DOCTYPE html>
<html>
<head>
<title>Welcome to Symfony!</title>
</head>
<body>
<h1><?= $page_title ?></h1>
<ul id="navigation">
<?php foreach ($navigation as $item): ?>
<li>
<a href="<?= $item->getHref() ?>">
<?= $item->getCaption() ?>
</a>
</li>
<?php endforeach ?>
</ul>
</body>
</html>

اما سیمفونی( Symfony ) یک زبان برنامه نویسی قویتر را به نام Twig را در اختیار شما قرار می دهد . Twig اجازه می دهد تا قالب ها را بصورت خلاصه تر و خواناتر و با روش های متنوعی بنویسید ضمن اینکه Twig رابطه دوستانه تری با طراحان وب دارد.

به عنوان مثال بجای استفاده از قالب PHP فوق می توان قالب Twig زیر را ایجاد کرد:

<!DOCTYPE html>
<html>
<head>
<title>Welcome to Symfony!</title>
</head>
<body>
<h1>{{ page_title }}</h
۱>
<ul id="navigation">
{% for item in navigation %}
<li><a href="{{ item.href }}">{{ item.caption }}</a></li>
{% endfor %}
</ul>
</body>
</html>

قواعد twig

twig سه نوع قاعده خاص را تعریف می کند:

{{ … }}

“چیزی می گوید” : که  یک متغیر یا نتیجه بیان به الگو را چاپ می کند.

{% … %}

“چیزی انجام می دهد”: یک برچسب که منطق قالب را کنترل می کند؛ برای اجرای ساختارهای شرطی، تکرار و … استفاده می شود.

{# … #}

“توضیح می دهد “: برای تعیین توضیحات است و می تواند بصورت یک یا چند سطر نوشته شود. محتوای توضیحات در صفحات رندر نخواهد شد.

twig همچنین دارای فیلترهایی است که قبل از رندر کردن محتوا، روی آنها تغییراتی اعمال می کند. در مثال زیر، متغیر عنوان را قبل از رندر آن را به صورت بزرگ نشان می دهد:

{{ title|upper }}

twig همراه با لیست طولانی از برچسب ها، فیلتر ها و توابع که به طور پیش فرض در دسترس هستند.  حتی می توانید فیلتر های سفارشی خود، توابع (و بیشتر) را از طریق یک افزونه به twig اضافه کنید.

کدهای twig تا حدودی مشابه کدهای php هستند با تفاوت های ظریف و زیبا. مثال زیر با استفاده از یک استاندارد برای تگ و تابع cycl برای چاپ ده تگ div، با کلاس های متناوب و عادی، استفاده شده است:


{% for i in 1..10 %}
<div class="{{ cycle(['even', 'odd'], i) }}">
<!-- some HTML here -->
</div>
{% endfor %}

کش کردن قالب های twig

twig سریع است چون هر یک از قالب ها پس از رندر شده به  به یک کلاس PHP تبدیل شده و برای دفعات بعد ذخیره می شود. این کار به طور خودکار انجام شده و نیازی به انجام هیچ کاری توسط شما ندارد. و در حالی که اگر در حال توسعه نرم افزار هستید، Twig به اندازه کافی هوشمند است و در صورت تغییر قالب، نسخه مربوط به آن در کش را بروز می کند .

twig در زمان انتشار نرم افزار باعث سریع شدن بازیابی و رندر صفحات می شود هر چند در زمان توسعه نرم افزار هم کار را راحت تر می کند.

وراثت و طرح بندی قالب ها

در اغلب موارد، قالب ها در یک پروژه دارای بخش هایی مثل هدر، پفوتر، نوار کناری و یا بیشتر هستند که در همه صفحات یکسان است. در سیمفونی، این مسئله به طور ویژه ای مورد توجه قرار گرفته است: قالب را می توان با قالب دیگری تزئین کرد. ارث بری الگوها به شما امکان می دهد تا یک قالب پایه (یا قالب پدر) را که شامل تمام بخش های مشترک سایت شما است تعریف کنید ( که به آنها block گفته می شود) . سپس هر قالب فرزند می تواند از قالب پدر ارث بری داشته باشد و هر یک از بلوک های آن را در صورت نیاز رونویسی کند.

برای این کار ابتدا یک فایل قالب پایه ایجاد کنید:

{# templates/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Test Application{% endblock %}</title>
</head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog">Blog</a></li>
</ul>
{% endblock %}
</div>
<div id="content">
{% block body %}{% endblock %}
</div>
</body>
</html>

این قالب یک صفحه دارای دو ستون تعریف می کند. در این مثال، سه بلوک {٪ block٪} یا ناحیه تعریف شده اند (عنوان، نوار کناری و بدنه ). هر بلوک ممکن است توسط قالب فرزند  رونویسی شود یا همین مقدار پیش فرض آن باقی مانده و استفاده شود. این قالب همچنین می تواند به طور مستقیم نمایش داده شود که در این صورت عنوان، نوار کناری و بلوک های بدنه با همین مقادیر پیش فرض نمایش داده خواهند شد.

قالب فرزند ممکن است شبیه زیر نوشته شود:

{# templates/blog/index.html.twig #}
{% extends 'base.html.twig' %}
{% block title %}My cool blog posts{% endblock %}
{% block body %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}

الگوی پدر در مسیر templates/ ذخیره می شود، و نام آن base.html.twig است.

نکته کلیدی در ارث بری، عبارت {% extends ‘base.html.twig’ %} است که به موتور قالب گوشزد می کند، اول قالب پدر را بررسی کند. تا تنظیمات قالب تعیین شده و بلاک های اصلی تعریف شوند. سپس قالب فرزند بررسی شده و بلاک های title و body  روی بلاک های پدر رونویسی می شوند.

در مثال فوق با توجه به رکوردهای قرار گرفته در آرایه blog_entries ممکن است خروجی HTML زیر تولید شود:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My cool blog posts</title>
</head>
<body>
<div id="sidebar">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog">Blog</a></li>
</ul>
</div>
<div id="content">
<h2>My first post</h2>
<p>The body of the first post.</p>
<h2>Another post</h2>
<p>The body of the second post.</p>
</div>
</body>
</html>

توجه کنید از انجا که قالب فرزند بلاک sidebar را تعیین نکرده است، همان مقدار تعیین شده در قالب پدر برای آن نمایش داده خواهد شد.

هنگام کار با ارث الگو، چند نکته را در نظر داشته باشید:

۱- اگر از راهنمای extends استفاده می کنید باید آنرا در ابتدای قالب بنویسید.

۲- سعی کنید بلاک های بیشتری را در قالب پدر تعریف کنید. این کار از تکرار بلاک ها مشابه در قالب های فرزند جلوگیری می کند و طراحی قالب و تغییرات قالب ها را در آینده راحت تر می کند.  اصلا هم لازم نیست بلاک های تعریف شده در قالب پدر در همه قالب های قرزند تعریف شده باشند.

۳- اگر بخش های مشابهی در چند تا از قالب های فرزند مشاهده کردید، بهتر است که قالب کمکی با این محتوای تکراری تعریف کرده و به جای محتوا، آن قالب را ضمیمه کنید.

۴- اگر می خواهید در قالب فرزند، محتوای بلاک که در قالب پدر تعریف شده را داشته باشید از عبارت {{ ()parent }} استفاد کنید:

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

نامگذاری و مکان فایل های قالب

پوشه views از هر کاربرد می تواند حاوی زیرپوشه templates باشد و فایل های قالب در این زیرپوشه قرارداده شوند. معمولا قالب های پایه در پوشه templates ذخیره شده و برای هر ماژول یک زیرپوشه در آن ایجاد شده و قالب های مربوط به ماژول در آن زیر پوشه قرار می گیرند.

 

در این قسمت ، ساخت قالب های سیمفونی با استفاده از موتور قالب twig را آموزش دادیم در قسمت های بعد، قواعد کامل twig برای ساخت قالب را بررسی خواهیم کرد.

موفق باشید.