| .. | ||
| components | ||
| core | ||
| starter-components | ||
| ARCHITECTURE.md | ||
| CONTRIBUTING.md | ||
| INSTALLATION.md | ||
| LICENSE.md | ||
| README.md | ||
Flux CMS - Laravel Package Suite
🚀 Modern, component-first CMS for Laravel with multi-domain support
Overview
Flux CMS is a powerful, modern Content Management System built specifically for Laravel applications. It features a revolutionary "Code-as-Schema" approach where content structure is defined directly in PHP components, offering unprecedented flexibility and developer experience.
🎯 Key Features
- 🧩 Component-First Architecture - Build pages from reusable Livewire components
- 📝 Code-as-Schema - Define fields in PHP, not in databases
- 🌍 Multi-Domain Support - Manage multiple websites from one installation
- 🗣️ Full Multilingual - Everything is translatable with fallbacks
- 📦 Versioning - Automatic content versioning and rollback
- 🎨 Media Management - Integrated media library with automatic conversions
- ⚡ Performance - Optimized queries and smart caching
- 🔒 Secure - Built-in security best practices
Package Architecture
Flux CMS is split into modular packages for maximum flexibility:
Core Packages
| Package | Description | Installation |
|---|---|---|
| flux-cms/core | Core models, services, and field types | composer require flux-cms/core |
| flux-cms/components | Livewire backend and frontend components | composer require flux-cms/components |
| flux-cms/starter-components | Ready-to-use starter components | composer require flux-cms/starter-components |
Quick Start
1. Installation
# Install core package
composer require flux-cms/core
# Install components (optional but recommended)
composer require flux-cms/components flux-cms/starter-components
# Install and setup
php artisan flux-cms:install
2. Basic Configuration
// config/flux-cms.php
return [
'locales' => [
'de' => 'Deutsch',
'en' => 'English',
],
'component_paths' => [
'App\\Livewire\\Components',
'FluxCms\\StarterComponents\\Components',
],
'domains' => [
'enabled' => true,
'config_source' => 'domains', // Use existing config/domains.php
],
];
3. Create Your First Component
<?php
namespace App\Livewire\Components;
use Livewire\Component;
use FluxCms\Core\FieldTypes\TextField;
use FluxCms\Core\FieldTypes\WysiwygField;
use FluxCms\Core\FieldTypes\MediaField;
class FeatureSection extends Component
{
public array $content = [];
public function mount(array $content = [])
{
$this->content = $content;
}
public static function getCmsName(): string
{
return 'Feature Section';
}
public static function getCmsDescription(): string
{
return 'Showcase features with icons and descriptions';
}
public static function getCmsCategory(): string
{
return 'Content';
}
public static function getCmsFields(): array
{
return [
TextField::make('headline', 'Headline')
->translatable()
->required()
->maxLength(100),
WysiwygField::make('description', 'Description')
->translatable()
->toolbar(['bold', 'italic', 'link']),
MediaField::make('icon', 'Icon')
->images()
->helpText('SVG or PNG icon'),
];
}
public function render()
{
return view('components.feature-section');
}
// Helper methods
protected function getHeadline(?string $locale = null): string
{
$locale = $locale ?? app()->getLocale();
return $this->content['headline'][$locale] ?? '';
}
}
4. Create the Blade Template
{{-- resources/views/components/feature-section.blade.php --}}
<section class="feature-section py-12">
<div class="container mx-auto px-4">
@if($this->getHeadline())
<h2 class="text-3xl font-bold text-center mb-8">
{{ $this->getHeadline() }}
</h2>
@endif
@if($this->getDescription())
<div class="prose prose-lg mx-auto text-center">
{!! $this->getDescription() !!}
</div>
@endif
</div>
</section>
Advanced Usage
Multi-Domain Setup
// Automatic domain detection from existing config/domains.php
$page = Page::forDomain('b2in')->bySlug('/about', 'en')->first();
// Create domain-specific content
$page = Page::create([
'domain_key' => 'b2in',
'title' => ['de' => 'Über uns', 'en' => 'About us'],
'is_published' => true,
]);
$page->slugs()->create(['locale' => 'de', 'slug' => '/ueber-uns']);
$page->slugs()->create(['locale' => 'en', 'slug' => '/about']);
Component Registry
// Get all available components
$registry = app(ComponentRegistry::class);
$components = $registry->getAvailableComponents();
// Search components
$results = $registry->searchComponents('hero');
// Get by category
$layoutComponents = $registry->getComponentsByCategory()['Layout'];
// Validate component content
$errors = $registry->validateComponentContent(HeroSection::class, $content);
Custom Field Types
<?php
namespace App\FieldTypes;
use FluxCms\Core\FieldTypes\BaseField;
class ColorField extends BaseField
{
public function getType(): string
{
return 'color';
}
public function getValidationRules(): array
{
$rules = ['string', 'regex:/^#[0-9A-Fa-f]{6}$/'];
if ($this->required) {
$rules[] = 'required';
}
return $rules;
}
public function toArray(): array
{
return [
'type' => $this->getType(),
'key' => $this->key,
'label' => $this->label,
'translatable' => $this->translatable,
'required' => $this->required,
'default' => $this->default,
];
}
}
Versioning
// Create version before major changes
$page->createVersion('Redesign homepage layout', auth()->id());
// Restore previous version
$version = $page->versions()->first();
$version->restore();
// Compare versions
$differences = $version->getDifferences();
Field Types
Flux CMS includes powerful field types out of the box:
Text Fields
TextField::make('title', 'Title')
->translatable()
->required()
->maxLength(100)
->placeholder('Enter title...');
TextField::make('email', 'Email')
->email()
->required();
TextField::make('website', 'Website')
->url();
Content Fields
WysiwygField::make('content', 'Content')
->translatable()
->toolbar(['bold', 'italic', 'link', 'bulletList'])
->allowImages(true)
->minHeight(300);
Media Fields
MediaField::make('image', 'Image')
->images()
->required();
MediaField::make('gallery', 'Gallery')
->images()
->multiple(true, 10);
MediaField::make('document', 'Document')
->documents()
->maxFileSize(5120); // 5MB
Selection Fields
SelectField::make('layout', 'Layout')
->options([
'left' => 'Image Left',
'right' => 'Image Right',
'center' => 'Centered'
])
->default('left')
->searchable();
Other Fields
NumberField::make('count', 'Count')
->min(1)
->max(100)
->default(5);
BooleanField::make('featured', 'Featured')
->default(false)
->labels('Yes', 'No');
Frontend Integration
Page Controller
<?php
namespace App\Http\Controllers;
use FluxCms\Core\Models\Page;
use Illuminate\Http\Request;
class PageController extends Controller
{
public function show(Request $request, string $slug = '/')
{
$domainKey = $this->getCurrentDomainKey($request);
$locale = app()->getLocale();
$page = Page::forDomain($domainKey)
->bySlugWithFallback($slug)
->published()
->with(['components'])
->firstOrFail();
$components = $page->components()->get();
return view('pages.show', compact('page', 'components'));
}
}
Page Template
{{-- resources/views/pages/show.blade.php --}}
@extends('layouts.app')
@section('title', $page->getSeoTitle())
@section('description', $page->getSeoDescription())
@section('content')
@foreach($components as $component)
@if($component->canRender())
@livewire($component->component_class, [
'content' => $component->getTranslations('content')
], key('component-' . $component->id))
@endif
@endforeach
@endsection
Backend Integration
Admin Routes
// routes/admin.php
Route::middleware(['web', 'auth'])->prefix('admin/cms')->name('admin.cms.')->group(function () {
Route::get('/', [Admin\DashboardController::class, 'index'])->name('index');
Route::resource('pages', Admin\PageController::class)->except(['show']);
// ... other admin routes
});
Admin Controller
<?php
namespace App\Http\Controllers\Admin;
use FluxCms\Core\Models\Page;
use Illuminate\Http\Request;
class PageController extends Controller
{
public function index()
{
$pages = Page::with(['components'])
->orderBy('updated_at', 'desc')
->paginate(20);
return view('admin.cms.pages.index', compact('pages'));
}
public function edit(Page $page)
{
return view('admin.cms.pages.edit', compact('page'));
}
}
Edit Page Template
{{-- resources/views/admin/cms/edit.blade.php --}}
@extends('layouts.admin')
@section('content')
@livewire('flux-cms::page-editor', ['page' => $page])
@endsection
Configuration
Available Locales
// config/flux-cms.php
'locales' => [
'de' => 'Deutsch',
'en' => 'English',
'fr' => 'Français',
'es' => 'Español',
],
Component Paths
'component_paths' => [
'App\\Livewire\\Components',
'App\\CmsComponents',
'FluxCms\\StarterComponents\\Components',
],
Media Configuration
'media' => [
'disk' => 'public',
'max_file_size' => 10240, // 10MB
'conversions' => [
'thumb' => ['width' => 300, 'height' => 300],
'medium' => ['width' => 800, 'height' => 600],
'large' => ['width' => 1200, 'height' => 900],
],
],
Commands
# Install Flux CMS
php artisan flux-cms:install
# Create a new component (in app/Livewire/Web/Components)
php artisan flux-cms:make-component MyNewComponent
# Clear component registry cache
php artisan flux-cms:clear-cache
# Publish package assets
php artisan vendor:publish --tag=flux-cms
Testing
# Run tests from the root of your project
./vendor/bin/pest
Security
- XSS Protection: All user content is sanitized
- CSRF Protection: All forms include CSRF tokens
- File Upload Security: MIME type validation and file scanning
- Permission System: Integration with Spatie Laravel Permission
Performance
- Component Registry Caching: Components are cached for fast lookup
- Eager Loading: Optimized database queries
- Asset Optimization: Automatic image conversions
- Query Caching: Smart caching for frequently accessed data
Upgrade Guide
From Dev Version to Package
- Install packages:
composer require flux-cms/core flux-cms/components flux-cms/starter-components
- Migrate existing components:
# Copy your existing components to app/Livewire/Components/
# Update namespaces and field imports
- Update configuration:
php artisan vendor:publish --tag=flux-cms-config
- Run migrations:
php artisan migrate
Contributing
We welcome contributions! Please see CONTRIBUTING.md for details.
Development Setup
# Clone the repository
git clone https://github.com/flux-cms/flux-cms.git
# Install dependencies
composer install
# Run tests
composer test
# Code style
composer format
License
Flux CMS is open-sourced software licensed under the MIT license.
Support
- 📖 Documentation: https://flux-cms.com/docs
- 💬 Discussions: GitHub Discussions
- 🐛 Issues: GitHub Issues
- 💌 Email: support@flux-cms.com
Acknowledgments
- Built with Laravel
- Powered by Livewire
- Uses Spatie packages
- UI with Flux UI
Made with ❤️ by the Flux CMS team