Eine moderne Alternative zum xoutputfilter AddOn für REDAXO CMS.
Das Snippets-AddOn bietet zentrale Verwaltung von wiederverwendbaren Code-Fragmenten und automatische HTML-Manipulation mit PHP 8.4 DOM:
- Snippets – Wiederverwendbare HTML/PHP-Fragmente mit Parametern
- Filter – 26+ Filter für Textformatierung
- HTML-Ersetzungen – CSS-Selektoren, Regex und PHP-Callbacks
- Abkürzungen – Automatische
<abbr>-Tags für Akronyme - PHP-API –
Snippets::get(),Snippets::apply()für PHP-Zugriff - Scope-Kontrolle – Templates, Kategorien, URLs, Backend-Seiten
- Berechtigungssystem – Admin, Editor, Viewer Rollen
- AddOn im Ordner
/redaxo/src/addons/snippetsinstallieren - Im Backend unter AddOns aktivieren
- Berechtigungen für Benutzer einrichten (optional)
[[snippet:key_name]]
[[snippet:key_name|param1=wert1|param2=wert2]]
[[snippet:key_name|upper|truncate(100)]]
[[snippet:key_name|filter|param=wert]]
Snippet erstellen:
- Key:
footer_copyright - Typ:
html - Inhalt:
© 2026 Meine Firma GmbH
Verwendung:
<footer>
[[snippet:footer_copyright]]
</footer>Ausgabe:
<footer>
© 2026 Meine Firma GmbH
</footer>Snippet erstellen:
- Key:
alert - Typ:
php - Inhalt:
<?php
$typ = $SNIPPET_PARAMS['typ'] ?? 'info';
$text = $SNIPPET_PARAMS['text'] ?? '';
$titel = $SNIPPET_PARAMS['titel'] ?? '';
$icons = [
'info' => 'fa-info-circle',
'success' => 'fa-check-circle',
'warning' => 'fa-exclamation-triangle',
'danger' => 'fa-times-circle'
];
$icon = $icons[$typ] ?? 'fa-info-circle';
?>
<div class="alert alert-<?= htmlspecialchars($typ) ?>">
<?php if ($titel): ?>
<h4><i class="fa <?= $icon ?>"></i> <?= htmlspecialchars($titel) ?></h4>
<?php endif; ?>
<p><?= htmlspecialchars($text) ?></p>
</div>Verwendung:
[[snippet:alert|typ=success|titel=Gespeichert!|text=Ihre Daten wurden erfolgreich gespeichert.]]Ausgabe:
<div class="alert alert-success">
<h4><i class="fa fa-check-circle"></i> Gespeichert!</h4>
<p>Ihre Daten wurden erfolgreich gespeichert.</p>
</div>Snippet erstellen:
- Key:
kontakt - Typ:
php - Inhalt:
<?php
$name = $SNIPPET_PARAMS['name'] ?? '';
$position = $SNIPPET_PARAMS['position'] ?? '';
$tel = $SNIPPET_PARAMS['tel'] ?? '';
$email = $SNIPPET_PARAMS['email'] ?? '';
$foto = $SNIPPET_PARAMS['foto'] ?? '';
?>
<div class="kontaktbox">
<?php if ($foto): ?>
<img src="<?= rex_url::media($foto) ?>" alt="<?= htmlspecialchars($name) ?>">
<?php endif; ?>
<h4><?= htmlspecialchars($name) ?></h4>
<?php if ($position): ?>
<p class="position"><?= htmlspecialchars($position) ?></p>
<?php endif; ?>
<?php if ($tel): ?>
<p><i class="fa fa-phone"></i> <a href="tel:<?= htmlspecialchars($tel) ?>"><?= htmlspecialchars($tel) ?></a></p>
<?php endif; ?>
<?php if ($email): ?>
<p><i class="fa fa-envelope"></i> <a href="mailto:<?= htmlspecialchars($email) ?>"><?= htmlspecialchars($email) ?></a></p>
<?php endif; ?>
</div>Verwendung:
[[snippet:kontakt|name=Max Mustermann|position=Geschäftsführer|tel=+49 123 456789|email=max@firma.de|foto=max.jpg]]<?php
// Array mit allen übergebenen Parametern
$wert = $SNIPPET_PARAMS['mein_param'] ?? 'standard';
// Der Snippet-Key als String
echo $SNIPPET_KEY; // z.B. "kontakt"
// Das Snippet-Objekt mit allen Eigenschaften
$snippet->getTitle();
$snippet->getDescription();
$snippet->getId();| Typ | Beschreibung |
|---|---|
html |
HTML-Code, wird direkt ausgegeben |
text |
Reiner Text, wird escaped |
php |
PHP-Code mit Zugriff auf $SNIPPET_PARAMS (nur Admins) |
Filter formatieren die Snippet-Ausgabe. Sie werden mit | notiert und können kombiniert werden.
| Filter | Beschreibung | Beispiel |
|---|---|---|
upper |
GROSSBUCHSTABEN | [[snippet:key|upper]] |
lower |
kleinbuchstaben | [[snippet:key|lower]] |
title |
Title Case | [[snippet:key|title]] |
capitalize |
Erster Buchstabe groß | [[snippet:key|capitalize]] |
trim |
Whitespace entfernen | [[snippet:key|trim]] |
truncate(n,suffix) |
Auf n Zeichen kürzen | [[snippet:key|truncate(100,...)]] |
limit(n,suffix) |
Alias für truncate | [[snippet:key|limit(50)]] |
words(n,suffix) |
Auf n Wörter kürzen | [[snippet:key|words(20)]] |
nl2br |
Zeilenumbrüche → <br> |
[[snippet:key|nl2br]] |
raw |
Keine nl2br-Konvertierung | [[snippet:key|raw]] |
markdown |
Markdown → HTML | [[snippet:key|markdown]] |
strip_tags(allowed) |
HTML-Tags entfernen | [[snippet:key|strip_tags(<p><br>)]] |
escape |
HTML-Entities escapen | [[snippet:key|escape]] |
sanitize |
HTML sicher machen | [[snippet:key|sanitize]] |
format(args...) |
sprintf-Formatierung | [[snippet:key|format(5,Baum)]] |
default(value) |
Fallback wenn leer | [[snippet:key|default(Kein Inhalt)]] |
replace(s,r) |
Text ersetzen | [[snippet:key|replace(alt,neu)]] |
prefix(text) |
Text voranstellen | [[snippet:key|prefix(>>> )]] |
suffix(text) |
Text anhängen | [[snippet:key|suffix( <<<)]] |
wrap(b,a) |
Text umschließen | [[snippet:key|wrap(<em>,</em>)]] |
date(format) |
Datum formatieren | [[snippet:key|date(d.m.Y)]] |
intldate(format) |
Internationales Datum | [[snippet:key|intldate(LONG)]] |
number(d,dp,ts) |
Zahl formatieren | [[snippet:key|number(2,",",".")]] |
bytes(precision) |
Bytes formatieren | [[snippet:key|bytes(2)]] |
slug |
URL-freundlich | [[snippet:key|slug]] |
url |
Als klickbarer Link | [[snippet:key|url]] |
email |
Als klickbare E-Mail | [[snippet:key|email]] |
widont |
Keine Einzel-Wörter am Ende | [[snippet:key|widont]] |
json |
Als JSON ausgeben | [[snippet:key|json]] |
base64 |
Base64-kodiert | [[snippet:key|base64]] |
<!-- Überschrift in Großbuchstaben -->
[[snippet:headline|upper]]
<!-- Teaser: max 150 Zeichen, ohne HTML -->
[[snippet:description|strip_tags|truncate(150,...)]]
<!-- Markdown-Content sicher ausgeben -->
[[snippet:content|markdown|sanitize]]
<!-- Preis formatieren -->
[[snippet:price|number(2,",",".")]] €
<!-- E-Mail als Link -->
[[snippet:contact_email|email]]
<!-- Filter + Parameter kombiniert -->
[[snippet:teaser|upper|max_length=100|truncate(100)]]Die zentrale API-Klasse für den Zugriff auf Snippets.
use FriendsOfREDAXO\Snippets\Snippets;
// Snippet abrufen
echo Snippets::get('footer_text');
echo Snippets::get('greeting', ['name' => 'Max']);
// Mit Filtern
echo Snippets::filtered('headline', [], 'upper');
echo Snippets::filtered('content', [], 'markdown|sanitize');
// Platzhalter in Text ersetzen
$html = '<h1>[[snippet:headline]]</h1>';
echo Snippets::apply($html);
// Existenz prüfen
if (Snippets::exists('special_offer')) {
echo Snippets::get('special_offer');
}
// Mit Fallback
echo Snippets::getOr('headline', 'Willkommen');
// Beliebigen Text filtern
echo Snippets::filter($content, 'escape|truncate(100)');| Methode | Beschreibung |
|---|---|
Snippets::get($key, $params, $clangId) |
Snippet abrufen |
Snippets::filtered($key, $params, $filters, $clangId) |
Snippet mit Filtern |
Snippets::apply($text, $clangId, $context) |
Platzhalter ersetzen |
Snippets::exists($key) |
Existenz prüfen |
Snippets::getOr($key, $fallback, $params, $clangId) |
Mit Fallback |
Snippets::filter($content, $filters) |
Text filtern |
Automatische Manipulation des HTML-Outputs über CSS-Selektoren, Regex oder PHP-Callbacks.
| Typ | Beschreibung |
|---|---|
css |
CSS-Selektoren zum Finden und Manipulieren von Elementen |
regex |
Reguläre Ausdrücke für Pattern-basierte Ersetzung |
callback |
PHP-Funktion für komplexe Logik |
Regel erstellen:
- Typ: CSS-Selektor
- Suchwert:
a[href^="http"]:not([href*="meine-domain.de"]) - Position: Am Ende einfügen
- Ersetzung:
<i class="fa fa-external-link"></i>
Vorher:
<a href="https://example.com">Mehr Info</a>Nachher:
<a href="https://example.com">Mehr Info <i class="fa fa-external-link"></i></a>Regel erstellen:
- Typ: CSS-Selektor
- Suchwert:
img:not([loading]) - Position: Attribut setzen
- Attribut:
loading - Wert:
lazy
Vorher:
<img src="bild.jpg" alt="Beispiel">Nachher:
<img src="bild.jpg" alt="Beispiel" loading="lazy">Regel erstellen:
- Typ: CSS-Selektor
- Suchwert:
table:not(.no-wrap) - Position: Umschließen
- Ersetzung:
<div class="table-responsive">|</div>
Vorher:
<table>...</table>Nachher:
<div class="table-responsive"><table>...</table></div>Regel erstellen:
- Typ: Regex
- Pattern:
/(\+49[\d\s\-]+)/ - Ersetzung:
<a href="tel:$1">$1</a>
Vorher:
<p>Rufen Sie uns an: +49 123 456789</p>Nachher:
<p>Rufen Sie uns an: <a href="tel:+49 123 456789">+49 123 456789</a></p>Regel erstellen:
- Typ: PHP Callback
- Suchwert:
{{YEAR}} - Ersetzung:
FriendsOfREDAXO\MeinAddon\Replacer::currentYear
Callback-Klasse:
<?php
namespace FriendsOfREDAXO\MeinAddon;
use FriendsOfREDAXO\Snippets\Domain\HtmlReplacement;
class Replacer
{
public static function currentYear(string $search, string $content, HtmlReplacement $replacement): string
{
return str_replace($search, date('Y'), $content);
}
}| Position | Beschreibung |
|---|---|
| Ersetzen | Ersetzt das gesamte Element |
| Davor einfügen | Fügt vor dem Element ein |
| Danach einfügen | Fügt nach dem Element ein |
| Am Anfang einfügen | Fügt innerhalb am Anfang ein (prepend) |
| Am Ende einfügen | Fügt innerhalb am Ende ein (append) |
Jede HTML-Ersetzung kann eingeschränkt werden auf:
- Context: Frontend, Backend oder beides
- Templates: Nur bestimmte Templates (Frontend)
- Kategorien: Nur bestimmte Kategorien mit/ohne Unterkategorien (Frontend)
- URL-Pattern: Regex für URL-Matching (Frontend)
- Backend-Seiten: Nur bestimmte Backend-Seiten
Automatische Kennzeichnung von Abkürzungen und Akronymen mit <abbr>-Tags.
Abkürzung erstellen:
- Abkürzung:
HTML - Ausschreibung:
HyperText Markup Language - Groß-/Kleinschreibung beachten: ✅
- Nur ganze Wörter: ✅
Vorher:
<p>HTML und CSS sind die Grundlagen des Webs.</p>Nachher:
<p><abbr title="HyperText Markup Language">HTML</abbr> und
<abbr title="Cascading Style Sheets">CSS</abbr> sind die Grundlagen des Webs.</p>| Option | Beschreibung |
|---|---|
| Groß-/Kleinschreibung | Nur exakte Schreibweise ersetzen |
| Nur ganze Wörter | Keine Teilwörter ersetzen (z.B. "API" nicht in "MyAPIClass") |
| Sprache | Nur für bestimmte REDAXO-Sprache |
| Priorität | Verarbeitungsreihenfolge (höher = früher) |
In den Einstellungen können Bereiche definiert werden, die von der Abkürzungs-Ersetzung ausgenommen sind:
a
nav
code
pre
.no-abbr
<?php
use FriendsOfREDAXO\Snippets\Service\SnippetService;
// Snippet rendern
echo SnippetService::render(
'kontakt', // Snippet-Key
'frontend', // Context
rex_clang::getCurrentId(), // Sprach-ID
['name' => 'Max'] // Parameter
);<?php
use FriendsOfREDAXO\Snippets\Service\ReplacementService;
$content = 'Hallo [[snippet:kontakt|name=Max]]';
$service = new ReplacementService();
$ersetzt = $service->replace($content, [
'context' => 'frontend',
'clang_id' => rex_clang::getCurrentId()
]);
echo $ersetzt;<?php
use FriendsOfREDAXO\Snippets\Service\HtmlReplacementService;
$content = '<h1>Überschrift</h1><p>Text</p>';
$processed = HtmlReplacementService::process($content, 'frontend');
echo $processed;<?php
use FriendsOfREDAXO\Snippets\Service\FilterService;
$text = 'Mein langer Text hier...';
$filtered = FilterService::apply($text, [
['name' => 'truncate', 'args' => ['50', '...']],
['name' => 'upper', 'args' => []]
]);
echo $filtered;| Rolle | Rechte |
|---|---|
snippets[admin] |
Vollzugriff, PHP-Snippets bearbeiten, Einstellungen |
snippets[editor] |
HTML/Text-Snippets erstellen und bearbeiten |
snippets[viewer] |
Nur lesen |
- Snippet-Ersetzung aktiv: Frontend/Backend aktivieren
- HTML-Ersetzungen aktiv: Frontend/Backend aktivieren
- Abkürzungen aktiv: Frontend/Backend aktivieren
- Debug-Modus: Erweiterte Fehlerausgabe
Das Snippets-AddOn ist vollständig mit Sprog kombinierbar. Beide AddOns ergänzen sich:
- Sprog für mehrsprachige Platzhalter und Übersetzungen
- Snippets für wiederverwendbare Code-Fragmente mit Parametern
Falls Sprog installiert ist, können Sprog-Wildcards direkt im Content verwendet werden:
<!-- Sprog für Übersetzungen -->
{{ firmenname }}
{{ kontakt_email }}
<!-- Snippets für Komponenten -->
[[snippet:kontaktbox|name={{ ansprechpartner }}|tel={{ telefon }}]]Snippets werden nicht ersetzt in:
- Struktur-Edit-Modus
- YForm Table Manager Edit
- Module-Edit / Template-Edit
- AJAX Edit-Requests
- Snippets-AddOn Backend-Seiten
- Nur für
snippets[admin]-Benutzer - Alle Ausführungen werden protokolliert
- Fehler werden im Debug-Modus sichtbar
- PHP-Callbacks nur aus erlaubten Namespaces (
FriendsOfREDAXO\,rex_)
- Status prüfen: Snippet muss aktiv sein
- Context prüfen: Frontend-Snippet nicht im Backend sichtbar
- Key prüfen: Groß-/Kleinschreibung beachten
- Edit-Modus: Snippets werden beim Bearbeiten nicht ersetzt
- Status prüfen: Regel muss aktiv sein
- Scope prüfen: Template/Kategorie/URL stimmen?
- Selektor testen: CSS-Selektor korrekt?
- Debug aktivieren: In Einstellungen aktivieren
Debug-Modus aktivieren → Fehler erscheinen als HTML-Kommentare:
<!-- PHP Snippet Error (mein_snippet): Undefined variable $test -->| Tabelle | Beschreibung |
|---|---|
rex_snippets_snippet |
Snippets |
rex_snippets_translation |
Übersetzungen |
rex_snippets_category |
Kategorien |
rex_snippets_html_replacement |
HTML-Ersetzungen |
rex_snippets_abbreviation |
Abkürzungen |
rex_snippets_log |
Audit-Log |
MIT License
Entwickelt von der REDAXO-Community