19 KiB
Flux CMS Integration – Entwicklungsplan
Ziel: Integration des flux-cms Packages für die b2in-Webseite.
Scope: Nur b2in – weitere Subseiten (b2a, stileigentum, style2own) folgen später.
Stand: 2026-03-18
Ausgangslage
Was existiert
- Package:
packages/flux-cms/(core, components, starter-components) liegt im Projekt - Composer:
packages/*/*Repository-Pfad ist incomposer.jsonkonfiguriert - Frontend: Vollständige b2in-Webseite mit ~15 Seiten
- Content-Quelle:
config/content.php– statische PHP-Arrays pro Theme - Content-Zugriff: Livewire-Sections laden via
config("content.themes.{$theme}.{$section}") - Immobilien/Projekte: Komplett in
config/content.phpdefiniert (Slug, Titel, Preise, Galerie, Quick Facts, Investment Case, Location etc.), Routeimmobilien/{slug}liest direkt aus Config - Admin-Portal:
portal.b2in.testmit eigenem CMS (Cabinets/Displays), User-/Partner-Management - Domain-System: Multi-Domain-Setup in
config/domains.php
Was fehlt
- flux-cms/core ist nicht als Composer-Dependency installiert
- Keine
app/helpers.phpmitcms()/tcms()/cms_media_url() - Keine
config/flux-cms.phppubliziert - Keine
flux_cms_*Datenbanktabellen - Keine Admin-Views/Routes für das CMS
- Keine Medienbibliothek
- Kein Immobilien-Model (Projekte leben in Config)
Scope-Einschränkung Phase 1
Nur diese Tabellen werden initial benötigt:
flux_cms_contents– Alle Seiteninhalte (Key-Value mit Übersetzungen)flux_cms_media– Medienbibliothek (Bilder, PDFs)
Nicht benötigt (kommt später bei Bedarf):
– Nachrichteneinträgeflux_cms_news_items– Branchenflux_cms_industries– FAQ-Einträgeflux_cms_faqs– Downloadsflux_cms_downloads– LinkedIn-Postsflux_cms_linkedin_posts– Suchindexflux_cms_search_index
Zusätzlich benötigt:
- Neues Immobilien/Projekte-Model mit eigenem CRUD im CMS-Backend (ersetzt die statischen Projekte aus
config/content.php)
Phasen-Übersicht
| Phase | Beschreibung | Abhängig von |
|---|---|---|
| 1 | Package-Installation & Infrastruktur | – |
| 2 | Immobilien-Model & CRUD | Phase 1 |
| 3 | Content-Migration (config → DB) | Phase 1 |
| 4 | CMS Admin-Backend | Phase 1 |
| 5 | Frontend-Umstellung (config → cms) | Phase 2, 3 |
| 6 | Medienbibliothek & Bilder | Phase 1, 4 |
| 7 | Tests | Phase 2–6 |
| 8 | Feinschliff & Dokumentation | Phase 5–7 |
Phase 1 – Package-Installation & Infrastruktur
1.1 Composer-Dependency installieren
composer require flux-cms/core:@dev
composer require intervention/image
Prüfen:
FluxCmsServiceProviderwird automatisch geladen- Keine Konflikte mit bestehenden Dependencies
1.2 Konfiguration publizieren
php artisan vendor:publish --tag=flux-cms-config
Anpassen in config/flux-cms.php:
default_locale→'de'locales→['de' => 'Deutsch', 'en' => 'English']media.profiles→ an b2in-Bildgrößen anpassenroutes.enabled→false(eigene Admin-Routes im Portal)
1.3 Migrations ausführen
Nur die benötigten Migrations:
create_flux_cms_contents_tablecreate_flux_cms_media_table
Die restlichen Migrations (news, industries, faqs, downloads, linkedin, search_index) werden nicht ausgeführt – sie liegen im Package und können bei Bedarf später migriert werden.
Optionen:
- A) Alle Migrations laufen lassen (Tabellen existieren, werden aber nicht genutzt) – einfacher
- B) Nur selektiv migrieren – sauberer, erfordert ggf. Anpassung am ServiceProvider
→ Empfehlung: Option A – leere Tabellen stören nicht und vereinfachen spätere Erweiterung.
php artisan migrate
1.4 Helper-Funktionen einrichten
Erstellen: app/helpers.php mit cms(), tcms(), cms_media_url(), media_url()
Registrieren in composer.json:
"autoload": {
"files": ["app/helpers.php"]
}
composer dump-autoload
1.5 Storage-Link
php artisan storage:link
Ergebnis Phase 1: Package installiert, DB-Tabellen vorhanden, Helper verfügbar.
Phase 2 – Immobilien/Projekte-Model & CRUD
2.1 Datenstruktur analysieren
Aktuelle Projekt-Daten aus config/content.php (am Beispiel Azizi Creek Views 4):
| Feld | Typ | Beispiel |
|---|---|---|
slug |
string | azizi-creek-views-4 |
title |
string | Azizi Developments: Creek Views 4 |
location |
string | Al Jaddaf, Dubai |
status |
string | NEW LAUNCH |
launch_date |
string | 03.03.2026 |
price_from |
integer (AED) | 1125000 |
image |
string (Pfad) | expose/a1/image-4.jpeg |
highlights |
array<string> | ['Prime Waterfront Views', ...] |
quick_facts |
array<{icon, label, value}> | Typen, Größe, Einheiten, Entwickler |
investment_case |
object | {title, text, views[]} |
gallery |
array<string> | Bildpfade |
location_info |
object | {title, map_url, points[]} |
contact |
object | {title, subtitle, options[]} |
2.2 Migration erstellen
Neue Migration create_cms_projects_table:
Schema::create('cms_projects', function (Blueprint $table) {
$table->id();
$table->string('slug')->unique();
$table->json('title'); // translatable
$table->json('location'); // translatable
$table->string('status')->nullable();
$table->date('launch_date')->nullable();
$table->unsignedInteger('price_from_aed')->nullable();
$table->string('currency')->default('AED');
$table->string('image')->nullable(); // CmsMedia Referenz
$table->json('highlights')->nullable(); // translatable array
$table->json('quick_facts')->nullable(); // [{icon, label, value}]
$table->json('investment_case')->nullable(); // {title, text, views[]}
$table->json('gallery')->nullable(); // [filename, ...]
$table->json('location_info')->nullable(); // {title, map_url, points[]}
$table->json('contact')->nullable(); // {title, subtitle, options[]}
$table->boolean('is_published')->default(false);
$table->unsignedInteger('order')->default(0);
$table->timestamps();
});
2.3 Model erstellen
App\Models\CmsProject mit:
HasTranslations(Spatie) fürtitle,location,highlights- Scopes:
published(),ordered() toFrontendArray()→ kompatibles Array für bestehende Blade-ViewsgetFormattedPrice()→ nutztPriceHelper::formatAed()- Accessors für
gallery_urls,image_urletc.
2.4 Factory & Seeder
- Factory:
CmsProjectFactoryfür Tests - Seeder:
CmsProjectSeeder– importiert die bestehenden Projekte ausconfig/content.phpin die DB
2.5 Admin CRUD (Volt-Komponente)
Admin-View admin.cms.projects-index:
- Liste aller Projekte (Titel, Status, Preis, Published, Order)
- Erstellen/Bearbeiten Modal oder Inline
- Felder: alle aus 2.2
- Galerie-Management via MediaPicker
- Bild-Upload via MediaLibraryUploader
- Sortierung per Drag & Drop oder Order-Feld
- Publish/Unpublish Toggle
2.6 Route für Immobilien-Show anpassen
// Vorher:
Route::get('/immobilien/{slug}', function (string $slug) {
$project = config("content.themes.{$theme}.immobilien_projects.projects.{$slug}");
...
});
// Nachher:
Route::get('/immobilien/{slug}', function (string $slug) {
$project = CmsProject::where('slug', $slug)->published()->firstOrFail();
return view('web.immobilien-show', ['project' => $project->toFrontendArray()]);
});
Ergebnis Phase 2: Immobilien-Projekte in DB, editierbar im CMS, Frontend nutzt Model.
Phase 3 – Content-Migration (config → DB)
3.1 Content-Struktur analysieren
Die config/content.php enthält das b2in-Theme mit folgenden Sektionen:
| Page | Section | Typ |
|---|---|---|
| global | announcement_bar |
Text + Links |
| global | header |
Navigation |
| global | footer |
Text + Links |
| home | hero |
Text + Bild + Stats |
| home | founder_bar |
Text + Bild |
| home | synergie_section |
Text + Bild |
| home | vision_section |
Text + Bild |
| home | ecosystem_core |
Text + Items |
| home | cta_section |
Text + Link |
| home | brand_worlds |
Text + Items |
| about | about_hero, our_story, our_values, leadership_team |
Diverse |
| immobilien | immobilien_hero_v2, immobilien_warum_dubai, immobilien_kaufprozess, immobilien_bruecke, immobilien_mindset, immobilien_moebel_vorteil |
Diverse |
| faq | FAQ-Kategorien | Q&A |
| netzwerk | Hero, Stats, Sections | Diverse |
| contact | Form-Info | Text |
| impressum/privacy/terms/cookie-policy | Langtext | HTML |
3.2 CmsContentSeeder erstellen
Strategie: Alle b2in-Inhalte aus config/content.php in flux_cms_contents überführen.
- Key-Schema:
{page}.{section}.{field}(z.B.home.hero.title,about.our_story.title) - Typen:
text,html,image,json(für Arrays wiepillars,stats,navigation) - Gruppen:
home,about,immobilien,netzwerk,faq,contact,impressum,privacy,terms,cookie_policy,global(Header, Footer)
Datei: database/seeders/CmsContentSeeder.php – liest config/content.php und schreibt in DB.
3.3 Seeders ausführen & verifizieren
php artisan db:seed --class=CmsContentSeeder
Ergebnis Phase 3: Alle b2in-Inhalte in der DB, abrufbar über cms('home.hero.title').
Phase 4 – CMS Admin-Backend
4.1 CMS als eigener Menüpunkt
Das CMS wird im Admin-Portal (portal.b2in.test) als eigener Top-Level-Menüpunkt "CMS" in der Sidebar integriert.
Sidebar-Erweiterung (resources/views/components/layouts/app/sidebar.blade.php):
CMS
├── Dashboard (Übersicht: Anzahl Contents, Medien, Projekte)
├── Inhalte (Content-Editor für Text/HTML/Image/JSON Keys)
├── Projekte (Immobilien-CRUD – aus Phase 2)
├── Medienbibliothek (Upload, Grid, Conversions)
4.2 CMS-Layout
Entscheidung: Die CMS-Views nutzen das bestehende Admin-Portal-Layout (admin-master.blade.php / app.blade.php), damit Navigation und User-Menü konsistent bleiben.
→ Das Reference-Layout layout-cms.blade.php wird nicht als separates Layout genutzt, sondern als Vorlage für die Content-Struktur innerhalb des bestehenden Layouts.
4.3 Admin-Views erstellen
Aus den Package-Referenz-Views nur die benötigten kopieren und anpassen:
| View | Quelle | Ziel |
|---|---|---|
| Dashboard | admin-reference/cms/dashboard.blade.php |
livewire/admin/cms/dashboard.blade.php |
| Content-Editor | admin-reference/cms/content-index.blade.php |
livewire/admin/cms/content-index.blade.php |
| Medienbibliothek | admin-reference/cms/media-index.blade.php |
livewire/admin/cms/media-index.blade.php |
| MediaPicker | admin-reference/cms/media-picker.blade.php |
livewire/admin/cms/media-picker.blade.php |
| MediaUploader | admin-reference/cms/media-library-uploader.blade.php |
livewire/admin/cms/media-library-uploader.blade.php |
| Projekte | Neu erstellen | livewire/admin/cms/projects-index.blade.php |
Nicht benötigt (vorerst): news-index, industries-index, faqs-index, linkedin-index, downloads-index, team-index, search-index
4.4 Livewire-Komponenten einrichten
mkdir -p app/Livewire/Admin/Cms/
Aus Package kopieren + Namespace anpassen:
MediaLibraryUploader.php→App\Livewire\Admin\CmsMediaPicker.php→App\Livewire\Admin\CmsMediaUploader.php→App\Livewire\Admin\Cms
4.5 Admin-Routes registrieren
In routes/admin.php innerhalb der bestehenden auth-Middleware-Gruppe:
// Flux CMS Routes
Volt::route('admin/cms', 'admin.cms.dashboard')->name('cms.dashboard');
Volt::route('admin/cms/content', 'admin.cms.content-index')->name('cms.content.index');
Volt::route('admin/cms/media', 'admin.cms.media-index')->name('cms.media.index');
Volt::route('admin/cms/projects', 'admin.cms.projects-index')->name('cms.projects.index');
Ergebnis Phase 4: Funktionierendes Admin-Backend unter portal.b2in.test/admin/cms mit Dashboard, Content-Editor, Medienbibliothek und Projekte-CRUD.
Phase 5 – Frontend-Umstellung (config → cms)
5.1 Strategie: Dualer Betrieb mit Fallback
Die Umstellung erfolgt inkrementell. Jede Section einzeln umstellen, mit Fallback auf config():
// Vorher (Hero.php):
$this->content = config("content.themes.{$theme}.hero", []);
// Nachher:
$this->content = $this->loadFromCms('home.hero');
// Fallback-Methode in einem Trait oder Base-Class:
protected function loadFromCms(string $group): array
{
$cmsContent = app(CmsContentService::class)->getGroup($group);
if (empty($cmsContent)) {
$theme = config('app.theme', 'b2in');
$section = Str::afterLast($group, '.');
return config("content.themes.{$theme}.{$section}", []);
}
return $cmsContent;
}
5.2 Sections schrittweise umstellen
Reihenfolge (nach Priorität / Sichtbarkeit):
-
Home-Page Sections:
- Hero →
home.hero - FounderBar →
home.founder_bar - ContentSection →
home.{section}(dynamisch) - VisionSection →
home.vision_section - EcosystemCore →
home.ecosystem_core - CTASection →
home.cta_section
- Hero →
-
Globale Elemente:
- Header (Navigation) →
global.header - Footer →
global.footer - AnnouncementBar →
global.announcement_bar
- Header (Navigation) →
-
Immobilien-Seite (statischer Content):
- HeroV2 →
immobilien.hero_v2 - WarumDubai →
immobilien.warum_dubai - Kaufprozess →
immobilien.kaufprozess - Brücke →
immobilien.bruecke - Mindset →
immobilien.mindset - MöbelVorteil →
immobilien.moebel_vorteil - Projekte-Liste → CmsProject::published()->ordered() (aus Phase 2)
- HeroV2 →
-
Unterseiten:
- About
- FAQ
- Contact
- Impressum / Privacy / Terms / Cookie-Policy
- Netzwerk
- Service / Portfolio
5.3 Immobilien-Route umstellen
// routes/web.php – von config auf Model:
Route::get('/immobilien/{slug}', function (string $slug) {
$project = \App\Models\CmsProject::where('slug', $slug)
->published()
->firstOrFail();
return view('web.immobilien-show', ['project' => $project->toFrontendArray()]);
})->name('immobilien.show');
Die immobilien.blade.php Projekte-Liste ebenfalls umstellen:
// Vorher: $projects = config("content.themes.{$theme}.immobilien_projects", []);
// Nachher: $projects = CmsProject::published()->ordered()->get();
5.4 Bilder umstellen
- asset('img/assets/' . $heroV2['image'])
+ cms_media_url('immobilien.hero_v2.image', 'hero')
Ergebnis Phase 5: b2in-Frontend liest Inhalte aus DB + CmsProject-Model, editierbar über Admin.
Phase 6 – Medienbibliothek & Bilder
6.1 Bestehende Bilder importieren
Alle b2in-Bilder (aus public/img/assets/) in die CMS-Medienbibliothek importieren:
b2in/– allgemeine b2in-Bilder (Hero, Founder, Sections)expose/– Immobilien-Projektbilder
6.2 CmsMediaSeeder
Seeder erstellt CmsMedia-Einträge für alle bestehenden Bilder und verknüpft sie mit den CmsContent-Keys vom Typ image.
6.3 Bildprofile definieren
In config/flux-cms.php:
hero→ 1920×800 (Hero-Banner)card→ 768×512 (Kacheln, Sections)thumbnail→ 400×300 (Listen, Übersichten)avatar→ 400×400 (Team-Fotos, Founder)gallery→ 1200×900 (Projekt-Galerie)og_image→ 1200×630 (Social Sharing)
6.4 Conversions generieren
php artisan flux-cms:clear-cache
Ergebnis Phase 6: Alle Bilder in Medienbibliothek, Conversions generiert, URLs aufgelöst.
Phase 7 – Tests
7.1 Referenz-Tests kopieren (selektiv)
mkdir -p tests/Feature/Cms
cp packages/flux-cms/core/tests-reference/Feature/Cms/CmsMediaTest.php tests/Feature/Cms/
cp packages/flux-cms/core/tests-reference/Feature/Cms/CmsContentServiceTest.php tests/Feature/Cms/
7.2 Projektspezifische Tests
- CmsProjectTest – CRUD, published/unpublished, toFrontendArray(), Validierung
- CmsContentSeederTest – Prüft ob alle Keys aus config in DB existieren
- CmsAdminAccessTest – Prüft Zugriffskontrolle auf CMS-Admin-Routen
- ImmobilienRouteTest – Prüft
/immobilien/{slug}mit DB-Daten - FrontendFallbackTest – Prüft dualen Betrieb (CMS → config Fallback)
- MediaIntegrationTest – Upload, Conversion, URL-Auflösung
7.3 Tests ausführen
php artisan test --compact --filter=Cms
php artisan test --compact --filter=Immobilien
Ergebnis Phase 7: Alle CMS-Funktionalitäten sind getestet.
Phase 8 – Feinschliff & Dokumentation
8.1 Cache & Performance
- CMS-Content-Cache aktivieren
- Eager Loading optimieren
- Prüfen: Keine N+1-Queries auf Frontseiten
8.2 config/content.php aufräumen
- Nach vollständiger Umstellung: b2in-Theme-Daten als
@deprecatedmarkieren - Noch nicht entfernen (Fallback für andere Themes!)
- Immobilien-Projekte aus Config entfernen (leben jetzt in DB)
8.3 Sidebar-Berechtigungen
- CMS-Zugang über Spatie-Permission absichern (
permission:manage-cms) - CMS-Menüpunkt nur für berechtigte User anzeigen
8.4 Dokumentation
- Diesen Plan aktualisieren mit Status
- Notizen für Integration weiterer Subseiten (b2a, stileigentum, style2own)
Offene Fragen / Entscheidungen
| # | Frage | Entscheidung |
|---|---|---|
| 1 | Alle flux-cms Migrations laufen lassen oder nur contents + media? | Empfehlung: Alle (leere Tabellen stören nicht) |
| 2 | CmsProject: Eigene Migration oder flux-cms erweitern? | Eigene Migration im Projekt |
| 3 | FAQ-Daten: Vorerst in config belassen oder direkt in flux_cms_faqs? |
Vorerst config |
| 4 | Magazin: Eigenes System belassen oder später auf CMS? | Vorerst belassen |
| 5 | Andere Themes (b2a etc.) weiterhin via config()? |
Ja |
Fortschritt
| Phase | Status | Notizen |
|---|---|---|
| 1 – Installation & Infrastruktur | ✅ Fertig | 2026-03-18: Package installiert, Config angepasst, Migrations gelaufen, Helpers eingerichtet, 434 Tests grün |
| 2 – Immobilien-Model & CRUD | ✅ Fertig | 2026-03-18: Migration, Model, Factory, Seeder, 9 Tests grün. CRUD Admin-View folgt in Phase 4. |
| 3 – Content-Migration | ✅ Fertig | 2026-03-18: 61 Sections in 8 Gruppen migriert, Section-als-JSON-Ansatz, 8 Tests grün |
| 4 – CMS Admin-Backend | ✅ Fertig | 2026-03-18: Dashboard, Content-Editor, Projekte-CRUD, Medienbibliothek, Sidebar-Menü, MediaPicker/Uploader, 16 Tests grün |
| 5 – Frontend-Umstellung | ⬜ Offen | |
| 6 – Medienbibliothek | ⬜ Offen | |
| 7 – Tests | ⬜ Offen | |
| 8 – Feinschliff | ⬜ Offen |