This document covers frontend templating, theme customization, and available Blade components for rendering pages, menus and the language switch.
- General remark
- Available Blade Components
- Page Templates
- Styling Integration
- Frontend Best Practices
This package provides only Blade templates. These templates are only a starting point to start implementing your own project requirements. The idea is that the backend is flexible and easily extendable, while the frontend requirements will differ most likely between projects, so they (currently) only provide basic styling.
Publish the package views to customize templates:
php artisan vendor:publish --tag="filament-flexible-content-block-pages-views"This creates the views in:
resources/views/vendor/filament-flexible-content-block-pages/
└── tailwind/
├── components/
│ ├── layouts/
│ │ └── base.blade.php
│ └── menu/
│ ├── default.blade.php
│ └── default-item.blade.php
└── pages/
├── show.blade.php
└── tag_index.blade.php
Base Layout (components/layouts/base.blade.php):
- HTML5 document structure
- SEO meta tags integration
- Responsive viewport setup
- Tailwind CSS integration
Page Template (pages/show.blade.php):
- Page content rendering
- Hero section display
- Content blocks rendering
- SEO structured data
Menu Templates (components/menu/):
- Hierarchical menu rendering
- Active state handling
- Multi-level dropdown support
We provide a basic TailwindCSS theme. But you can create another custom theme.
The package provides several Blade components for common frontend functionality:
Renders hierarchical menus with full customization support:
<x-flexible-pages-menu
code="HEADER"
style="default"
ulClass="flex flex-row justify-start items-center gap-x-4"
itemLinkClass="text-black hover:text-primary hover:underline"
currentItemLinkClass="text-grey hover:no-underline"
childUlClass="absolute top-full left-0 bg-white shadow-lg"
childItemLinkClass="block px-4 py-2 hover:bg-gray-100"
/>Available parameters:
code- Menu code of the menu model (required)style- Menu style template (default: 'default')ulClass- CSS classes for<ul>elementsitemLinkClass- CSS classes for menu item linkscurrentItemLinkClass- CSS classes for active/current page linkschildUlClass- CSS classes for submenu<ul>elementschildItemLinkClass- CSS classes for submenu item linksitemClass- CSS classes for<li>elementschildItemClass- CSS classes for submenu<li>elements
Creating custom menu styles:
- Add the style to your configuration:
// config/filament-flexible-content-block-pages.php
'menu' => [
'styles' => ['default', 'mega', 'sidebar'],
],- Create the corresponding templates and make a custom implementation based on the
defaultexample:
resources/views/vendor/filament-flexible-content-block-pages/tailwind/components/menu/mega.blade.php
resources/views/vendor/filament-flexible-content-block-pages/tailwind/components/menu/mega-item.blade.php
Renders a navigation component with language switching links for multilingual sites:
<x-flexible-pages-language-switch
class="flex gap-2"
/>The current implementation is very basic. Maybe we will add a more advanced component in the future.
Provides a base HTML structure skeleton with SEO meta tags that is used to render the pages. For example, you can implement a custom page like this:
<x-flexible-pages-base-layout>
<header>
<x-flexible-pages-menu code="HEADER" />
<x-flexible-pages-language-switch />
</header>
<main>
<x-flexible-hero :page="$page"/>
<x-flexible-content-blocks :page="$page"/>
</main>
<footer>
<x-flexible-pages-menu code="FOOTER" />
</footer>
</x-flexible-pages-base-layout>A convenience button, which is shown in the actual web application (so not in the filament admin), for page admins to easily navigate to the EditPage admin url of the active page. When enabled AND in case the logged-in user has sufficient permission, this button will appear in the lower-left corner within the default page layout.
1. The edit-page-button component can be included in the page layout (pages/index.blade.php) like this:
<x-flexible-pages-base-layout>
<x-flexible-pages-edit-page-button :page="$page"/>
{{-- other page layout elements like the <header>, <main> and <footer> --}}
</x-flexible-pages-base-layout>2. To enable the edit-page button in the configuration:
// config/filament-flexible-content-block-pages.php
'page_resource' => [
Page::class => [
/*
| Enable or disable the front-end button that will open the current page for editing.
*/
'enable_edit_page_button' => true,
],
],3. Configuring the permission required for a user to be able to see the button:
// config/filament-flexible-content-block-pages.php
'page_resource' => [
Page::class => [
/*
| Authorisation gates for the page resource.
*/
'gates' => [
'edit_page_button' => 'update_page',
],
],
],You can create custom templates for a specific page. You can use the page code to create a mapping in the configuration.
1. Create template file:
{{-- resources/views/pages/product-template.blade.php --}}
<x-flexible-pages-base-layout>
<div class="product-page">
<div class="product-hero">
{{-- Custom product page layout --}}
</div>
<div class="product-content">
{!! $page->renderContentBlocks() !!}
</div>
<div class="product-sidebar">
{{-- Additional product information --}}
</div>
</div>
</x-flexible-pages-base-layout>2. Register in configuration:
// config/filament-flexible-content-block-pages.php
'page_templates' => [
'default' => 'filament-flexible-content-block-pages::tailwind.pages.show',
'product' => 'pages.product-template',
'landing' => 'pages.landing-template',
],NB: product and landing are codes on the Page model.
Ensure Tailwind CSS includes the required package paths in your tailwind.config.js which is used by the front-end.
See tailwind installation steps in the main README.md
Here are some snippets with ideas for frontend optimisations.
Lazy loading:
{{-- Lazy load content blocks --}}
<div class="content-blocks" x-data="{ loaded: false }" x-intersect="loaded = true">
<template x-if="loaded">
{!! $page->renderContentBlocks() !!}
</template>
</div>Semantic HTML:
We have tried to optimise the flexible content block templates for accessibility. But in the page templates, you might still need to pay attention.
<article role="main" aria-labelledby="page-title">
<header>
<h1 id="page-title">{{ $page->getTitle() }}</h1>
@if($page->publishing_begins_at)
<time datetime="{{ $page->publishing_begins_at->toISOString() }}">
{{ $page->publishing_begins_at->format('F j, Y') }}
</time>
@endif
</header>
<main>
{!! $page->renderContentBlocks() !!}
</main>
</article>