Architecture Overview
Filament CMS is built from focused packages that work together to provide a complete content management and visual editing experience.
Package Architecture
Section titled “Package Architecture”graph TD
subgraph "Host Application"
A[Your Laravel App]
B[Livewire Pages]
C[Livewire Sections]
D[Custom Content Blocks]
E[Policies]
end
subgraph CorePackage["franc014/filament-cms-core"]
F[FilamentCMSCorePlugin]
G[PageResource]
H[SectionResource]
I[ContentResolver]
J[SectionContent]
K[BlockData]
L[Models]
end
subgraph LivewirePackage["franc014/filament-cms-livewire"]
P1[Page Livewire Component]
P2[SectionComponent]
P4[Metatags Trait]
P5[Blade Views]
end
subgraph VEPackage["franc014/ve-filament-cms-livewire"]
N[VisualEditor]
O[InlineEditForm]
P3[InteractsWithVisualEditing]
Q[CmsSourceMap]
R[EditingMode]
end
A -->|registers| F
A -.->|via service provider| N
B -->|extends| P1
C -->|extends| P2
D -->|implements| F
C -.->|opt-in| P3
P3 -->|reads| Q
I -->|produces| J
J -->|contains| K
K -->|carries| Q
N -->|opens| O
O -->|updates| L
The Core Package (filament-cms-core)
Section titled “The Core Package (filament-cms-core)”The core package provides:
Content Management
Section titled “Content Management”- Pages, Sections, Posts, Menus, Categories, Components — Full CRUD via Filament resources
- Content Builder — Block-based content editing using Filament’s Builder field
- Media Management — Spatie Media Library integration for images and files
Content Resolution
Section titled “Content Resolution”- ContentResolver — Transforms database JSON into typed objects
- SectionContent — Container for resolved blocks with magic property access
- BlockData / NullBlockData — Wrapper for individual block data
Contracts & Enums
Section titled “Contracts & Enums”- ContentBlock — Interface for defining content blocks
- PageStatus, SectionStatus — Enums for content state
The Livewire Package (filament-cms-livewire)
Section titled “The Livewire Package (filament-cms-livewire)”The Livewire package provides:
Frontend Components
Section titled “Frontend Components”- Page — Abstract Livewire component for frontend pages
- SectionComponent — Abstract base for all frontend sections
- Intro — Example concrete section component
Utilities
Section titled “Utilities”- Metatags — Trait for injecting SEO meta tags from CMS page data
- partials/page — Renders sections dynamically via
@livewire() - partials/head — Renders metatags, OG tags, Twitter cards
The Visual Editing Package (ve-filament-cms-livewire)
Section titled “The Visual Editing Package (ve-filament-cms-livewire)”The visual editing package provides:
Frontend Editing
Section titled “Frontend Editing”- VisualEditor — Floating UI that toggles editing mode and manages the slide-over panel
- InlineEditForm — Dynamic form inside the panel that loads and saves section content
- InteractsWithVisualEditing — Opt-in trait providing
renderField(),renderImageField(),renderRepeaterContainer(), andrefreshFromCMS()for section components that want inline editing - HasFieldLabels — Optional interface for localized field labels
Content Provenance
Section titled “Content Provenance”- CmsSourceMap — Immutable value object tracing HTML elements back to database records
- EditingMode — Session-based state manager for editing mode
Supporting Services
Section titled “Supporting Services”- ImageUploadHandler — Moves uploaded images from temp to permanent storage
- RepeaterSchemaBuilder — Dynamically builds repeater form schemas from block definitions
- InitializeEditingMode — Middleware ensuring editing state is available
Data Flow
Section titled “Data Flow”sequenceDiagram
participant DB as Database
participant CR as ContentResolver
participant SC as SectionContent
participant BD as BlockData
participant LC as Livewire Component
participant VE as VisualEditor
DB->>CR: JSON content
CR->>SC: Resolve blocks by type
SC->>BD: Wrap each block
BD->>BD: Attach source map
SC->>LC: Pass to mount()
LC->>LC: hydrateFromContent()
LC->>VE: Render with data-cms-source
VE->>LC: contentUpdated event
LC->>CR: Re-resolve
Three-Tier Content Architecture
Section titled “Three-Tier Content Architecture”graph TD
Page["Page (slug: 'about')"] -->|page_section pivot| Section1["Section (slug: 'hero')"]
Page -->|page_section pivot| Section2["Section (slug: 'mission')"]
Page -->|page_section pivot| Section3["Section (slug: 'team')"]
Section1 -->|content JSON| Block1["BlockData: type='hero'"]
Section2 -->|content JSON| Block2["BlockData: type='mission'"]
Section3 -->|content JSON| Block3["BlockData: type='team'"]
Block1 -->|rendered by| Comp1["App\\Livewire\\Hero"]
Block2 -->|rendered by| Comp2["App\\Livewire\\Mission"]
Block3 -->|rendered by| Comp3["App\\Livewire\\Team"]
Why Separate Packages?
Section titled “Why Separate Packages?”The core package is frontend-agnostic — it provides the admin dashboard and data layer, but knows nothing about how content is rendered on the frontend. This means:
- Livewire projects use
filament-cms-core+filament-cms-livewire - Inertia projects (coming soon) will use
filament-cms-core+filament-cms-inertia - API/headless projects can use
filament-cms-corealone and consume content via Eloquent or API resources
The core package handles:
- Database schema
- Filament resources and forms
- Content resolution
- Media management
The frontend packages handle:
- Page routing and rendering
- Section component lifecycle
- Blade views and layouts
- Visual editing integration
Key Design Principles
Section titled “Key Design Principles”- Separation of Concerns — Content structure (blocks) is separate from presentation (Livewire components)
- Content Provenance — Every rendered element knows its database origin via source maps
- Package Modularity — Core, frontend, and visual editing are independent packages
- Convention over Configuration — Section slugs match component class names, block types match
Block::make()names