Skip to Content
ModulesView Pages

View Pages System

Flute CMS provides a powerful view pages system that automatically registers routes for Blade templates placed in the Resources/pages/ directory of your module. This system eliminates the need for manually defining routes for simple pages and ensures automatic URL generation.

The base route prefix is determined by the module name in kebab-case (e.g., Blog/blog). The loadViewPages() method is called inside bootstrapModule().

How View Pages Work

When you call loadViewPages() or bootstrapModule() in your module provider, the system automatically:

Directory Scanning

Scans the Resources/pages/ directory of the module.

Route Registration

Registers routes for all .blade.php files.

Nested Directories

Supports nested directories for organized routing.

Name Conversion

Uses kebab-case conversion for route prefixes.

Directory Structure and Route Mapping

    • index.blade.php
    • about.blade.php
    • contact.blade.php
      • index.blade.php
      • create.blade.php

File to URL Mapping:

FileURL
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

Configuring View Pages

Provider Configuration

<?php namespace Flute\Modules\YourModule\Providers; use Flute\Core\Support\ModuleServiceProvider; class YourModuleProvider extends ModuleServiceProvider { public function boot(\DI\Container $container): void { // Automatic setup - calls loadViewPages() internally $this->bootstrapModule(); // Load view namespace for components and layouts $this->loadViews('Resources/views', 'yourmodule'); } }

Manual Setup (if needed)

<?php class YourModuleProvider extends ModuleServiceProvider { public function boot(\DI\Container $container): void { // First load view namespace $this->loadViews('Resources/views', 'yourmodule'); // Explicitly load view pages $this->loadViewPages(); // Other module resources $this->loadTranslations(); $this->loadScss('Resources/assets/scss/main.scss'); } }

Creating Page Templates

Basic Page Template

{{-- 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

Nested Page Template

{{-- 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

Page with Dynamic Content

{{-- 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

Real World Examples from Existing Modules

News Module Implementation

The News module uses view pages in its structure:

      • index.blade.php
      • view.blade.php
    • view.blade.php

News Provider:

<?php namespace Flute\Modules\News\Providers; use Flute\Core\Support\ModuleServiceProvider; class NewsProvider extends ModuleServiceProvider { public function boot(\DI\Container $container): void { $this->bootstrapModule(); // includes loadViewPages() $this->loadViews('Resources/views', 'news'); $this->loadScss('Resources/assets/scss/news.scss'); } }

News Index Page:

{{-- 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>News</h1> <p class="news-page-subtitle">Latest materials about technology, science, and development</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">Technology</span> <h3>New Technologies in Web Development 2024</h3> <p>Brief overview of promising frameworks and tools.</p> <div class="news-meta"> <span class="news-author"> <x-icon path="ph.regular.user" /> Ivan Petrov </span> <span class="news-time"> <x-icon path="ph.regular.clock" /> 5 min </span> <span class="news-date"> <x-icon path="ph.regular.calendar" /> 15.01.2024 </span> </div> </div> </a> @endfor </div> </div> </div> @endpush

FAQ Module Implementation

The FAQ module uses view pages to display widgets:

    • faq.blade.php
    • settings.blade.php

FAQ Provider:

<?php namespace Flute\Modules\FAQ\Providers; use Flute\Core\Support\ModuleServiceProvider; class FAQProvider extends ModuleServiceProvider { public function boot(\DI\Container $container): void { $this->bootstrapModule(); // Automatically loads view pages $this->loadViews('Resources/views', 'faq'); $this->loadScss('Resources/assets/scss/faq.scss'); } }

Full Module Example

Here is a complete example of a Blog module using view pages:

Module Structure

    • module.json
        • index.blade.php
        • create.blade.php

Provider Implementation

<?php namespace Flute\Modules\Blog\Providers; use Flute\Core\Support\ModuleServiceProvider; class BlogProvider extends ModuleServiceProvider { public function boot(\DI\Container $container): void { // This enables view pages automatically $this->bootstrapModule(); // Load additional view namespace $this->loadViews('Resources/views', 'blog'); // Load styles $this->loadScss('Resources/assets/scss/blog.scss'); } }

Page Templates

Blog Index Page:

{{-- 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

Categories Page:

{{-- 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

Best Practices

1. Directory Organization

  • Use clear, descriptive directory names
  • Group related pages in subdirectories
  • Keep structure as flat as possible

2. Template Structure

  • Always extend a base layout
  • Use proper section organization
  • Include meaningful page titles

3. Route Naming

  • Filenames become URL segments
  • Use kebab-case for multi-word files
  • Keep URLs clean and SEO-friendly

4. Content Management

  • Use translation functions for all text
  • Handle missing data gracefully
  • Provide fallback content

Advantages of View Pages System

Key Benefits:

  • Automatic Routing — no need to manually define routes
  • Organized Structure — files organized by URL paths
  • SEO-Friendly URLs — automatic conversion to kebab-case
  • Nesting — support for any depth of directory nesting
  • Simplicity — just create a Blade template and it becomes a page

Summary

The view pages system provides a simple and effective way to create pages in Flute CMS without manually defining routes. Simply create Blade templates in the Resources/pages/ directory and they automatically become accessible URLs!

Key Points:

  1. Files in Resources/pages/ automatically become routes
  2. Module name is converted to URL prefix (kebab-case)
  3. index.blade.php becomes the root route of the directory
  4. Nested directories create nested URL paths
  5. bootstrapModule() automatically loads view pages