Skip to content

Architecture Overview

Filament CMS is built from focused packages that work together to provide a complete content management and visual editing experience.

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 provides:

  • 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
  • ContentResolver — Transforms database JSON into typed objects
  • SectionContent — Container for resolved blocks with magic property access
  • BlockData / NullBlockData — Wrapper for individual block data
  • 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:

  • Page — Abstract Livewire component for frontend pages
  • SectionComponent — Abstract base for all frontend sections
  • Intro — Example concrete section component
  • 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:

  • 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(), and refreshFromCMS() for section components that want inline editing
  • HasFieldLabels — Optional interface for localized field labels
  • CmsSourceMap — Immutable value object tracing HTML elements back to database records
  • EditingMode — Session-based state manager for editing mode
  • 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
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
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"]

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-core alone 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
  1. Separation of Concerns — Content structure (blocks) is separate from presentation (Livewire components)
  2. Content Provenance — Every rendered element knows its database origin via source maps
  3. Package Modularity — Core, frontend, and visual editing are independent packages
  4. Convention over Configuration — Section slugs match component class names, block types match Block::make() names