فصل ۶: طراحی قالب با Blade‌ در لاراول

23 اسفند 1395
درسنامه درس 7 از سری لاراول
Laravel-Main

در فصل گذشته به یادگیری و آموزش مبحث کنترلرها به عنوان هسته‌ی مرکزی هر نرم‌افزار پرداختیم. همانطور که در مبحث MVC مطرح کردیم،  کنترلر وظیفه‌ی ارتباط با ویو (View) و مدل را به عهده دارد. در این جلسه می‌خواهیم به آموزش مقدماتی تا پیشرفته‌ی طراحی قالب در لاراول بپردازیم.

مقدمه

اگر زبان برنامه‌نویسی PHP را با سایر زبان‌ها مقایسه کنید به این نتیجه می‌رسید که زبان PHP به طور کامل با زبان‌های طراحی قالب مانند HTML, CSS, JS در تعامل است. گاهی برای کدنویسی یک قالب وب سایت نیاز داریم که از توابع و یا دستورهای PHP‌ استفاده کنیم. بنابراین همواره باید تگ <? php?> را بکار برده و دستورهای PHP را درون آن اجرا کنیم. اما لاراول ابزاری را در اختیار برنامه‌نویسان قرار می‌دهد که به سادگی هرچه تمام تر بتوانند دستورهای PHP را بدون استفاده از تگ‌های تکراری پی اچ پی اجرا کنند. نام این موتور طراحی قالب Blade می‌باشد. Blade از موتور Razor در NET. الهام گرفته شده است و از نظر قواعد نحوی و نگارشی (سینتکس) بسیار شبیه به این موتور می‌باشد. در مثال زیر تفاوت بین دو قالبی که از Blade بهره‌برده‌اند و دیگری که بدون استفاده از Blade‌ است، نمایش داده شده:

<?php /* PHP */ ?>
<?php if (empty($users)): ?>
	No users.
<?php else: ?>
	<?php foreach ($users as $user): ?>
		<?= $user->first_name ?> <?= $user->last_name ?><br>
	<?php endforeach; ?>
<?php endif; ?>

{{-- Blade --}}
@forelse ($users as $user)
	{{ $user->first_name }} {{ $user->last_name }}<br>
@empty
	No users.
@endforelse

همانطور که مشاهده می‌کنید سینتکس Blade‌ بسیار ساده و تمیز تر از سینتکس PHP است.

نمایش داده‌ها و اطلاعات

در مثال بالا همانطور که مشاهده می‌کنید برخی از عبارات داخل تگ {{ }} که به تگ سیبیل (Mustache Tag) معروف است، قرار گرفته اند. این تگ برای نمایش مقادیر ذخیره شده درون متغییر ها کاربرد دارد و مانند دستور echo‌ در PHP می‌باشد. به فرض مثال عبارت {{ variable$ }} مشابه دستور <?  variable$ =?> است.

اما تنها تفاوتی که بین این دو دستور وجود دارد این است که در Blade تمام داده‌ها و متغییرها به صورت پیشفرض با حالت htmlspecialchars نمایش داده می‌شوند تا از حملات XSS روی وب سایت شما جلوگیری کند. (یعنی هر داده‌ای که شامل خط فاصله و حروف نامعلوم باشد در خروجی به صورت کد html تبدیل می‌شود) این بدین معنی‌ست که عبارت {{ variable$ }} مشابه دستور <?  htmlentities($variable) =?> است.

برای نمایش دادن یک عبارت در خروجی بدون درنظر گرفتن بحث htmlspecialchars باید از سینتکس {!!  !!} استفاده کرد. در مثال زیر نمونه‌های خروجی را به نمایش می‌گذاریم:

<?php  $variable = '<a href="http://www.roxo.ir"></a>'; ?>
// <a href="http://www.roxo.ir"></a> در خروجی سورس برنامه نمایش میدهد:
// اما در صفحه نمایش برای کاربر چیزی را نمایش نمیدهد
{!! $variable !!} // تنها در سورس برنامه مقدار دقیق $variable

//&lt;a href=&quot;http://www.roxo.ir&quot;&gt;&lt;/a&gt; نمایش در سورس برنامه:
// آما آنچه به کاربر نمایش داده می‌شود: <a href="http://www.roxo.ir"></a>
{{ $variable }}

حال اگر بخواهیم دستور {{ }} را غیر فعال کنیم کافی‌ست از یک @ در ابتدای آن قرار دهیم. برای مثال بالا خروجی به صورت زیر خواهد بود:

<?php  $variable = '<a href="http://www.roxo.ir"></a>'; ?>

@{{ $variable }} // آنچه در خروجی نمایش داده می‌شود:‌ {{ $variable }}

همچنین برای کامنت کردن‌ (غیرفعال کردن بخشی از کدها) در Blade باید از دستور {-- --} استفاده کرد. در این حالت آنچه ما بین این سینتکس قرار می‌گیرد هرگز اجرا نمی‌شود.

ساختار کنترلی در Blade

موتور طراحی قالب Blade امکانات فوق‌العاده‌ای در اختیار شما قرار می‌دهد تا بتوانید دستورهای شرطی و کنترلی را به ساده‌ترین شکل ممکن پیاده‌سازی کنید. کارایی این دستورها دقیقا مشابه زبان PHP است. در ادامه به توضیح این دستورها می‌پردازیم:

دستورهای شرطی

دستور if@, @else, @elseif

دستور شرطی if  به همراه else یا else if در زبان طراحی قالب Blade با استفاده از عبارات زیر تعیین می‌شود:

@if (count($talks) === 1)
    There is one talk at this time period.
@elseif (count($talks) === 0)
    There are no talks at this time period.
@else
    There are {{ count($talks) }} talks at this time period.
@endif

دستور unless@ و endunless@

این دستور مشابه Not دستور if عمل می‌کند. یعنی:

Blade                                     PHP
=========================================================
@unless ($condition)            <?php if(! $condition) ?>
    //do somethings
@endunless

دستور حلقه‌ها

دستور حلقه‌های for@, foreach, @while

برای معادل‌سازی دستور حلقه‌های while و for و foreach‌ در Blade به‌صورت زیر عمل خواهیم کرد:

@for and @endforeach
=======================
@for ($i = 0; $i < 20; $i++)
    The number is {{ $i }}
@endfor

@foreach and @endforeach
========================
@foreach ($talks as $talk)
    {{ $talk->title }} ({{ $talk->length }} minutes)
@endforeach

@while and @endwhile
========================
@while ($item = true)
{{ $item->orSomething() }}<br>
@endwhile

دستور forelse@

این دستور یک اختراع جدید در Blade می‌باشد که درصورت خالی بودن آرایه و یا مقادیر یک فضا در اختیار شما قرار می‌دهد تا عملیات دیگری را اجرا کنید:

@forelse ($talks as $talk)
    {{ $talk->title }} ({{ $talk->length }} minutes)
@empty
    No talks this day.
@endforelse

عبارت or

از دستور or برای نمایش مقدار پیش‌فرض در کناب متغییر استفاده می‌شود. به نمونه‌ی زیر توجه کنید تا توضیحات را ارائه دهیم:

{{ $title or "Roxo" }}

در این مثال اگر متغییر title مقدار داشت نمایش داده می‌شود درغیر اینصورت مقدار پیشفرض Roxo‌ نمایش داده خواهد شد.

ارث‌بری در Blade

همانطور که از نام این بخش پیداست می‌خواهیم شما عزیزان را با مفهومی تحت عنوان ارث‌بری (inheritance) آشنا کنیم. نکته‌ای که باید همواره به یاد داشته باشید این است که هر لحظه کلمه‌ی ارث‌بری در هر زبان برنامه‌نویسی استفاده شد، مفهوم ارث بری شما از پدرتان و پدرتان از پدربزرگتان است. یعنی برخی از خصوصیات از پدربزرگتان به پدرتان و در نهایت برخی از خصوصیات از پدرتان به شما رسیده و به‌صورت سلسله‌مراتبی شما از پدربزرگتان ویژگی‌هایی را به ارث برده‌اید.

حال در Blade سیستم ارث‌بری به شما کمک می‌کند که یک قالب پدر (Master) را به چندین قالب فرزند (child) تقسیم کنید. برای اینکار ابتدا باید با برخی مفاهیم مانند section, show, yield آشنایی کامل داشته باشید.

تعریف فرزندان (childs) با section/show و yield

برای اینکار ابتدا در پوشه‌ی resources/view/layouts یک فایل به نام master.blade.php بسازید و محتویات زیر را درون آن قرار دهید:

<html>
<head>
    <title>App Name - @yield('title')</title>
</head>
<body>
@section('sidebar')
    This is the master sidebar.
@show

<div class="container">
    @yield('content')
</div>
</body>
</html>

section@

ترجمه کلمه‌ی section برابر است با:‌ بخش. حال در این مثال به قالب اصلی (پدر) گفته‌ایم که این قالب از چندین فرزند تشکیل شده است. عبارت section یکی از فرزندها را نمایش می‌دهد که نام آن footerScripts می‌باشد.

yield@

ترجمه عبارت yield برابر است با: واگذار کردن. حال در این مثال برخی از بخش‌های قالب را واگذار کرده‌ایم.

show@

ترجمه این عبارت معادل: نمایش است و برای نمایش دادن بخش‌های فرزند استفاده می‌شود.

extend@

حال باید به دستوری به نام extend@ اشاره کنیم که نحوه‌ی تعریف قالب‌های فرزند جهت استفاده در قالب‌های پدر را مشخص می‌کند. برای اینکار یک فایل تحت عنوان child.blade.php در فولدر اصلی یعنی resources/view ایجاد می‌کنیم:

@extends('layouts.master')

@section('title')
    Hello Roxo
@endsection

@section('sidebar')
    @parent
    New Sidebar
@endsection

@section('content')
    New Content
@endsection

در این فایل ابتدا از دستور extend@ جهت فراخوانی فایل پدر تحت عنوان layouts.master استفاده کرده‌ایم.

سپس یک section با عنوان مشابه در صفحه پدر master با عنوان title ایجاد کرده‌ایم. یعنی title هر آنچه که اینجا نوشته شود در صفحه اصلی با استفاده از دستور yield دریافت می‌شود و در مکان مشخص خود قرار می‌گیرد.

سپس یک section‌ دیگر با نامی مشابه آنچه در صفحه پدر master است ایجاد کردیم. این نام sidebar است. منظور از این کار یا جایگزین کردن این بخش با بخش موجود در صفحه پدر است و یا اضافه کردن بخش پدر با دستور parent@ به بخش فرزند است. اگر از دستور parent@ استفاده نکنیم. مقدار این بخش با مقدار موجود در صفحه پدر جایگزین می‌شود.

در انتها آخرین section را ایجاد کرده و نام آن را برابر content قرار داده‌ایم تا هر آنچه در این بخش است را به بخش content در صفحه پدر ارسال کنیم.

include@

از دستور include برای فراخوانی فایل‌های دیگر و ارسال داده‌ها به سایر فایل‌ها استفاده می‌شود. به مثال زیر توجه کنید:

<!-- resources/views/home.blade.php -->
<div class="content" data-page-name="{{ $pageName }}">
    <p>Here's why you should sign up for our service: <strong>It's Great.</strong></p>
    @include('sign-up-button', ['text' => 'See just how great it is'])
</div>
===================================================================
<!-- resources/views/sign-up-button.blade.php -->
<a class="button button--callout" data-page-name="{{ $pageName }}">
    <i class="exclamation-icon"></i> {{ $text }}
</a>

نکته‌ای که در دستور include نهفته است این است:‌ در دستور include نه تنها می‌توان به عنوان یک پارامتر داده‌ای خارجی را به صفحه include شده ارسال کرد بلکه هر متغییری که در صفحه پدر موجود باشد در صفحه‌ی فرزند که می‌خواهیم آن را include‌ کنیم قابل دسترسی است. مانند متغییر pageName$ در مثال فوق.

دستوری تحت عنوان includeIf@ برای زمانی‌ مورد استفاده قرار می‌گیرد که در صورت عدم وجود صفحه فرزند خطایی را نمایش ندهد.

به شما تبریک می‌گوییم. حال با فراگفتن بخش کنترلر و ویوها می‌توانید قالب‌های بسیار جذابی برای خودتان بسازید. در بخش آینده به توضیح برخی از Facade‌های بسیار کاربردی در لاراول می‌پردازیم. با ما همراه باشید.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری لاراول توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما (5 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

من
05 اسفند 1397
در کد مثال @for and @endfor به اشتباه در سطر اول نوشته اید: @for and @endforeach

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

ابوالفضل
20 آذر 1397
تا اینجای کار که خیلی عالی

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

haj_sajad
29 فروردین 1397
yield('ap')@

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

فاطمه
18 فروردین 1397
سلام و خسته نباشید آموزشی بهتر از این ندیدم عالی بود ممنون

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

ap
19 آبان 1396
واقعا دمتون گرم .. کلمه به کلمه مقاله هاتون قابل فهمه بهترین آموزشیه که دیدم

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.