Inhaltsverzeichnis

WvdS.DokuWiki.AcMenu Plugin

Plugin: wvdsacmenu
Versione: 1.3.0
Namespace: lib/plugins/wvdsacmenu/
Base: AcMenu di Torpedo
Estensioni: Wolfgang van der Stille zeljko.petrusic@outlook.de
Licenza: GPL 2


Definizione

Il plugin wvdsacmenu mostra un menu ad accordion per namespace e pagine. Estende l'AcMenu originale con sintassi wiki, rilevamento namespace dinamico, lazy loading, navigazione ACL-aware e supporto multilingue.


Motivazione

Il problema con la navigazione standard

La navigazione standard DokuWiki e l'AcMenu originale hanno diverse limitazioni in ambienti enterprise:

Esempio: Percorso pubblico in area protetta

Configurazione ACL:
  de:int:*                @ALL  0   (bloccato)
  de:int:vsce:fpc:p:*     @ALL  1   (pubblico)

Risultato AcMenu standard:
  📂 de
     📁 pub          ← visibile
     (vsce manca!)   ← PROBLEMA: intero percorso nascosto

Risultato wvdsacmenu:
  📂 de
     📁 pub
     📂 int
        📂 vsce      ← partial (nessun link)
           📂 fpc    ← partial (nessun link)
              📁 p   ← visibile e navigabile

L'utente vede il percorso verso contenuti pubblici, anche se le cartelle intermedie non sono direttamente leggibili.


Obiettivi

wvdsacmenu è stato sviluppato per strutture documentali complesse con permessi di accesso differenziati:

Requisito Soluzione
Grandi strutture Lazy loading (dynamic=„N“)
ACL differenziati Partial namespace, ACL-aware „Vai su“
Multilingue Rilevamento lingua automatico, ns=„auto“
Performance Ripristino cookie lato server
UX Modalità Total Commander, icone FontAwesome

Confronto con AcMenu originale

Funzione AcMenu originale wvdsacmenu
Supporto ACL Solo read/hide Partial namespace, percorsi profondi
Lazy loading No Sì (AJAX)
Ripristino cookie Solo client Server + client
Multilingue Manuale Automatico (ns=„auto“)
Icone No FontAwesome
Integrazione template No Sidebar namespace-aware
Navigazione „Vai su“ No Basata su ACL
Titolo invisibile No {{wvds:title>...}}

Principi di design

  1. Minima divulgazione: Mostra solo ciò che l'utente può vedere, ma mostra il percorso per arrivarci
  2. Caricamento progressivo: Carica poco inizialmente, espandi su richiesta
  3. Ripristino stateless: Lo stato cookie viene ripristinato lato server (nessun flicker)
  4. Integrazione profonda: Il plugin lavora strettamente con template e sistema ACL

Casi d'uso


Sintassi

Sintassi menu

{{wvds:acmenu}}
{{wvds:acmenu ns="namespace"}}
{{wvds:acmenu dynamic="N"}}
{{wvds:acmenu startns="current" icons="fa"}}

Sintassi titolo (titolo invisibile)

{{wvds:title>Titolo della mia pagina}}

Definisce un titolo per la pagina mostrato nel menu, senza apparire visibile sulla pagina. Utile per pagine con hero section o layout speciali.

Parametri

Parametro Tipo Default Descrizione
ns string (auto) Namespace per il menu (vedi sotto)
dynamic integer 1 Numero livelli precaricati (lazy loading)
startns string (auto) current = Inizia dal namespace corrente con link „Vai su“
icons string none fa = Icone FontAwesome per cartelle/file

Valori parametro ns:

Valore Descrizione
ns=„de:docs“ Namespace esplicito
ns=„auto“ Smart Auto: Vista focalizzata + fratelli con contenuto parziale
(vuoto) Rilevamento automatico via posizione sidebar

Dettagli parametri

ns - Namespace esplicito

Mostra un namespace specifico indipendentemente dalla pagina corrente:

{{wvds:acmenu ns="it:crypto"}}
{{wvds:acmenu ns="it:docs:api"}}

dynamic - Profondità lazy loading

Controlla quanti livelli vengono caricati inizialmente. Livelli più profondi vengono caricati via AJAX:

Valore Comportamento
dynamic=„0“ Mostra solo pagine (nessuna sottocartella)
dynamic=„1“ 1 livello precaricato, resto via AJAX (default)
dynamic=„2“ 2 livelli precaricati, resto via AJAX
dynamic=„3“ 3 livelli precaricati, resto via AJAX

Importante: Il namespace viene sempre calcolato relativamente alla posizione sidebar, non alla pagina corrente.

startns - Modalità Total Commander

Simile a Total Commander: Mostra solo il namespace corrente con link „Vai su“:

{{wvds:acmenu startns="current"}}
{{wvds:acmenu startns="current" dynamic="2"}}
Valore Comportamento
startns=„current“ Inizia dal namespace della pagina corrente
(combinato con dynamic) Limita la profondità come al solito

Vantaggi:

icons - Icone FontAwesome

Attiva icone visive per cartelle e file:

{{wvds:acmenu icons="fa"}}
{{wvds:acmenu startns="current" icons="fa"}}
Icona Elemento Classe FA
📁 Cartella chiusa fa-folder-o
📂 Cartella aperta fa-folder-open-o
📄 Pagina/Documento fa-file-text-o
Namespace esterno fa-external-link
Vai su fa-level-up

Prerequisito: FontAwesome deve essere caricato nel template (già incluso nel template flat).

ns="auto" - Modalità Smart Auto

La modalità auto combina navigazione focalizzata con rilevamento fratelli ACL-aware:

{{wvds:acmenu ns="auto" icons="fa" dynamic="1"}}

Funzionamento:

  1. Vista focalizzata: Inizia dal namespace corrente (come startns=„current“)
  2. „Vai su“ ACL-aware: Link al namespace home dell'utente basato su regole ACL
  3. Fratelli con contenuto parziale: Mostra altri namespace a livello lingua che hanno contenuto leggibile
  4. Combinabile con dynamic per lazy loading

Differenza da startns=„current“:

Modalità Comportamento
startns=„current“ Solo namespace corrente + „Vai su“ al parent
ns=„auto“ Namespace corrente + „Vai su“ a home + tutti i fratelli con contenuto parziale

Caso d'uso: Una sola sidebar1.txt per tutti i namespace di una lingua:

# it/sidebar1.txt (funziona per it:pub:*, it:int:*, ecc.)
~~NOCACHE~~
{{wvds:acmenu ns="auto" icons="fa" dynamic="1"}}

Esempio 1: Utente anonimo su it:pub:start

ACL: it:int:vsce:fpc:p:* è pubblico, resto di it:int:* è bloccato

↑ ..                    ← Vai su (omesso se già a home)
📂 pub                  ← namespace corrente (focalizzato)
   📄 start
   📁 services
📂 int                  ← fratello con contenuto parziale
   📂 vsce              ← partial (cliccabile per espandere)
      📂 fpc            ← partial
         📁 p           ← leggibile

Esempio 2: Utente anonimo su it:int:vsce:fpc:p:start

↑ ..                    ← Vai su a it:pub:start (home per @ALL)
📁 p                    ← namespace corrente (focalizzato)
   📄 start
   📄 download

Esempio 3: @user su it:int:dwe:start

↑ ..                    ← Vai su a it:int:start (home per @user)
📁 dwe                  ← namespace corrente (focalizzato)
   📄 start
   📁 wvdsacmenu
   📁 wvdssnippet
📁 vsce                 ← fratello (completamente leggibile)
📁 pqcrypt              ← fratello (completamente leggibile)

Perché Smart Auto?

Problema Soluzione
Grandi strutture sovraccaricano Vista focalizzata mostra solo area rilevante
„Vai su“ porta a pagine bloccate ACL-aware: link porta sempre a namespace leggibile
Percorsi pubblici in aree protette invisibili Fratelli con contenuto parziale vengono mostrati
Utente perde orientamento Sempre visibile: posizione corrente + alternative raggiungibili

Lazy loading

Funzionamento

  1. Al caricamento pagina vengono renderizzati solo i primi N livelli (dynamic)
  2. Cartelle al limite di profondità ricevono classe CSS lazy
  3. Al click su cartella lazy il contenuto viene caricato via AJAX
  4. Lo stato di caricamento viene indicato dalla classe loading

Le cartelle aperte vengono salvate nel cookie. Al prossimo caricamento pagina queste cartelle vengono precaricate lato server, anche se sono più profonde di dynamic. Questo impedisce „flicker“ al caricamento.

Endpoint AJAX

GET /lib/exe/ajax.php?call=plugin_wvdsacmenu_load&ns=it:crypto:subfolder

Risposta:

{
  "success": true,
  "html": "<li>...</li>",
  "ns": "it:crypto:subfolder"
}

Rilevamento namespace

Rilevamento confine sidebar

Il plugin riconosce i confini namespace tramite file sidebar*:

Logica di rilevamento

1. Senza parametro
   └── Cerca verso l'alto file sidebar*
   └── Avvia menu da quel namespace

2. Con ns="..."
   └── Usa il namespace specificato direttamente

3. Con dynamic="N"
   └── Trova namespace sidebar
   └── Carica N livelli in anticipo, resto via AJAX

Il plugin considera le regole ACL DokuWiki e mostra le cartelle in modo intelligente, anche se non tutti i contenuti sono leggibili per l'utente.

Partial namespace

Quando sneaky_index è attivato e una cartella non è direttamente leggibile (es. it:int:vsce:start per utenti anonimi), ma contenuti leggibili esistono più in profondità nell'albero (es. it:int:vsce:fpc:p:*), la cartella viene comunque mostrata:

📂 vsce          ← partial (nessun link, solo etichetta)
   📂 fpc        ← partial (nessun link, solo etichetta)
      📁 p       ← normale (link a p:start)
         📄 start
         📄 download

Comportamento:

"Vai su" basato su ACL

Con startns=„current“ il link „Vai su“ non salta semplicemente al namespace parent, ma al namespace home dell'utente basato su regole ACL:

Utente Regola ACL Destinazione „Vai su“
Anonimo (@ALL) it:pub:* @ALL 1 it:pub:start
Gruppo @user it:int:* @user 1 it:int:start
Gruppo @wvdse it:int:* @wvdse 8 it:int:start

Priorità:

  1. Wildcard namespace (es. it:pub:*) hanno precedenza
  2. ACL singole pagine (es. it:int:start) sono secondari
  3. Viene preferito il namespace più corto (più alto)

Esempio: Un utente anonimo su it:int:vsce:fpc:p:start vede il link „Vai su“ a it:pub:start, non a it:int:start.


Integrazione template

Il template flat carica le pagine sidebar specifiche per namespace.

Caricamento sidebar namespace-aware

Il template cerca il file sidebar (es. sidebar1.txt) partendo dal namespace corrente verso l'alto:

Pagina: it:int:vsce:fpc:p:start

Ricerca sidebar1.txt:
1. it:int:vsce:fpc:p:sidebar1 → non trovato
2. it:int:vsce:fpc:sidebar1   → non trovato
3. it:int:vsce:sidebar1       → non trovato
4. it:int:sidebar1            → TROVATO ✓

Risultato: Per pagine it:int:* viene caricato it:int:sidebar1.txt, per pagine it:pub:* viene caricato it:sidebar1.txt.

ACL per sidebar

Le pagine sidebar in namespace protetti devono essere leggibili per @ALL affinché la navigazione funzioni!

Esempio voci ACL:

it:int:sidebar         @ALL    1
it:int:sidebar1        @ALL    1
it:int:sidebar2        @ALL    1

Titolo invisibile

Per pagine senza titolo visibile (es. landing page con hero section) può essere definito un titolo per il menu:

~~NOTOC~~
{{wvds:title>Verifica conformità NIS2}}

{{wvds:snippet>nis2check_hero}}
{{wvds:snippet>nis2check_content}}

Il titolo viene:

Priorità titolo

Il menu usa titoli nel seguente ordine:

  1. {{wvds:title>...}} (Titolo invisibile)
  2. Primo heading della pagina (se useheading attivato)
  3. ID pagina come fallback

Esempi

Esempio 1: Menu automatico

sidebar1.txt:

~~NOCACHE~~
{{wvds:snippet>go_back}}
{{wvds:acmenu}}

Esempio 2: Configurazione consigliata (ns="auto")

Un solo file sidebar per tutti i namespace di una lingua:

it/sidebar1.txt:

~~NOCACHE~~
{{wvds:acmenu ns="auto" icons="fa" dynamic="1"}}

Questa configurazione:

Esempio 3: Configurazione classica

it/sidebar1.txt:

~~NOCACHE~~
{{wvds:snippet>go_back}}
{{wvds:acmenu dynamic="2"}}

Esempio 4: Namespace esplicito

{{wvds:acmenu ns="it:api"}}

Esempio 5: Modalità Total Commander

Per grandi strutture - mostra solo l'area corrente con link „Vai su“:

{{wvds:acmenu startns="current" icons="fa"}}

Risultato (per pagina it:crypto:openssl:start):

↑ ..
📂 openssl
   📄 start
   📁 commands
   📄 examples

Esempio 6: Menu compatto con icone

{{wvds:acmenu startns="current" dynamic="1" icons="fa"}}

Classi CSS

Classe Descrizione
.acmenu Container principale
.acmenu-icons Container con icone FontAwesome
.acmenu-up Link „Vai su“ (startns=current)
.open Cartella aperta
.closed Cartella chiusa
.partial Cartella con contenuto solo parzialmente leggibile (ACL)
.ns-label Etichetta senza link (per cartelle partial_ns)
.curid Pagina corrente
.divert Namespace esterno
.lazy Cartella con contenuti non ancora caricati
.loading Cartella in caricamento via AJAX

Styling per partial namespace

/* Partial namespace - cliccabile per espandere */
div.acmenu li.partial > div.li {
    cursor: pointer;
}
 
div.acmenu li.partial > div.li .ns-label {
    color: #666;
    font-style: italic;
}
 
/* Colore icona per cartelle partial */
div.acmenu.acmenu-icons li.partial > div.li .fa {
    color: #999;
}

I partial namespace sono cliccabili e si espandono/comprimono al click, esattamente come le cartelle normali. L'unica differenza è che non hanno link alla pagina start (perché non è leggibile).

Styling per lazy loading

/* Indicatore caricamento */
div.acmenu li.loading > div.li:after {
    content: " ⟳";
    animation: spin 1s linear infinite;
}
 
@keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}
 
/* Marcatura visiva cartelle lazy */
div.acmenu li.lazy > div.li {
    cursor: pointer;
}

Configurazione

Impostazione Tipo Default Descrizione
startOpen On/Off Off Tutte le cartelle aperte di default
sortType Scelta alpha Ordinamento
showPageTitle On/Off On Titolo pagina invece di ID
maxDepth Numero 0 Profondità max (0 = illimitata)

Le cartelle aperte vengono salvate nel cookie plugin_wvdsacmenu_open_items.

// Nome cookie
plugin_wvdsacmenu_open_items
 
// Valore (Array JSON)
["it:crypto:start","it:docs:api:start"]

Ripristino lato server

Durante il rendering il plugin legge il cookie e precarica tutte le cartelle salvate - anche se sono più profonde di dynamic. Questo ripristina lo stato menu senza flicker JavaScript.


Note sulla versione

Versione Data Modifiche
1.3.0 2026-01-29 Navigazione ACL-aware: ns=„auto“ modalità Smart Auto (focalizzata + fratelli con contenuto parziale), partial namespace (partial_ns), „Vai su“ basato su ACL a namespace home, _hasPartialChildren() per espansione automatica, _renderAutoSiblings() per rilevamento fratelli
1.2.0 2026-01-29 startns=„current“ (modalità Total Commander), icons=„fa“ (icone FontAwesome)
1.1.0 2026-01-29 Lazy loading, ripristino cookie, sintassi {{wvds:title>...}}
1.0.0 2025-01-06 Estensioni WvdS: sintassi wiki, supporto multilingue

Vedi anche


Riferimento tecnico

Classe: syntax_plugin_wvdsacmenu

File: lib/plugins/wvdsacmenu/syntax.php

Metodo Descrizione
getType() Restituisce substition
getSort() Restituisce 320
_findSidebar() Cerca file sidebar*
_tree() Costruisce albero menu (con supporto lazy e partial_ns)
_hasReadableContent() Verifica se contenuti leggibili esistono nel namespace
_hasPartialChildren() Verifica se namespace contiene figli partial_ns
_findUserHomeNamespace() Trova namespace home basato su ACL
_renderAutoSiblings() Renderizza namespace fratelli con contenuto parziale (per ns=„auto“)
_shouldForceLoad() Verifica se namespace deve essere ripristinato via cookie
_getPageTitle() Ottiene titolo pagina (wvds:title > heading > ID)
buildSubTree() Pubblico: Costruisce sotto-albero per AJAX
renderSubTree() Pubblico: Renderizza sotto-albero come HTML

Funzione template: tpl_findSidebarInNamespace()

File: lib/tpl/flat/lang_helper.php

Parametro Tipo Descrizione
$sidebarName string Nome file sidebar (es. sidebar1)
Ritorno string/null Page-ID completo o null se non trovato

Cerca un file sidebar partendo dal namespace corrente verso l'alto.

Classe: action_plugin_wvdsacmenu

File: lib/plugins/wvdsacmenu/action.php

Metodo Descrizione
_add_user_conf() Configurazione per JavaScript (JSINFO)
_ajax_load_ns() Handler AJAX per lazy loading

JavaScript: script.js

File: lib/plugins/wvdsacmenu/script.js

Funzione Descrizione
get_cookie() Legge elementi aperti dal cookie
set_cookie() Salva elementi aperti
saveCookie() Aggiorna cookie dopo modifica
trim_url() Estrae Page-ID da URL
handleLazyLoad() Caricamento AJAX contenuti cartella
toggleItem() Apre/chiude una cartella
hasIcons() Verifica se icone sono attivate
updateFolderIcon() Cambia icona cartella all'apertura/chiusura

wvdsacmenu PluginAudit bestanden • 2026-03-30