Das SuluArticleConfigurationBundle erweitert Artikel in Sulu 3.0 um einen umfangreichen "Konfiguration"-Tab. Es ermöglicht die Verwaltung zusätzlicher Darstellungsoptionen, Features und Veröffentlichungseinstellungen direkt am Artikel.
- Layout-Stil - Wähle zwischen Standard, Breit, Volle Breite oder Schmal (Reading Mode)
- Sidebar - Sidebar aktivieren/deaktivieren und Position (Links/Rechts) bestimmen
- Elemente anzeigen - Inhaltsverzeichnis (TOC), Lesezeit, Autor-Box, Ähnliche Artikel
- Interaktionen - Kommentare, Share-Buttons
- Tools - Druck-Funktion, PDF-Download
- Highlighting - "Hervorgehoben" (für Slider/Teaser)
- Listen-Verhalten - "Fixiert" (Sticky) oder "Aus Listen ausblenden" (nur direkt aufrufbar)
- Metadaten - Veröffentlichungsdatum ausblenden
- Design - Header Hintergrund- und Textfarbe, Custom CSS Klassen
- Technik - Custom Template Zuweisung, Cache Lifetime, Custom JSON Data
- Vererbungs-System - Setze eine Standard-Konfiguration für alle Artikel desselben Templates
- 3-Stufen-Kaskade - Artikel-spezifisch → Template-spezifisch → Standardwerte
- Template-Erkennung - Der Template-Name wird automatisch erkannt und gespeichert
- PHP 8.2 oder höher
- Sulu CMS 3.0 oder höher
Füge das Repository zu deiner composer.json hinzu (falls lokal) oder installiere es direkt:
composer require manuxi/sulu-article-configuration-bundleFalls du nicht Symfony Flex verwendest, füge das Bundle in config/bundles.php hinzu:
return [
//...
Manuxi\SuluArticleConfigurationBundle\SuluArticleConfigurationBundle::class => ['all' => true],
];Füge Folgendes zu config/routes.yaml hinzu, um die Admin-API-Routen zu laden:
sulu_article_configuration_api:
resource: '@SuluArticleConfigurationBundle/Resources/config/routes_admin.yaml'Erstelle die benötigte Tabelle ar_article_configuration:
# Prüfe was erstellt wird
php bin/console doctrine:schema:update --dump-sql
# Führe Migration aus
php bin/console doctrine:schema:update --force- Navigiere zu Artikel in der Sulu-Admin-Navigation.
- Öffne einen bestehenden Artikel oder erstelle einen neuen (speichern!).
- Klicke auf den Konfiguration-Tab.
- Wähle die gewünschten Optionen aus (z.B. "Sidebar aktivieren", "Layout-Stil").
- Speichere die Konfiguration.
Du kannst eine Standard-Konfiguration für alle Artikel mit demselben Template definieren:
- Öffne einen Artikel mit dem gewünschten Template (z.B. "Blog-Beitrag")
- Gehe zum Konfiguration-Tab
- Konfiguriere alle Einstellungen wie gewünscht
- Aktiviere "Als Standard verwenden" im Bereich "Standard-Konfiguration"
- Speichere die Konfiguration.
Nun verwenden alle anderen Artikel mit diesem Template automatisch diese Einstellungen - es sei denn, sie haben eine eigene Konfiguration.
So funktioniert die Kaskade:
1. Artikel hat eigene Konfiguration? → wird verwendet
2. Es existiert eine Standard-Konfiguration für dieses Template? → wird verwendet
3. Keines von beiden? → hinterlegte Standardwerte werden verwendet
Das Bundle stellt eine Twig-Funktion bereit, um die Konfiguration in Twig-Templates bereit zu stellen:
{# Konfiguration holen #}
{% set articleConfig = article_configuration(uuid, template) %}
{# Oder via Alias #}
{% set articleConfig = article_config(uuid, template) %}
{# Konfigurationswerte verwenden #}
<article class="article article--{{ articleConfig.layoutStyle }}{% if articleConfig.customCssClass %} {{ articleConfig.customCssClass }}{% endif %}">
{% if articleConfig.showReadingTime %}
<span class="reading-time">{{ reading_time }} Min. Lesezeit</span>
{% endif %}
{% if articleConfig.showToc %}
<nav class="table-of-contents">
{# ... TOC Inhalt ... #}
</nav>
{% endif %}
<div class="article__content">
{{ content|raw }}
</div>
{% if articleConfig.showAuthorBox %}
<div class="author-box">
{# ... Autor-Info ... #}
</div>
{% endif %}
{% if articleConfig.showRelated %}
<section class="related-articles">
{# ... Ähnliche Artikel ... #}
</section>
{% endif %}
{% if articleConfig.enableShareButtons %}
<div class="share-buttons">
{# ... Share-Buttons ... #}
</div>
{% endif %}
</article>
{# Prüfen, woher die Config kommt #}
{% if articleConfig.configSource == 'template_default' %}
<!-- Verwendet Konfiguration aus Artikel {{ articleConfig.templateDefaultArticleId }} -->
{% endif %}Verfügbare Konfigurationswerte:
| Eigenschaft | Typ | Standard | Beschreibung |
|---|---|---|---|
layoutStyle |
string | 'default' |
default, wide, fullwidth, narrow |
enableSidebar |
bool | true |
Sidebar anzeigen |
sidebarPosition |
string | 'right' |
left, right |
showToc |
bool | true |
Inhaltsverzeichnis anzeigen |
showReadingTime |
bool | true |
Lesezeit anzeigen |
showAuthorBox |
bool | true |
Autor-Box anzeigen |
showRelated |
bool | true |
Ähnliche Artikel anzeigen |
enableComments |
bool | false |
Kommentare aktivieren |
enableShareButtons |
bool | true |
Teilen-Buttons anzeigen |
enablePrint |
bool | true |
Drucken-Button anzeigen |
enableDownloadPdf |
bool | false |
PDF-Download anzeigen |
isFeatured |
bool | false |
Hervorgehobener Artikel |
isSticky |
bool | false |
In Listen fixiert |
hideFromLists |
bool | false |
Aus Listen ausblenden |
hidePublishDate |
bool | false |
Veröffentlichungsdatum verbergen |
customCssClass |
string | null |
Eigene CSS-Klasse |
headerBgColor |
string | null |
Header Hintergrundfarbe |
headerTextColor |
string | 'auto' |
auto, light, dark |
customTemplate |
string | null |
Pfad zum eigenen Template |
cacheLifetime |
int | 86400 |
Cache-Lebensdauer in Sekunden |
customData |
string | null |
Eigene JSON-Daten |
configSource |
string | - | article, template_default, hardcoded |
Beispiel: Bedingtes Sidebar-Layout
{% set articleConfig = article_config(uuid, template) %}
<div class="layout layout--{{ articleConfig.layoutStyle }}">
{% if articleConfig.enableSidebar %}
<div class="layout__sidebar layout__sidebar--{{ articleConfig.sidebarPosition }}">
{% if articleConfig.showToc %}
{{ render_toc(content) }}
{% endif %}
</div>
{% endif %}
<main class="layout__main">
{{ content|raw }}
</main>
</div>Beispiel: Eigenes Header-Styling
{% set config = article_configuration(article.id, article.templateKey) %}
<header class="article-header"
{% if articleConfig.headerBgColor %}
style="background-color: {{ articleConfig.headerBgColor }};
color: {% if articleConfig.headerTextColor == 'light' %}#fff{% elseif articleConfig.headerTextColor == 'dark' %}#000{% else %}inherit{% endif %};"
{% endif %}>
<h1>{{ article.title }}</h1>
</header>Das Bundle erstellt folgende Tabelle:
CREATE TABLE ar_article_configuration (
id INT AUTO_INCREMENT PRIMARY KEY,
article_id VARCHAR(36) UNIQUE NOT NULL,
template_key VARCHAR(128) DEFAULT NULL,
is_default TINYINT(1) DEFAULT 0 NOT NULL,
layout_style VARCHAR(32) DEFAULT 'default' NOT NULL,
enable_sidebar TINYINT(1) DEFAULT 1 NOT NULL,
sidebar_position VARCHAR(16) DEFAULT 'right' NOT NULL,
show_toc TINYINT(1) DEFAULT 1 NOT NULL,
show_reading_time TINYINT(1) DEFAULT 1 NOT NULL,
show_author_box TINYINT(1) DEFAULT 1 NOT NULL,
show_related TINYINT(1) DEFAULT 1 NOT NULL,
enable_comments TINYINT(1) DEFAULT 0 NOT NULL,
enable_share_buttons TINYINT(1) DEFAULT 1 NOT NULL,
enable_print TINYINT(1) DEFAULT 1 NOT NULL,
enable_download_pdf TINYINT(1) DEFAULT 0 NOT NULL,
is_featured TINYINT(1) DEFAULT 0 NOT NULL,
is_sticky TINYINT(1) DEFAULT 0 NOT NULL,
hide_from_lists TINYINT(1) DEFAULT 0 NOT NULL,
hide_publish_date TINYINT(1) DEFAULT 0 NOT NULL,
custom_css_class VARCHAR(128) DEFAULT NULL,
header_bg_color VARCHAR(32) DEFAULT NULL,
header_text_color VARCHAR(16) DEFAULT 'auto' NOT NULL,
custom_template VARCHAR(255) DEFAULT NULL,
cache_lifetime INT DEFAULT 86400 NOT NULL,
custom_data LONGTEXT DEFAULT NULL,
INDEX idx_template_default (template_key, is_default)
);composer testDieses Bundle steht unter der MIT-Lizenz. Die vollständige Lizenz findest du im Bundle: LICENSE
Manuel Bertrams
- GitHub: @manuxi
