Система View Pages
Flute CMS предоставляет мощную систему view pages, которая автоматически регистрирует маршруты для Blade шаблонов, размещенных в директории Resources/pages/ вашего модуля. Эта система устраняет необходимость ручного определения маршрутов для простых страниц и обеспечивает автоматическую генерацию URL.
Базовый префикс маршрутов определяется именем модуля в kebab-case (например, Blog → /blog). Метод loadViewPages() вызывается внутри bootstrapModule().
Как работают View Pages
Когда вы вызываете loadViewPages() или bootstrapModule() в вашем провайдере модуля, система автоматически:
Сканирование директории
Сканирует директорию Resources/pages/ модуля.
Регистрация маршрутов
Регистрирует маршруты для всех файлов .blade.php.
Вложенные директории
Поддерживает вложенные директории для организованной маршрутизации.
Преобразование имен
Использует преобразование kebab-case для префиксов маршрутов.
Структура директорий и отображение маршрутов
- index.blade.php
- about.blade.php
- contact.blade.php
- index.blade.php
- create.blade.php
Отображение файлов в URL:
| Файл | URL |
|---|---|
index.blade.php | /your-module |
about.blade.php | /your-module/about |
contact.blade.php | /your-module/contact |
blog/index.blade.php | /your-module/blog |
blog/create.blade.php | /your-module/blog/create |
blog/categories/index.blade.php | /your-module/blog/categories |
blog/tags/index.blade.php | /your-module/blog/tags |
blog/tags/show.blade.php | /your-module/blog/tags/show |
Настройка View Pages
Конфигурация провайдера
<?php
namespace Flute\Modules\YourModule\Providers;
use Flute\Core\Support\ModuleServiceProvider;
class YourModuleProvider extends ModuleServiceProvider
{
public function boot(\DI\Container $container): void
{
// Автоматическая настройка - вызывает loadViewPages() внутри
$this->bootstrapModule();
// Загрузка пространства имен представлений для компонентов и макетов
$this->loadViews('Resources/views', 'yourmodule');
}
}Ручная настройка (при необходимости)
<?php
class YourModuleProvider extends ModuleServiceProvider
{
public function boot(\DI\Container $container): void
{
// Сначала загрузите пространство имен представлений
$this->loadViews('Resources/views', 'yourmodule');
// Явно загрузите view pages
$this->loadViewPages();
// Другие ресурсы модуля
$this->loadTranslations();
$this->loadScss('Resources/assets/scss/main.scss');
}
}Создание шаблонов страниц
Базовый шаблон страницы
{{-- Resources/pages/index.blade.php --}}
@extends('flute::layouts.app')
@section('title', __('yourmodule.home_title'))
@section('content')
<div class="container">
<div class="hero-section">
<h1>{{ __('yourmodule.welcome_message') }}</h1>
<p class="lead">{{ __('yourmodule.description') }}</p>
</div>
</div>
@endsectionВложенный шаблон страницы
{{-- Resources/pages/blog/index.blade.php --}}
@extends('flute::layouts.app')
@section('title', __('blog.articles'))
@section('content')
<div class="container">
<div class="blog-header">
<h1>{{ __('blog.latest_articles') }}</h1>
</div>
<div class="articles-grid">
@foreach($articles ?? [] as $article)
<article class="article-card">
<h3>{{ $article->title }}</h3>
<p>{{ $article->excerpt }}</p>
</article>
@endforeach
</div>
</div>
@endsectionСтраница с динамическим контентом
{{-- Resources/pages/blog/show.blade.php --}}
@extends('flute::layouts.app')
@section('title', $article->title ?? __('blog.article'))
@section('content')
<div class="container">
@if($article)
<article class="blog-post">
<header class="post-header">
<h1>{{ $article->title }}</h1>
<div class="post-meta">
<span>{{ __('blog.by') }} {{ $article->author->name }}</span>
<span>{{ $article->created_at->format('M j, Y') }}</span>
</div>
</header>
<div class="post-content">
{!! $article->content !!}
</div>
</article>
@else
<div class="error-page">
<h1>{{ __('blog.article_not_found') }}</h1>
</div>
@endif
</div>
@endsectionРеальные примеры из существующих модулей
Реализация модуля News
Модуль News использует view pages в своей структуре:
- index.blade.php
- view.blade.php
- view.blade.php
Провайдер News:
<?php
namespace Flute\Modules\News\Providers;
use Flute\Core\Support\ModuleServiceProvider;
class NewsProvider extends ModuleServiceProvider
{
public function boot(\DI\Container $container): void
{
$this->bootstrapModule(); // включает loadViewPages()
$this->loadViews('Resources/views', 'news');
$this->loadScss('Resources/assets/scss/news.scss');
}
}Главная страница новостей:
{{-- app/Modules/News/Resources/pages/news/index.blade.php --}}
@extends('flute::layouts.app')
@push('content')
<div class="container">
<div class="news-page" hx-boost="true" hx-target="#main" hx-swap="outerHTML transition:true">
<header class="news-page-header">
<h1>Новости</h1>
<p class="news-page-subtitle">Актуальные материалы о технологиях, науке и разработке</p>
</header>
<div class="news-list-grid">
@for ($i = 0; $i < 8; $i++)
<a href="{{ url('/news/view') }}" class="news-card">
<div class="news-card-image" aria-hidden="true"></div>
<div class="news-card-content">
<span class="news-chip">Технологии</span>
<h3>Новые технологии в веб‑разработке 2024</h3>
<p>Краткий обзор перспективных фреймворков и инструментов.</p>
<div class="news-meta">
<span class="news-author">
<x-icon path="ph.regular.user" /> Иван Петров
</span>
<span class="news-time">
<x-icon path="ph.regular.clock" /> 5 мин
</span>
<span class="news-date">
<x-icon path="ph.regular.calendar" /> 15.01.2024
</span>
</div>
</div>
</a>
@endfor
</div>
</div>
</div>
@endpushРеализация модуля FAQ
Модуль FAQ использует view pages для отображения виджетов:
- faq.blade.php
- settings.blade.php
Провайдер FAQ:
<?php
namespace Flute\Modules\FAQ\Providers;
use Flute\Core\Support\ModuleServiceProvider;
class FAQProvider extends ModuleServiceProvider
{
public function boot(\DI\Container $container): void
{
$this->bootstrapModule(); // Автоматически загружает view pages
$this->loadViews('Resources/views', 'faq');
$this->loadScss('Resources/assets/scss/faq.scss');
}
}Полный пример модуля
Вот полный пример модуля Blog, использующего view pages:
Структура модуля
- module.json
- index.blade.php
- create.blade.php
Реализация провайдера
<?php
namespace Flute\Modules\Blog\Providers;
use Flute\Core\Support\ModuleServiceProvider;
class BlogProvider extends ModuleServiceProvider
{
public function boot(\DI\Container $container): void
{
// Это включает view pages автоматически
$this->bootstrapModule();
// Загрузка дополнительного пространства имен представлений
$this->loadViews('Resources/views', 'blog');
// Загрузка стилей
$this->loadScss('Resources/assets/scss/blog.scss');
}
}Шаблоны страниц
Главная страница блога:
{{-- Resources/pages/index.blade.php --}}
@extends('flute::layouts.app')
@section('title', __('blog.articles'))
@section('content')
<div class="blog-container">
<div class="blog-header">
<h1>{{ __('blog.latest_articles') }}</h1>
<p>{{ __('blog.discover_content') }}</p>
</div>
<div class="articles-grid">
@foreach($articles ?? [] as $article)
<article class="article-card">
<h3>{{ $article->title }}</h3>
<p>{{ $article->excerpt }}</p>
<a href="{{ route('blog.show', ['id' => $article->id]) }}">
{{ __('blog.read_more') }}
</a>
</article>
@endforeach
</div>
</div>
@endsectionСтраница категорий:
{{-- Resources/pages/categories/index.blade.php --}}
@extends('flute::layouts.app')
@section('title', __('blog.categories'))
@section('content')
<div class="categories-container">
<h1>{{ __('blog.all_categories') }}</h1>
<div class="categories-grid">
@foreach($categories ?? [] as $category)
<div class="category-card">
<h3>{{ $category->name }}</h3>
<p>{{ $category->description }}</p>
<span class="article-count">
{{ $category->articles_count }} {{ __('blog.articles') }}
</span>
</div>
@endforeach
</div>
</div>
@endsectionЛучшие практики
1. Организация директорий
- Используйте понятные, описательные имена директорий
- Группируйте связанные страницы в поддиректориях
- Держите структуру максимально плоской
2. Структура шаблонов
- Всегда наследуйтесь от базового макета
- Используйте правильную организацию секций
- Включайте осмысленные заголовки страниц
3. Именование маршрутов
- Имена файлов становятся сегментами URL
- Используйте kebab-case для многословных файлов
- Держите URL чистыми и SEO-дружественными
4. Управление контентом
- Используйте функции перевода для всего текста
- Элегантно обрабатывайте отсутствующие данные
- Предоставляйте резервный контент
Преимущества системы View Pages
Основные преимущества:
- Автоматическая маршрутизация — не нужно вручную определять маршруты
- Организованная структура — файлы организованы по URL-путям
- SEO-дружественные URL — автоматическое преобразование в kebab-case
- Вложенность — поддержка любой глубины вложенности директорий
- Простота — просто создайте Blade шаблон и он станет страницей
Итоги
Система view pages предоставляет простой и эффективный способ создания страниц в Flute CMS без ручного определения маршрутов. Просто создайте Blade шаблоны в директории Resources/pages/ и они автоматически станут доступными URL!
Ключевые моменты:
- Файлы в
Resources/pages/автоматически становятся маршрутами - Имя модуля преобразуется в префикс URL (kebab-case)
index.blade.phpстановится корневым маршрутом директории- Вложенные директории создают вложенные URL-пути
bootstrapModule()автоматически загружает view pages