Inhaltsverzeichnis
WvdS.DokuWiki.AcMenu Plugin
Plugin: wvdsacmenu
Version: 1.4.0
Namespace: lib/plugins/wvdsacmenu/
Basis: AcMenu von Torpedo
Erweiterungen: Wolfgang van der Stille zeljko.petrusic@outlook.de
Lizenz: GPL 2
Definition
Das wvdsacmenu Plugin zeigt ein Akkordeon-Menü für Namespaces und Seiten. Es erweitert das Original-AcMenu um Wiki-Syntax, dynamische Namespace-Erkennung, Lazy Loading, ACL-aware Navigation und mehrsprachige Unterstützung.
Motivation
Das Problem mit Standard-Navigation
DokuWiki-Standardnavigation und das Original-AcMenu haben in Enterprise-Umgebungen mehrere Einschränkungen:
- ACL-Blindheit: Wenn
sneaky_index=1aktiv ist, werden geschützte Ordner komplett ausgeblendet - auch wenn tiefer öffentliche Inhalte existieren - Keine Lazy Loading: Bei großen Dokumentationsstrukturen (100+ Seiten) wird die Sidebar langsam und unübersichtlich
- Sprach-Isolation: Mehrsprachige Wikis benötigen manuelle Konfiguration pro Namespace
- Keine Template-Integration: Die Sidebar-Auswahl ist statisch und kennt keine Namespace-Hierarchie
Beispiel: Öffentlicher Pfad in geschütztem Bereich
ACL-Konfiguration:
de:int:* @ALL 0 (gesperrt)
de:int:vsce:fpc:p:* @ALL 1 (öffentlich)
Standard-AcMenu Ergebnis:
📂 de
📁 pub ← sichtbar
(vsce fehlt!) ← PROBLEM: gesamter Pfad ist versteckt
wvdsacmenu Ergebnis:
📂 de
📁 pub
📂 int
📂 vsce ← partial (kein Link)
📂 fpc ← partial (kein Link)
📁 p ← sichtbar und navigierbar
Der Benutzer sieht den Pfad zu öffentlichen Inhalten, auch wenn dazwischenliegende Ordner nicht direkt lesbar sind.
Ziele
Enterprise-Navigation
wvdsacmenu wurde für komplexe Dokumentationsstrukturen mit differenzierten Zugriffsrechten entwickelt:
| Anforderung | Lösung |
|---|---|
| Große Strukturen | Lazy Loading (dynamic=„N“) |
| Differenzierte ACLs | Partial Namespaces, ACL-aware „Go Up“ |
| Mehrsprachigkeit | Automatische Sprach-Erkennung, ns=„auto“ |
| Performance | Server-seitige Cookie-Wiederherstellung |
| UX | Total Commander Modus, FontAwesome Icons |
Vergleich mit Original-AcMenu
| Feature | Original AcMenu | wvdsacmenu |
|---|---|---|
| ACL-Unterstützung | Nur read/hide | Partial Namespaces, tiefe Pfade |
| Lazy Loading | Nein | Ja (AJAX) |
| Cookie-Wiederherstellung | Nur Client | Server + Client |
| Mehrsprachigkeit | Manuell | Automatisch (ns=„auto“) |
| Icons | Nein | FontAwesome |
| Template-Integration | Nein | Namespace-aware Sidebar |
| „Go Up“ Navigation | Nein | ACL-basiert |
| Unsichtbarer Titel | Nein | {{wvds:title>...}} |
Design-Prinzipien
- Minimal Disclosure: Zeige nur was der Benutzer sehen darf, aber zeige den Pfad dorthin
- Progressive Loading: Lade initial wenig, erweitere bei Bedarf
- Stateless Recovery: Cookie-Zustand wird Server-seitig wiederhergestellt (kein Flackern)
- Deep Integration: Das Plugin arbeitet eng mit Template und ACL-System zusammen
Anwendungsfälle
- Namespace-Navigation - Automatisches Menü für Dokumentationsstruktur
- Mehrsprachige Wikis - Separate Menüs pro Sprach-Namespace
- Projektdokumentation - Hierarchische Navigation in Unter-Namespaces
- Sidebar-Integration - Kompakte Navigation in der Seitenleiste
- Performance-Optimierung - Lazy Loading für große Menüstrukturen
- ACL-aware Navigation - Zeigt Ordner auch wenn nur Teile lesbar sind
Syntax
Menü-Syntax
{{wvds:acmenu>}}
{{wvds:acmenu>ns=namespace}}
{{wvds:acmenu>dynamic=N}}
{{wvds:acmenu>startns=current|icons=fa}}
Syntax-Änderung (v1.4): Das > nach wvds:acmenu ist pflicht, um Konflikte mit DokuWikis Media-Syntax zu vermeiden. Parameter werden mit | getrennt.
Titel-Syntax (Unsichtbarer Titel)
{{wvds:title>Mein Seitentitel}}
Definiert einen Titel für die Seite, der im Menü angezeigt wird, ohne sichtbar auf der Seite zu erscheinen. Nützlich für Seiten mit Hero-Sections oder speziellen Layouts.
Parameter
| Parameter | Typ | Standard | Beschreibung |
|---|---|---|---|
ns | string | (auto) | Namespace für das Menü (siehe unten) |
dynamic | integer | 1 | Anzahl der vorgeladenen Ebenen (Lazy Loading) |
startns | string | (auto) | current = Start beim aktuellen Namespace mit „Nach oben“-Link |
icons | string | none | fa = FontAwesome Icons für Ordner/Dateien |
ns-Parameter Werte:
| Wert | Beschreibung |
|---|---|
ns=„de:docs“ | Expliziter Namespace |
ns=„auto“ | Smart Auto: Fokussierte Ansicht + Geschwister mit Partial Content |
| (leer) | Automatische Erkennung via Sidebar-Position |
Parameter-Details
ns - Expliziter Namespace
Zeigt einen bestimmten Namespace unabhängig von der aktuellen Seite:
{{wvds:acmenu>ns=de:crypto}}
{{wvds:acmenu>ns=de:docs:api}}
dynamic - Lazy Loading Tiefe
Steuert wie viele Ebenen initial geladen werden. Tiefere Ebenen werden per AJAX nachgeladen:
| Wert | Verhalten |
|---|---|
dynamic=„0“ | Nur Seiten anzeigen (keine Unterordner) |
dynamic=„1“ | 1 Ebene vorgeladen, Rest per AJAX (Standard) |
dynamic=„2“ | 2 Ebenen vorgeladen, Rest per AJAX |
dynamic=„3“ | 3 Ebenen vorgeladen, Rest per AJAX |
Wichtig: Der Namespace wird immer relativ zur Sidebar-Position berechnet, nicht zur aktuellen Seite.
startns - Total Commander Modus
Ähnlich wie Total Commander: Zeigt nur den aktuellen Namespace mit einem „Nach oben“-Link:
{{wvds:acmenu>startns=current}}
{{wvds:acmenu>startns=current|dynamic=2}}
| Wert | Verhalten |
|---|---|
startns=„current“ | Startet beim Namespace der aktuellen Seite |
| (kombiniert mit dynamic) | Begrenzt die Tiefe wie gewohnt |
Vorteile:
- Übersichtlicher bei großen Strukturen
- Fokus auf den aktuellen Bereich
- „Nach oben“-Link zur Navigation
icons - FontAwesome Icons
Aktiviert visuelle Icons für Ordner und Dateien:
{{wvds:acmenu>icons=fa}}
{{wvds:acmenu>startns=current|icons=fa}}
| Icon | Element | FA-Klasse |
|---|---|---|
| 📁 | Geschlossener Ordner | fa-folder-o |
| 📂 | Geöffneter Ordner | fa-folder-open-o |
| 📄 | Seite/Dokument | fa-file-text-o |
| ↗ | Externer Namespace | fa-external-link |
| ↑ | Nach oben | fa-level-up |
Voraussetzung: FontAwesome muss im Template geladen sein (im flat Template bereits enthalten).
ns="auto" - Smart Auto Modus
Der auto-Modus kombiniert fokussierte Navigation mit ACL-aware Geschwister-Erkennung:
{{wvds:acmenu>ns=auto|icons=fa|dynamic=1}}
Funktionsweise:
- Fokussierte Ansicht: Startet beim aktuellen Namespace (wie
startns=„current“) - ACL-aware „Go Up“: Link zum Home-Namespace des Benutzers basierend auf ACL-Regeln
- Geschwister mit Partial Content: Zeigt andere Namespaces auf Sprach-Ebene, die lesbaren Inhalt haben
- Kombinierbar mit
dynamicfür Lazy Loading
Unterschied zu startns=„current“:
| Modus | Verhalten |
|---|---|
startns=„current“ | Nur aktueller Namespace + „Go Up“ zum Parent |
ns=„auto“ | Aktueller Namespace + „Go Up“ zum Home + alle Geschwister mit Partial Content |
Anwendungsfall: Eine einzige sidebar1.txt für alle Namespaces einer Sprache:
# de/sidebar1.txt (funktioniert für de:pub:*, de:int:*, etc.)
~~NOCACHE~~
{{wvds:acmenu>ns=auto|icons=fa|dynamic=1}}
Beispiel 1: Anonymer Benutzer auf de:pub:start
ACL: de:int:vsce:fpc:p:* ist öffentlich, Rest von de:int:* ist gesperrt
↑ .. ← Go Up (entfällt wenn schon am Home)
📂 pub ← aktueller Namespace (fokussiert)
📄 start
📁 services
📂 int ← Geschwister mit Partial Content
📂 vsce ← partial (klickbar zum Expandieren)
📂 fpc ← partial
📁 p ← lesbar
Beispiel 2: Anonymer Benutzer auf de:int:vsce:fpc:p:start
↑ .. ← Go Up zu de:pub:start (Home für @ALL) 📁 p ← aktueller Namespace (fokussiert) 📄 start 📄 download
Beispiel 3: @user auf de:int:dwe:start
↑ .. ← Go Up zu de:int:start (Home für @user) 📁 dwe ← aktueller Namespace (fokussiert) 📄 start 📁 wvdsacmenu 📁 wvdssnippet 📁 vsce ← Geschwister (vollständig lesbar) 📁 pqcrypt ← Geschwister (vollständig lesbar)
Warum Smart Auto?
| Problem | Lösung |
| Große Strukturen überfordern | Fokussierte Ansicht zeigt nur relevanten Bereich |
| „Go Up“ führt zu gesperrten Seiten | ACL-aware: Link führt immer zu lesbarem Namespace |
| Öffentliche Pfade in geschützten Bereichen unsichtbar | Geschwister mit Partial Content werden angezeigt |
| Benutzer verliert Orientierung | Immer sichtbar: aktueller Ort + erreichbare Alternativen |
Lazy Loading
Funktionsweise
- Beim Laden der Seite werden nur die ersten
NEbenen (dynamic) gerendert - Ordner am Tiefenlimit erhalten die CSS-Klasse
lazy - Beim Klick auf einen
lazy-Ordner wird der Inhalt per AJAX geladen - Der Ladezustand wird durch die Klasse
loadingangezeigt
Cookie-Wiederherstellung
Geöffnete Ordner werden im Cookie gespeichert. Beim nächsten Seitenaufruf werden diese Ordner server-seitig vorgeladen, auch wenn sie tiefer als dynamic liegen. Dies verhindert ein „Flackern“ beim Laden.
AJAX-Endpoint
GET /lib/exe/ajax.php?call=plugin_wvdsacmenu_load&ns=de:crypto:subfolder
Response:
{ "success": true, "html": "<li>...</li>", "ns": "de:crypto:subfolder" }
Namespace-Erkennung
Sidebar-Grenz-Erkennung
Das Plugin erkennt Namespace-Grenzen durch sidebar* Dateien:
sidebar.txtsidebar1.txtsidebar2.txtsidebar_name.txt
Erkennungs-Logik
1. Ohne Parameter └── Sucht aufwärts nach sidebar* Datei └── Startet Menü ab diesem Namespace 2. Mit ns="..." └── Verwendet den angegebenen Namespace direkt 3. Mit dynamic="N" └── Findet Sidebar-Namespace └── Lädt N Ebenen vor, Rest per AJAX
ACL-aware Navigation
Das Plugin berücksichtigt DokuWiki-ACL-Regeln und zeigt Ordner intelligent an, auch wenn nicht alle Inhalte für den Benutzer lesbar sind.
Partial Namespaces
Wenn sneaky_index aktiviert ist und ein Ordner nicht direkt lesbar ist (z.B. de:int:vsce:start für anonyme Benutzer), aber lesbare Inhalte tiefer im Baum existieren (z.B. de:int:vsce:fpc:p:*), wird der Ordner trotzdem angezeigt:
📂 vsce ← partial (kein Link, nur Label)
📂 fpc ← partial (kein Link, nur Label)
📁 p ← normal (Link zu p:start)
📄 start
📄 download
Verhalten:
- Ordner mit
partialKlasse zeigen nur ein Label (kein Link zur Start-Seite) - Klickbar: Ein Klick auf den Ordner expandiert/kollabiert die Kinder
- Der Ordner ist initial geöffnet, um lesbare Kinder zu zeigen
- Styling kann per CSS angepasst werden
ACL-basiertes "Go Up"
Bei startns=„current“ springt der „Nach oben“-Link nicht einfach zum Parent-Namespace, sondern zum Home-Namespace des Benutzers basierend auf ACL-Regeln:
| Benutzer | ACL-Regel | „Go Up“ Ziel |
|---|---|---|
| Anonym (@ALL) | de:pub:* @ALL 1 | de:pub:start |
| @user Gruppe | de:int:* @user 1 | de:int:start |
| @wvdse Gruppe | de:int:* @wvdse 8 | de:int:start |
Priorität:
- Namespace-Wildcards (z.B.
de:pub:*) haben Vorrang - Einzelne Seiten-ACLs (z.B.
de:int:start) sind nachrangig - Der kürzeste (höchste) Namespace wird bevorzugt
Beispiel: Ein anonymer Benutzer auf de:int:vsce:fpc:p:start sieht den „Go Up“-Link zu de:pub:start, nicht zu de:int:start.
Template-Integration
Das flat Template lädt Sidebar-Seiten namespace-spezifisch.
Namespace-aware Sidebar Loading
Das Template sucht die Sidebar-Datei (z.B. sidebar1.txt) ausgehend vom aktuellen Namespace aufwärts:
Seite: de:int:vsce:fpc:p:start Suche nach sidebar1.txt: 1. de:int:vsce:fpc:p:sidebar1 → nicht gefunden 2. de:int:vsce:fpc:sidebar1 → nicht gefunden 3. de:int:vsce:sidebar1 → nicht gefunden 4. de:int:sidebar1 → GEFUNDEN ✓
Ergebnis: Für de:int:* Seiten wird de:int:sidebar1.txt geladen, für de:pub:* Seiten wird de:sidebar1.txt geladen.
ACL für Sidebars
Sidebar-Seiten in geschützten Namespaces müssen für @ALL lesbar sein, damit die Navigation funktioniert!
Beispiel ACL-Einträge:
de:int:sidebar @ALL 1 de:int:sidebar1 @ALL 1 de:int:sidebar2 @ALL 1
Unsichtbarer Titel
Für Seiten ohne sichtbaren Titel (z.B. Landing Pages mit Hero-Section) kann ein Menü-Titel definiert werden:
~~NOTOC~~
{{wvds:title>NIS2 Compliance Check}}
{{wvds:snippet>nis2check_hero}}
{{wvds:snippet>nis2check_content}}
Der Titel wird:
- Im Menü angezeigt
- In den Metadaten gespeichert
- Nicht auf der Seite gerendert
Titel-Priorität
Das Menü verwendet Titel in folgender Reihenfolge:
{{wvds:title>...}}(Unsichtbarer Titel)- Erste Überschrift der Seite (wenn
useheadingaktiviert) - Seiten-ID als Fallback
Beispiele
Beispiel 1: Automatisches Menü
sidebar1.txt:
~~NOCACHE~~
{{wvds:snippet>go_back}}
{{wvds:acmenu>}}
Beispiel 2: Empfohlene Konfiguration (ns="auto")
Eine einzige Sidebar-Datei für alle Namespaces einer Sprache:
de/sidebar1.txt:
~~NOCACHE~~
{{wvds:acmenu>ns=auto|icons=fa|dynamic=1}}
Diese Konfiguration:
- Fokussiert: Zeigt primär den aktuellen Namespace
- Smart „Go Up“: Link zum ACL-basierten Home-Namespace
- Geschwister-Erkennung: Zeigt andere Namespaces mit lesbarem Content
- Partial Namespaces: Pfade zu öffentlichen Bereichen in geschützten Zonen
- Nutzt FontAwesome Icons
- Lädt nur 1 Ebene initial, Rest per AJAX
Beispiel 3: Klassische Konfiguration
de/sidebar1.txt:
~~NOCACHE~~
{{wvds:snippet>go_back}}
{{wvds:acmenu>dynamic=2}}
Beispiel 4: Expliziter Namespace
{{wvds:acmenu>ns=de:api}}
Beispiel 5: Total Commander Modus
Für große Strukturen - zeigt nur den aktuellen Bereich mit „Nach oben“-Link:
{{wvds:acmenu>startns=current|icons=fa}}
Ergebnis (bei Seite de:crypto:openssl:start):
↑ .. 📂 openssl 📄 start 📁 commands 📄 examples
Beispiel 6: Kompaktes Icon-Menü
{{wvds:acmenu>startns=current|dynamic=1|icons=fa}}
CSS-Klassen
| Klasse | Beschreibung |
|---|---|
.acmenu | Haupt-Container |
.acmenu-icons | Container mit FontAwesome Icons |
.acmenu-up | „Nach oben“-Link (startns=current) |
.open | Geöffneter Ordner |
.closed | Geschlossener Ordner |
.partial | Ordner mit nur teilweise lesbarem Inhalt (ACL) |
.ns-label | Label ohne Link (für partial_ns Ordner) |
.curid | Aktuelle Seite |
.divert | Externer Namespace |
.lazy | Ordner mit noch nicht geladenen Inhalten |
.loading | Ordner wird gerade per AJAX geladen |
Styling für Partial Namespaces
/* Partial Namespaces - klickbar zum Expandieren */ div.acmenu li.partial > div.li { cursor: pointer; } div.acmenu li.partial > div.li .ns-label { color: #666; font-style: italic; } /* Icon-Farbe für partial Ordner */ div.acmenu.acmenu-icons li.partial > div.li .fa { color: #999; }
Partial Namespaces sind klickbar und expandieren/kollabieren beim Anklicken, genau wie normale Ordner. Der Unterschied ist nur, dass sie keinen Link zur Start-Seite haben (weil diese nicht lesbar ist).
Styling für Lazy Loading
/* Lade-Indikator */ div.acmenu li.loading > div.li:after { content: " ⟳"; animation: spin 1s linear infinite; } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* Lazy-Ordner visuell markieren */ div.acmenu li.lazy > div.li { cursor: pointer; }
Konfiguration
| Einstellung | Typ | Standard | Beschreibung |
|---|---|---|---|
startOpen | An/Aus | Aus | Alle Ordner standardmäßig öffnen |
sortType | Auswahl | alpha | Sortierung |
showPageTitle | An/Aus | An | Seitentitel statt ID |
maxDepth | Zahl | 0 | Max. Tiefe (0 = unbegrenzt) |
Cookie-Speicherung
Geöffnete Ordner werden im Cookie plugin_wvdsacmenu_open_items gespeichert.
Cookie-Format
// Cookie-Name plugin_wvdsacmenu_open_items // Wert (JSON-Array) ["de:crypto:start","de:docs:api:start"]
Server-seitige Wiederherstellung
Beim Rendern liest das Plugin den Cookie und lädt alle dort gespeicherten Ordner vor - auch wenn sie tiefer als dynamic liegen. Dies stellt den Menüzustand ohne JavaScript-Flackern wieder her.
Versionshinweise
| Version | Datum | Änderungen |
|---|---|---|
| 1.4.0 | 2026-01-30 | Syntax-Änderung: > nach wvds:acmenu pflicht (vermeidet Media-Syntax-Konflikt), pipe-separierte Parameter |
| 1.3.0 | 2026-01-29 | ACL-aware Navigation: ns=„auto“ Smart Auto Modus (fokussiert + Geschwister mit Partial Content), Partial Namespaces (partial_ns), ACL-basiertes „Go Up“ zu Home-Namespace, _hasPartialChildren() für automatische Expansion, _renderAutoSiblings() für Geschwister-Erkennung |
| 1.2.0 | 2026-01-29 | startns=„current“ (Total Commander Modus), icons=„fa“ (FontAwesome Icons) |
| 1.1.0 | 2026-01-29 | Lazy Loading, Cookie-Wiederherstellung, {{wvds:title>...}} Syntax |
| 1.0.0 | 2025-01-06 | WvdS-Erweiterungen: Wiki-Syntax, mehrsprachige Unterstützung |
Siehe auch
- WvdS.DokuWiki.Snippet Plugin - HTML-Bausteine
- WvdS.DokuWiki.i18n Plugin - Mehrsprachige Texte
- WvdS.DokuWiki.Flat Template - Template mit Sidebar
Technische Referenz
Klasse: syntax_plugin_wvdsacmenu
Datei: lib/plugins/wvdsacmenu/syntax.php
| Methode | Beschreibung |
|---|---|
getType() | Gibt substitution zurück |
getSort() | Gibt 320 zurück |
_findSidebar() | Sucht sidebar* Datei |
_tree() | Baut Menü-Baum (mit Lazy-Support und partial_ns) |
_hasReadableContent() | Prüft ob lesbare Inhalte im Namespace existieren |
_hasPartialChildren() | Prüft ob Namespace partial_ns Kinder enthält |
_findUserHomeNamespace() | Findet Home-Namespace basierend auf ACL |
_renderAutoSiblings() | Rendert Geschwister-Namespaces mit Partial Content (für ns=„auto“) |
_shouldForceLoad() | Prüft ob Namespace per Cookie wiederhergestellt werden soll |
_getPageTitle() | Holt Seitentitel (wvds:title > heading > ID) |
buildSubTree() | Öffentlich: Baut Unter-Baum für AJAX |
renderSubTree() | Öffentlich: Rendert Unter-Baum als HTML |
Template-Funktion: tpl_findSidebarInNamespace()
Datei: lib/tpl/flat/lang_helper.php
| Parameter | Typ | Beschreibung |
|---|---|---|
$sidebarName | string | Name der Sidebar-Datei (z.B. sidebar1) |
| Return | string/null | Volle Page-ID oder null wenn nicht gefunden |
Sucht eine Sidebar-Datei ausgehend vom aktuellen Namespace aufwärts.
Klasse: action_plugin_wvdsacmenu
Datei: lib/plugins/wvdsacmenu/action.php
| Methode | Beschreibung |
|---|---|
_add_user_conf() | Konfiguration für JavaScript (JSINFO) |
_ajax_load_ns() | AJAX-Handler für Lazy Loading |
JavaScript: script.js
Datei: lib/plugins/wvdsacmenu/script.js
| Funktion | Beschreibung |
|---|---|
get_cookie() | Liest geöffnete Items aus Cookie |
set_cookie() | Speichert geöffnete Items |
saveCookie() | Aktualisiert Cookie nach Änderung |
trim_url() | Extrahiert Page-ID aus URL |
handleLazyLoad() | AJAX-Laden von Ordnerinhalten |
toggleItem() | Öffnet/schließt einen Ordner |
hasIcons() | Prüft ob Icons aktiviert sind |
updateFolderIcon() | Wechselt Ordner-Icon beim Öffnen/Schließen |
Diskussion