جشنواره فطر سون لرن

آموزش View Composer در لاراول

دسته بندی: لاراول
زمان مطالعه: 7 دقیقه
۲۴ اردیبهشت ۱۳۹۹

در این مقاله به آموزش استفاده‌ی یکی از بهترین امکانات لاراول یعنی View Composer می‌پردازیم.

فرض کنید می‌خواهید تعداد زیادی از داده‌های database را در صفحات مختلف سایت به کاربر نمایش دهید. ساده‌ترین راه این است که در Controller داده‌ها را از Model بگیریم و به View ارسال کنیم. این کار تا زمانی که تعداد صفحات سایت کم باشد، تقریبا راهی معقول است. اما زمانی که سایت ما گسترش یابد، با مشکلاتی روبرو می‌شویم که به یک راه جایگزین نیاز پیدا می‌کنیم. این راه همان استفاده از View Composer است که در ادامه برای درک بهتر تفاوت‌ها ابتدا راه معمولی را می‌گوییم، سپس آن را با View Composer مقایسه می‌کنیم. همچنین برای تفهیم بیشتر View Composer در لاراول مطالب یک پروژه‌ی کوچک که می‌خواهد نام چند ماشین را نمایش دهد، پیاد‌ه‌سازی می‌کنیم.

فهرست محتوای این مقاله

راه معمولی :

Waysروشی که ما در این ‌‌آموزش به آن می‌پردازیم. ابتدا ساخت route، سپس controller و بعد از آن view است.

ساخت Route :

برای ساخت یک route در آدرس routes/web.php به‌صورت زیر عمل می‌کنیم.

<?php

use Illuminate\Support\Facades\Route;


Route::get('cars','CarsController@index');

ساخت Controller :

توسط دستور زیر  یک Controller به‌نام CarsController را ایجاد می‌کنیم.

$ php artisan make:controller CarsController

همان طور که مشاهده می‌کنید، برای نمایش داده‌ها route به CarsController می‌رود و تابع index را می‌خواند. پس تابع index را در CarsController ایجاد می‌کنیم و نام تمام ماشین‌ها که از قبل در database ایجاد کردیم را از Model می‌گیریم و به یک View ارسال می‌کنیم.

<?php

namespace App\Http\Controllers;

use App\Cars;
use Illuminate\Http\Request;

class CarsController extends Controller
{
    public function index()
    {
       $cars=Cars::all();

       return view('cars.index',compact('cars'));
    }
}

توجه کنید که حتما model خود را در بالا use کرده باشید.

ساخت View :

اگر به تابع index در Controller توجه کرده باشید، می‌بینید که cars به یک View به‌نام cars.index توسط تابع compact ارسال می‌شود. پس در این مرحله به ساخت View می‌پردازیم.

برای ساخت View ابتدا پوشه‌ای به‌نام cars در resources/views می‌سازیم. سپس فایل blade به‌نام index را به‌صورت زیر ایجاد می‌کنیم.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Cars</title>
</head>
<body>

<ul>
   @foreach($cars as $car)
       <li>{{ $car->name }}</li>
    @endforeach
</ul>

</body>
</html>

نمایش داده‌ها در سایت :

حال در صفحه‌ی سایت‌مان نام تمام ماشین‌ها به صورت زیر نمایش داده می‌شود، که این همان راه معمولی و همیشگی است.

List

همان‌طور که مشاهده کردید، ما فقط برای یک صفحه از سایت یعنی صفحه‌ی cars/ نیاز به ساخت Controller و سپس View داریم. فرض کنید که سایت ما دارای ۲۰ صفحه است که در تمام آن صفحات باید نام ماشین‌ها، به‌طور مثال در یک صفحه به‌ترتیب قیمت، در صفحه‌ی دیگر به‌ترتیب سال تولید و در صفحات مختلف به ترتیب‌های دیگری نمایش داده شود. در این صورت ساخت حداقل یک Controller برای هر کدام از آن‌ها دیگر بهترین راه نیست و View Composer بهترین جایگزین است.

انتقال داده‌ها به‌صورت Global :

برای آشنایی با View Composer ابتدا می‌خواهیم یاد بگیریم که چگونه می‌توانیم داده‌ها را به جای چند Controller تنها در یک قسمت وارد کنیم تا تمام View‌ها به ‌آن دسترسی داشته باشند.

برای این‌کار به app/Providers/AppServiceProvider.php بروید و در تابع boot دستور زیر را وارد کنید.

<?php

namespace App\Providers;

use App\Cars;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{

    public function boot()
    {
         View::share('cars', Cars::orderBy('name')->get());
    }

    public function register()
    {
        //
    }
}

ما از کلاس View، متد share را فراخوانی کردیم که پارامتر اول آن نام متغیر یعنی cars$ و پارامتر دوم مقدار cars$ است. (توجه کنید که از علامت $ در پارامتر‌ها استفاده نکنید.)

حال اگر در CarsController خط زیر و مقدار compact را پاک کنید و به صفحه‌ی سایت بروید، مشاهده می‌کنید که تمامی داده‌ها مثل قبل، البته به‌ترتیب نام وجود دارند.

مشکلات این روش :

وقتی که یک متغیر را به‌صورت بالا در AppServiceProvider و به‌صورت Global تعریف می‌کنیم. به‌طور خودکار این متغیر به‌تمام View‌ها چه بخواهیم، چه نخواهیم ارسال می‌شود و این کار database را بیهوده اشغال می‌کند.

View Composer در لاراول :

View Composer مانند روش بالاست با این تفاوت که می‌توانیم تعیین کنیم که متغیرمان به کدام View‌ها ارسال شود.

<?php

namespace App\Providers;

use App\Cars;
use Illuminate\Support\Facades\View;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{

    public function boot()
    {
        // Option 2

        View::composer(['cars.index','cars.buy'], function($view)
        {
            $view->with('cars', Cars::orderBy('name')->get())
        });
    }

    public function register()
    {
        //
    }
}

ما از کلاس View، متد composer را فراخوانی کردیم که پارامتر اول آن صفحاتی که می‌خواهیم متغیر به آن ارسال شود و پارامتر دوم یک تابع callback است که مانند View::share عمل می‌کند و می‌توانید همان اطلاعاتی که در View::share وارد کردید در with هم وارد کنید.

همچنین اگر می‌خواهید به‌طور مثال متغیر به تمام View‌های درون یک پوشه ارسال شود کافی است به‌جای نام یک View علامت * را به‌صورت زیر بگذارید.

View::composer(['cars.*'], function($view)
        {
            $view->with('cars', Cars::orderBy('name')->get())
        });

حال اگر به‌طور مثال بخواهیم که داده‌ها در یک صفحه به‌ترتیب نام، در صفحه‌ای دیگر به‌ترتیب قیمت، و در هر صفحه به شکل خاصی مرتب شوند می‌توانیم در app/Http یک پوشه به‌نام View بسازیم و در آن پوشه‌ای به‌نام Composers ایجاد کنیم. بعد از ایجاد پوشه‌ی Compossers در آن یک Class به‌نام CarsComposer بسازید و درون CarsComposer کد زیر را وارد کنید :

<?php


namespace App\Http\View\Composers;


use App\Cars;
use Illuminate\View\View;

class CarsComposser
{
    public function compose(View $view)
    {
        $view->with('cars', Cars::all());
    }
}

همان دستوراتی که در تابع callback هنگام استفاده از View::composer وارد کردیم را در تابع compose کلاس بالا تعریف می‌کنیم. سپس به AppServiceProvider رفته و View::composer را به‌صورت زیر تغییر می‌دهیم :

<?php

namespace App\Providers;

use App\Cars;
use App\Http\View\Composers\CarsComposser;
use Illuminate\Support\Facades\View;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{

    public function boot()
    {
        //Option 3

        View::composer(['cars.index','cars.buy'],CarsComposser::class);
    }

    public function register()
    {
        //
    }
}

همچنین امکان دارد چندین View مختلف، در چندین پوشه‌ی مختلف قرار داشته باشد. به‌طور مثال فرض کنید که شما ۱۰ پوشه که در هر پوشه ۵ View قرار دارد را دارید. در این صورت وارد کردن View‌ها کاری تقریبا زمانبر است. پس بهتر است از راه جایگزین استفاده کنید. بدین منظور قسمت‌هایی از View که دارای متغیر cars می‌باشد یعنی:

@foreach($cars as $car)
       <li>{{ $car->name }}</li>
@endforeach

را به پوشه‌ای مانند پوشه‌ی partials می‌بریم و در view خود آن را include می‌کنیم.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Cars</title>
</head>
<body>

<ul>
@include('partials.list')
</ul>

</body>
</html>

سپس appServiceProvider را از

public function boot()
    {
        //Option 3

        View::composer(['cars.index','cars.buy'],CarsComposser::class);
    }

به

public function boot()
    {
        //Option 3

        View::composer('partials.*',CarsComposser::class);
    }

تغییر می‌دهیم.

جمع‌بندی:

در این مقاله سعی ما از ابتدا بر این بود، که مفاهیم را هر چه بهتر و در قالب یک پروژه‌ی کوچک، همراه با مقایسه نسبت به روش‌های دیگر به شما آموزش بدهیم. حال شما می‌توانید از این قابلیت بزرگ لاراول در پروژه‌های خود همان‌گونه که می‌خواهید استفاده کنید. در صورت داشتن هرگونه سوال یا تجربه‌ای در این زمینه، آن را در قسمت نظرات با ما به اشتراک بگذارید.

اگر به یادگیری بیشتر لاراول علاقه داری می‌تونی در دوره آموزشی لاراول کاربردی (بسته پروژه محور) شرکت کنی، این دوره شامل ۱۲ پروژه کاربردی و پر استفاده در دنیای واقعی است، که تمامی پروژه‌ها به صورت کامل برنامه‌ نویسی خواهند شد، تا دانشجو بتواند با روند ایجاد و تکمیل پروژه به صورت کامل آشنا شود.

 

 

چه امتیازی به این مقاله می دید؟
نویسنده علی مجیدی
Backend Developer | PHP & Laravel Developer

نظرات کاربران

مهرزاد

بسیار عالی ….

علی مجیدی

ممنون از نظر لطف شما

Mohsen Torabi

مثل مقاله ی قبلیتون عالی و بدون نقص ممنونم ازتون بابت وقتی که میذارید

علی مجیدی

ممنون از شما بابت نظر لطفتان 🙏🏻🙏🏻

محمد جمالی

خیلی خوب بود مرسی👌🏻👌🏻

علی مجیدی

ممنون از نظر لطف و همراهی شما

Saba vahedi

خیلی جامع و کامل بود تشکر از سایت خوبتون بابت مطالب کاربردی و خوبی که می زارید واقعا به این سایت علاقه مند شدم

علی مجیدی

ممنون از لطف شما 🙏🏻

ارسال دیدگاه
خوشحال میشیم دیدگاه و یا تجربیات خودتون رو با ما در میون بذارید :