Slots & Layouts

استفاده از Slots و Layouts در Blade

graph TD A[View] -->|@extends| B[Layout] B --> C[@yield sections] A --> D[@section content] D --> C E[Component] --> F[Slots] F --> G[Default Slot] F --> H[Named Slots] I[Parent View] -->|@push| J[Stack] J --> K[Layout @stack]

Slots و Layouts به شما امکان می‌دهند محتوای قابل تغییر را در templateها تعریف کنید. این الگو به شما کمک می‌کند که structure مشترک را در چند view استفاده کنید.


Layouts:


Layouts ساختار اصلی صفحه را تعریف می‌کنند و با استفاده از @extends و @section کار می‌کنند. Layoutها معمولاً شامل HTML structure، head section، navigation، footer و placeholders برای content هستند.


ویژگی‌های Layouts:


  • Template inheritance با <code>@extends</code>
  • Sections با <code>@section</code> و <code>@yield</code>
  • Default content با <code>@section</code> و <code>@parent</code>
  • Stacks برای جمع‌آوری content
  • Components برای reusable elements

Slots:


Slots در Components استفاده می‌شوند و به شما امکان می‌دهند dynamic content را به component pass کنید.


انواع Slots:


  • <strong>Default Slot</strong>: محتوای اصلی component
  • <strong>Named Slots</strong>: slotهای با نام‌های مختلف
  • <strong>Scoped Slots</strong>: slotهایی که به parent data دسترسی دارند

مزایا:


  • استفاده مجدد از structure
  • کد تمیزتر و organized‌تر
  • مدیریت بهتر layouts
  • Flexibility در content placement

مثال‌ها

Layout

<!DOCTYPE html>
<html>
<head>
    <title>@yield('title', 'Default Title')</title>
    @stack('styles')
</head>
<body>
    <nav>Navigation</nav>
    
    <main>
        @yield('content')
    </main>
    
    <footer>Footer</footer>
    
    @stack('scripts')
</body>
</html>

یک layout ساده که sectionها را yield می‌کند.

Using Layout

@extends('layouts.app')

@section('title', 'Users')

@section('content')
    <h1>Users</h1>
    @foreach($users as $user)
        <p>{{ $user->name }}</p>
    @endforeach
@endsection

@push('scripts')
    <script src="/js/users.js"></script>
@endpush

استفاده از layout و تعریف sectionها.

Component Slots

<!-- resources/views/components/card.blade.php -->
<div class="card">
    @if(isset($header))
        <div class="card-header">
            {{ $header }}
        </div>
    @endif
    
    <div class="card-body">
        {{ $slot }}
    </div>
    
    @if(isset($footer))
        <div class="card-footer">
            {{ $footer }}
        </div>
    @endif
</div>

<!-- Usage -->
<x-card>
    <x-slot name="header">
        <h2>Title</h2>
    </x-slot>
    
    Content here
    
    <x-slot name="footer">
        <button>Action</button>
    </x-slot>
</x-card>

استفاده از named slots در کامپوننت.

Section با Default Content

<!-- Layout -->
<div class="sidebar">
    @yield('sidebar', 'Default sidebar content')
</div>

<!-- Or with @section and @parent -->
@section('sidebar')
    @parent
    <p>Additional sidebar content</p>
@endsection

Section با default content یا append کردن به parent.

Stacks

<!-- In layout -->
<head>
    @stack('styles')
</head>
<body>
    @stack('scripts')
</body>

<!-- In view -->
@push('styles')
    <link rel="stylesheet" href="/css/custom.css">
@endpush

@prepend('styles')
    <link rel="stylesheet" href="/css/base.css">
@endprepend

@push('scripts')
    <script src="/js/app.js"></script>
@endpush

استفاده از stacks برای جمع‌آوری content از چند view.

Nested Layouts

<!-- layouts/admin.blade.php -->
@extends('layouts.app')

@section('content')
    <div class="admin-layout">
        <aside>Admin Sidebar</aside>
        <main>@yield('admin-content')</main>
    </div>
@endsection

<!-- views/admin/users.blade.php -->
@extends('layouts.admin')

@section('admin-content')
    <h1>Users</h1>
@endsection

Nested layouts برای complex structures.

Scoped Slots

<!-- Component -->
@foreach($items as $item)
    <div class="item">
        {{ $slot($item) }}
    </div>
@endforeach

<!-- Usage -->
<x-item-list :items="$users">
    <x-slot :item="$item">
        <p>{{ $item->name }}</p>
        <span>{{ $item->email }}</span>
    </x-slot>
</x-item-list>

Scoped slots که به parent data دسترسی دارند.

Layout Components

<!-- Using component as layout -->
<x-layout title="Users">
    <x-slot name="header">
        <h1>User Management</h1>
    </x-slot>
    
    <x-slot name="content">
        <p>User list here</p>
    </x-slot>
</x-layout>

<!-- Component definition -->
<!DOCTYPE html>
<html>
<head>
    <title>{{ $title }}</title>
</head>
<body>
    {{ $header }}
    {{ $content }}
</body>
</html>

استفاده از component به عنوان layout.

موارد استفاده

  • ایجاد consistent page structure
  • استفاده مجدد از layouts در چند view
  • مدیریت navigation و footer
  • جمع‌آوری scripts و styles از چند view
  • ایجاد nested structures
  • Dynamic content placement

اشتباهات رایج

  • فراموش کردن @endsection که باعث syntax error می‌شود
  • Nested layouts که باعث complexity می‌شود
  • استفاده از @include به جای @extends
  • فراموش کردن @parent که باعث override شدن content می‌شود
  • Stacks با نام‌های duplicate
  • Slots با نام‌های اشتباه

بهترین روش‌ها

  • از layouts برای page structure استفاده کنید
  • از sections برای content areas استفاده کنید
  • از stacks برای scripts و styles استفاده کنید
  • از slots برای component content استفاده کنید
  • از @parent برای append کردن content استفاده کنید
  • Layout names را descriptive انتخاب کنید
  • از nested layouts با احتیاط استفاده کنید

موارد خاص

  • Nested layouts با multiple levels
  • Stacks با multiple pushes
  • Slots با conditional rendering
  • Layout inheritance با conflicts
  • Dynamic layout selection
  • Layouts با very large content

نکات عملکرد

  • Layout inheritance overhead کم است
  • Stacks می‌توانند performance را بهبود دهند
  • Nested layouts می‌توانند slow باشند
  • Layout caching در production بهبود performance می‌دهد
  • استفاده از @include می‌تواند overhead داشته باشد

نکات امنیتی

  • مطمئن شوید که content در sections escaped می‌شود
  • از raw output در slots با احتیاط استفاده کنید
  • مطمئن شوید که user input در layouts validated می‌شود

نکات مصاحبه

  • تفاوت بین @extends و @include چیست؟
  • Sections و Slots چه تفاوتی دارند؟
  • Stacks چیست و چه زمانی استفاده می‌شود؟
  • @parent چه کاری انجام می‌دهد؟
  • چگونه می‌توان nested layouts ایجاد کرد؟
  • مزایای استفاده از layouts چیست؟

یادداشت‌های نسخه

  • Laravel 11.x: بهبود performance در layout rendering
  • Laravel 11.x: پشتیبانی بهتر از scoped slots
  • Laravel 10.x: بهبود stacks mechanism
  • Laravel 9.x: بهبود layout inheritance