TYPO3 als Wiki-Plattform: Wie ich eine vollständige Wiki-Extension selbst gebaut habe
Typo3

TYPO3 als Wiki-Plattform: Wie ich eine vollständige Wiki-Extension selbst gebaut habe

Yannick Aister 5 min read 42 Views

Die Ausgangsfrage: Wiki kaufen oder selbst bauen?

Wikis gibt es wie Sand am Meer. MediaWiki, DokuWiki, Confluence, Notion, BookStack – die Liste bekannter Lösungen ist lang. Warum also eine eigene Wiki-Extension für TYPO3 bauen, anstatt einfach ein fertiges Tool zu nehmen?

Die Antwort liegt im Kontext: Wenn ein Projekt bereits auf TYPO3 setzt, ein einheitliches Nutzermanagement über fe_users gewünscht ist und das Wiki Teil einer bestehenden Infrastruktur sein soll, dann ist eine eigene Extension die sauberste Lösung. Kein zweites System, kein zweites Login, kein Datenschutzproblem mit einem externen Dienst.

Genau das war mein Ausgangspunkt. Das Ergebnis: AisteaWiki – eine vollständige Wiki-Frontend-Extension für TYPO3 v14, entwickelt mit PHP 8.3 und MySQL 8.

Was die Extension kann

Der Funktionsumfang ist bewusst praxisnah gehalten – nicht Feature-maximiert, sondern auf echte Nutzungsszenarien ausgerichtet:

  • Artikel mit Draft-, Published- und Archived-Status
  • Hierarchischer Seitenbaum über Parent/Child-Beziehungen
  • Kategorien, Tags und manuelle Sortierung
  • Revisionen mit Diff-Ansicht und Restore-Funktion
  • Wiki-Links per [[Artikelname]]-Syntax
  • Templates für wiederkehrende Artikeltypen
  • Anhänge und Inline-Bilder
  • Volltextsuche mit MySQL FULLTEXT und LIKE-Fallback
  • Team-Kontext mit Rollen, Einladungen per Token und Admin-Approval-Flow
  • Profilseiten mit Avatar, Passwortwechsel und Account-Löschung

Das alles läuft als Frontend-Plugin: Nutzer registrieren sich im Frontend, arbeiten in Teams und sehen nur das, was für sie sichtbar ist – gesteuert über Sichtbarkeitsregeln (private oder internal).

Architektur-Entscheidungen

Extbase als Grundlage

Die Extension basiert auf Extbase und Fluid, dem MVC-Framework von TYPO3. Das war eine bewusste Entscheidung: Extbase integriert sich tief in den TYPO3-Core, nutzt vorhandene Mechanismen für Persistenz, Routing und Caching – und ist für erfahrene TYPO3-Entwickler sofort lesbar.

Die Plugin-Konfiguration mit erlaubten Controller-Action-Kombinationen ist entsprechend umfangreich:

 

# Auszug aus der Plugin-Registrierung
Article: list, show, dashboard, new, create, edit,
         update, delete, search, myArticles,
         history, restore, templates
Profile: show, updateProfile, updatePassword, deleteAccount
Team:    switch, show, members, invite,
         removeMember, promote, createTeam

 

Request-Parsing bewusst außerhalb von Extbase

Eine interessante Architekturentscheidung betrifft das Request-Parsing. Mehrere Flows – darunter Datei-Uploads, Frontend-Registrierung und Token-basierte Einladungen – lesen Daten bewusst aus dem PSR-7-Main-Request statt aus dem Extbase-Request:

 

// Uploads
$uploadedFiles = $GLOBALS['TYPO3_REQUEST']->getUploadedFiles();
 
// Registrierungsfelder
$body = $GLOBALS['TYPO3_REQUEST']->getParsedBody();
 
// Invite-Token aus URL
$queryParams = $GLOBALS['TYPO3_REQUEST']->getQueryParams();

 

Der Grund: Extbase normalisiert und filtert einige Daten, bevor sie im Controller ankommen. Bei Datei-Uploads und flachen Feldnamen führte das zu Problemen, die über den direkten PSR-7-Zugriff sauber gelöst wurden.

Flache Feldnamen gegen Fluid-Parsing-Fehler

Verschachtelte Feldnamen wie tx_aisteawiki[key] in normalen HTML-Attributen innerhalb von Fluid-Templates führten zu Parse-Fehlern – Fluid interpretiert die eckigen Klammern als Syntax. Die Lösung war pragmatisch: flache Feldnamen wie reg_firstName im Template, manuelle Zuordnung im Controller. Kein Hack, sondern ein bewusster Kompromiss.

Volltextsuche: MySQL FULLTEXT mit Fallback

Die Suche läuft über MySQL FULLTEXT-Indizes auf title, teaser, content und tags. Was auf den ersten Blick simpel klingt, hat einen wichtigen Fallback-Mechanismus: Wenn die Datenbankstruktur vom erwarteten Index abweicht – etwa nach einem Datenbankimport ohne Index-Rebuild – fällt die Suche automatisch auf eine LIKE-Suche zurück, anstatt mit einer SQL-Exception zu brechen.

 

// Vereinfachte Logik im Repository
try {
    // FULLTEXT-Suche
    $result = $this->searchFulltext($searchTerm);
} catch (\Exception $e) {
    // Graceful Fallback auf LIKE
    $result = $this->searchLike($searchTerm);
}

 

Robust zu bauen bedeutet nicht nur "es funktioniert wenn alles passt", sondern auch "es bricht nicht, wenn etwas nicht passt".

Das cHash-Problem bei GET-basierter Suche

TYPO3 prüft bei gecachten Seiten standardmäßig einen cHash-Parameter zur Validierung der Query-Parameter. Das führt bei GET-basierter Suche – wo der Suchbegriff als URL-Parameter übergeben wird – zuverlässig zu 404-Fehlern, weil der cHash nicht mit dem Suchterm übereinstimmt.

Die Lösung: Die Suchparameter werden explizit aus der cHash-Validierung ausgenommen:

 

# config/system/settings.php
$GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'] = [
    'tx_aisteawiki_wiki[searchTerm]',
    'tx_aisteawiki_wiki[action]',
    'tx_aisteawiki_wiki[controller]',
];

 

Wer das vergisst oder später entfernt, wundert sich über mysteriöse 404s auf der Suchseite. Daher: Diese Ausnahmen gehören dokumentiert und dürfen bei Refactorings nicht stillschweigend entfernt werden.

Deployment mit Deployer

Das Deployment läuft über Deployer – ein PHP-basiertes Deployment-Tool, das sich gut mit TYPO3-Projekten verträgt. Für die Ersteinrichtung auf einem frischen Produktionsserver sieht der Ablauf so aus:

 

# 1. Code deployen
vendor/bin/dep deploy production
 
# 2. Lokale Datenbank einmalig auf Produktion übertragen
vendor/bin/dep typo3:database_push production
 
# 3. Extensions einrichten und Cache leeren
vendor/bin/dep typo3:extension_setup production
vendor/bin/dep typo3:cache_flush production

 

Ab dem zweiten Deployment reicht ein einzelner Befehl: vendor/bin/dep deploy production. Für den lokalen Abgleich mit der Produktionsdatenbank gibt es entsprechende Pull-Tasks, die die Daten direkt in die lokale DDEV-Umgebung importieren.

Wann lohnt sich dieser Ansatz?

Eine eigene TYPO3-Wiki-Extension ist nicht für jeden Anwendungsfall sinnvoll. Sie lohnt sich, wenn:

  • das Projekt bereits auf TYPO3 basiert und ein einheitliches Nutzermanagement wichtig ist
  • das Wiki Teil einer bestehenden Website sein soll – nicht ein separates Tool daneben
  • Datenschutz und Datenhaltung auf dem eigenen Server Pflicht sind
  • die Anforderungen überschaubar und stabil sind (kein kollaboratives Echtzeit-Editing à la Notion)

Für Teams, die komplexes kollaboratives Schreiben in Echtzeit, umfangreiche Plugin-Ökosysteme oder sofort einsatzbereite mobile Apps brauchen, sind spezialisierte Lösungen wie BookStack oder Confluence nach wie vor die bessere Wahl.

Fazit

TYPO3 als Wiki-Plattform ist kein Workaround – es ist eine echte Architekturentscheidung, die in bestimmten Kontexten mehr Sinn ergibt als jedes fertige Tool. Die technischen Herausforderungen – cHash-Handling, PSR-7-Request-Parsing, Fluid-Eigenheiten, robuste Suche – sind lösbar und lehrreich.

Wer bereits TYPO3 betreibt, sollte die Option einer eigenen Extension nicht vorschnell ausschließen. Manchmal ist das sauberste System das, das man selbst unter Kontrolle hat.

Habt ihr ähnliche Projekte umgesetzt oder interessiert ihr euch für bestimmte Teile der Architektur? Ich freue mich über Kommentare.

Leave a comment