پرش به مطلب اصلی

Blade Layout

Blade Layout ساختار اصلی صفحات پنل را به‌صورت متمرکز و یکپارچه مدیریت می‌کند. اجزایی مانند Header، Sidebar، Footer و سایر بخش‌های ثابت تنها یک‌بار تعریف شده و در تمام صفحات به‌صورت خودکار بارگذاری می‌شوند.

این رویکرد باعث می‌شود:

  • صفحات پنل ساختار یکسان و قابل پیش‌بینی داشته باشند
  • توسعه و نگهداری Viewها ساده‌تر شود
  • Generatorها به‌صورت شفاف بین Backend و Frontend مدیریت شوند

ساختار کلی

Blade Layout از دو بخش اصلی تشکیل شده است:

1. کامپوننت <x-default-layout>

این کامپوننت اسکلت اصلی صفحه را فراهم می‌کند و شامل موارد زیر است:

  • Header
  • Sidebar
  • Footer
  • ناحیه محتوای اصلی

2. Facade کلاس BladeLayout

Facade BladeLayout مسئول مدیریت Generatorها، داده‌ها، تنظیمات ظاهری و اجزای پویا در سطح صفحه است.


استفاده در View

<x-default-layout>

{{-- Page Content --}}

</x-default-layout>

استفاده از <x-default-layout> در تمام صفحات پنل الزامی است. در غیر این صورت، اجزای اصلی صفحه بارگذاری نخواهند شد.


مدیریت Generatorها

تعریف Generator

Table Generator
BladeLayout::table(\App\Generators\Tables\BankTable::class);
Tab Generator
BladeLayout::tab(\App\Generators\Tabs\BankTab::class);
Section Generator
BladeLayout::section(\App\Generators\Sections\BankSection::class);
Banner Generator
BladeLayout::banner(\App\Generators\Banners\BankBanner::class);
Filter Generator
BladeLayout::filter(\App\Generators\Filters\BankFilter::class);

بررسی وجود Generator

بررسی وجود Generator خاص
BladeLayout::exists('table');
بررسی مستقیم Generator
$hasTable = BladeLayout::table() !== false;
$hasTab = BladeLayout::tab() !== false;

استفاده در Blade

Render دستی Generator
<x-default-layout>
{!! bladeLayout()->table()->render() !!}
</x-default-layout>

سفارشی‌سازی Generatorهای پکیج

بعضی Generatorهای پکیج (مثل UserSection، UserBanner و UserTable) را می‌توان بدون کپی کردن کل کلاس، extend کرد و آیتم‌های جدید به آن‌ها افزود یا ترتیب نمایش را تغییر داد.

۱. ساخت کلاس Extend‌شده

کلاس پکیج را extend کنید و متد extensionDefinitions() را override کنید:

app/Generators/UserManagement/ExtendedUserSection.php
use Dornica\PanelKit\Generator\GeneratorDefinition;
use Dornica\PanelKit\Generator\Section\Builders\Section;
use Dornica\UserManagement\Generators\Sections\UserSection;

class ExtendedUserSection extends UserSection
{
protected function extensionDefinitions(): array
{
return [
'sections' => [
GeneratorDefinition::make(
Section::make('section_activity_log')
->label('Activity Log')
->icon('fa-regular fa-clock-rotate-left')
->routeName('admin.management.activity-log')
)
->key('section_activity_log')
->after('section_notes'),
],
];
}
}
app/Generators/UserManagement/ExtendedUserBanner.php
use Dornica\PanelKit\Generator\Banner\Builders\Banner;
use Dornica\PanelKit\Generator\GeneratorDefinition;
use Dornica\UserManagement\Generators\Banners\UserBanner;

class ExtendedUserBanner extends UserBanner
{
protected function extensionDefinitions(): array
{
return [
'items' => [
GeneratorDefinition::make(
Banner::make()
->key('last_login_at')
->label('Last Login')
->value('<span dir="ltr">' . now()->format('Y/m/d , H:i:s') . '</span>')
->icon('fa-regular fa-right-to-bracket')
)
->key('last_login_at')
->after('updated_at'),
],
];
}
}
app/Generators/UserManagement/ExtendedUserTable.php
use Dornica\PanelKit\Generator\GeneratorDefinition;
use Dornica\UserManagement\Generators\Tables\User\UserTable;

class ExtendedUserTable extends UserTable
{
protected function extensionDefinitions(): array
{
return [
'columns' => [
GeneratorDefinition::make(function (self $table): void {
$table->addColumn(
name: 'email',
label: 'Email',
generatorKey: 'email',
);
})
->key('email')
->before('status'),
],
'columnActions' => [
GeneratorDefinition::make(function (self $table): void {
$table->addColumnAction(
type: 'link',
title: __('panel-kit::general.show'),
target: fn ($entity) => route(
generateUserManagementRouteName('management.show'),
['user' => encryptValue($entity->id)]
),
generatorKey: 'show',
);
})
->key('show')
->before('edit'),
],
];
}
}

۲. معرفی کلاس‌ها از طریق Config

در User Management، Controllerها کلاس‌های Banner / Section / Table را از config می‌خوانند. بنابراین کافی است کلاس extend‌شده را در config/dornica-user-management.php معرفی کنید:

config/dornica-user-management.php
'user_section_class' => \App\Generators\UserManagement\ExtendedUserSection::class,
'user_banner_class' => \App\Generators\UserManagement\ExtendedUserBanner::class,
'user_table_class' => \App\Generators\UserManagement\ExtendedUserTable::class,

مقادیر پیش‌فرض پکیج:

کلیدپیش‌فرض
user_section_classUserSection::class
user_banner_classUserBanner::class
user_table_classUserTable::class

گروه‌های قابل Extend

Generatorگروه‌های extensionDefinitions()
Sectionsections
Banneritems, actionButtons, titleSuffixes, titlePrefixes
Tablecolumns, columnActions, filters, toolbar, bulkOperations

کنترل ترتیب با GeneratorDefinition

متدکاربرد
GeneratorDefinition::make($item)افزودن یا جایگزینی آیتم
->key('stable_id')شناسه پایدار برای merge / remove / placement
->after('other_key')قرار دادن بعد از آیتم دیگر
->before('other_key')قرار دادن قبل از آیتم دیگر
نکته مهم برای Table

برای اینکه before() / after() روی Table کار کنند، مقدار GeneratorDefinition::key() باید با generatorKey همان ستون یا action یکی باشد.


مدیریت داده‌ها

ارسال داده به همه Generatorها

BladeLayout::data([
'provinces' => Province::all(),
'cities' => City::all(),
'user' => Auth::user(),
]);

ارسال داده با کلید مشخص

BladeLayout::data('settings', $settings);
BladeLayout::data('page_title', 'مدیریت بانک‌ها');

دریافت داده

$data = BladeLayout::data();
$provinces = BladeLayout::data('provinces');

استفاده در Generator

class BankBanner extends BaseBanner
{
public function configure(): void
{
$provinces = $this->provinces->pluck('name', 'id');
$cities = $this->cities->pluck('name', 'id');
$userName = $this->user->name;
}
}

مدیریت فیلترهای جدول

در برخی سناریوها نیاز است فیلترهای جدول بدون تعامل کاربر تنظیم یا پاک‌سازی شوند. متدهای زیر این امکان را فراهم می‌کنند و داده‌ها را دقیقاً مشابه UI در سشن table_generator ذخیره می‌کنند.

تنظیم فیلترها

BladeLayout::setTableFilters(
table: \App\Generators\Tables\BankTable::class,
routeName: 'admin.banks.index',
filters: [
'filter_name' => 'بانک ملی',
'filter_status_select' => 1,
'filter_types_multi' => [1, 2, 3],
'filter_is_active' => true,
'filter_amount' => 5_000_000,
'filter_created_at' => '1404/09/02 14:30',
'filter_date_range_from' => '1404/09/01',
'filter_date_range_to' => '1404/09/05',
]
);

نکات مهم

  • ساختار filters باید دقیقاً مشابه خروجی فرم UI باشد
  • رمزنگاری مقادیر select و multiselect به‌صورت خودکار انجام می‌شود
  • برای فیلترهای بازه‌ای استفاده از from_ و to_ الزامی است
  • استفاده از routeName برای جلوگیری از تداخل فیلترها توصیه می‌شود

پاک‌سازی فیلترها

BladeLayout::clearTableFilters(
table: \App\Generators\Tables\BankTable::class,
routeName: 'admin.banks.index'
);

Bladeهای اضافی

با استفاده از متد addAdditionalBlades می‌توانید Bladeهای اضافی را به صفحه اضافه کنید. این Bladeها در تمام صفحات پنل بارگذاری می‌شوند و برای افزودن اجزای ثابت یا مشترک بین صفحات مفید هستند.

BladeLayout::addAdditionalBlades('components.custom-sidebar');
BladeLayout::addAdditionalBlades([
'components.custom-header',
'components.notifications',
'modals.quick-actions',
]);
BladeLayout::clearAdditionalBlades();

مدیریت Navbar

Badge ها

در صورت نیاز می‌توانید Badgeهای سفارشی را به Navbar اضافه کنید. این Badgeها در تمام صفحات پنل نمایش داده می‌شوند و برای نمایش اطلاعات پویا یا وضعیت‌های خاص مفید هستند.

تعریف به صورت دسته‌ای
BladeLayout::navbarBadges()
->addMany([
Badge::make()
->value('new')
->icon('fa-regular fa-award')
->variant('danger'),

Badge::make()
->value('deprecated')
->icon('fa-regular fa-award')
->variant('warning'),

Badge::make()
->appearance('light')
->value('new')
->size('lg')
->icon('fa-regular fa-award')
->value('امتیاز من: 7691.2365')
->variant('warning'),

Badge::make()
->appearance('light')
->value('new')
->size('lg')
->icon('fa-regular fa-award')
->value('امتیاز من: 7691.2365')
->variant('info'),
]);
تعریف تکی
BladeLayout::navbarBadges()
->add(
id: 'messages',
label: fn () => Auth::user()->unreadMessages()->count(),
tooltip: 'پیام‌های جدید'
);

زیرعنوان منوی کاربر

در زیر منوی کاربر در Navbar، یک زیرعنوان نمایش داده می‌شود که معمولاً برای نمایش اطلاعات اضافی یا وضعیت کاربر استفاده می‌شود. این زیرعنوان به‌صورت پویا قابل تنظیم است و می‌تواند اطلاعاتی مانند نقش کاربر، آخرین ورود یا هر متن دلخواه دیگری را نمایش دهد.

تنظیم زیرعنوان ثابت
BladeLayout::navbarUserMenuSubtitleManager()->set('کاربر: مدیر سیستم');
تنظیم زیرعنوان پویا با Closure
BladeLayout::navbarUserMenuSubtitleManager()->set(
fn () => 'آخرین ورود: ' . verta(Auth::user()->last_login)->format('Y/m/d H:i')
);

نکات مهم

الزامات

  1. استفاده از <x-default-layout> الزامی است
  2. هر Generator فقط یک‌بار در هر صفحه تعریف شود
  3. تعریف Generatorها باید در Controller انجام شود

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

  • ارسال داده‌های مشترک از طریق متد data
  • استفاده از Route Name در فیلترها
  • استفاده از Closure برای داده‌های پویا
  • برای سفارشی‌سازی User Management، کلاس extend‌شده را در config/dornica-user-management.php معرفی کنید تا نیازی به override کردن Controller نباشد

نکات فنی

  • فیلترها در سشن table_generator ذخیره می‌شوند
  • مقادیر select به‌صورت خودکار رمزنگاری می‌شوند
  • Bladeهای اضافی باید مسیر نسبی از پوشه views داشته باشند
  • Generatorها برای بهبود عملکرد در Container نگه‌داری می‌شوند
  • کلیدهای user_section_class، user_banner_class و user_table_class تعیین می‌کنند BladeLayout کدام کلاس را برای صفحات User Management بارگذاری کند