echo $begrüßung;
Es soll eine Menüstruktur mittels einer Textdatei erfasst werden. Jede Zeile der Datei stellt einen Menüpunkt dar. Das Menü darf unendlich tief verschachtelt werden.
Ich komme an dem Punkt der Verschachtelungen nicht weiter. Immer fehlt irgendwo irgendwas, entweder was geöffnet wird oder was geschlossen wird und ich bekomme keine Übersicht rein. Ich mache es dann im Endeffekt in PHP, aber eigentlich würde es mir ausreichen, wenn mir jemand mal die Logik dahinter erklären würde, wie ich so ein Menü mit sich selbst aufrufenden schleifen oder Funktionen automatisch unendlich tief bauen kann?
Meine Lösung sieht so aus: Aus dem Menü-String wird ein verschachteltes Array erstellt (Funktion einlesen()). In einem zweiten Schritt wird daraus das <ul><li>-Konstrukt erzeugt (Funktion ulli()).
Das "ulli" lässt sich aus dem Array heraus besser erzeugen. Man muss dann auch die großen Level-Sprünge, wie von cacc nach d nicht mehr berücksichtigen, da durch das rekursive Hinab- und wieder Hinaufsteigen jedes Level mitgenommen wird.
Und auch beim Einlesen verwende ich die Funktion rekursiv.
Seht selbst: (-:
/**
* einlesen() - Einlesen eines Jeena-Menü-Strings in ein Array
*
* @param array $menuarray Referenz auf das Ergebnis-Array
* @param string/array $menu ein Jeena-Menu als String oder zeilenweise als Array
* @param integer $i interner Wert, nicht verwenden
* @param integer $level interner Wert, nicht verwenden
*/
function einlesen(&$menuarray, $menu, $i = 0, $level = 1) {
if (is_string($menu)) {
$menu = strtr($menu, array("\r\n" => "\n", "\r" => "\n"));
$menu = explode("\n", $menu);
}
while ($i < count($menu)) {
list($itemlevel, $item) = explode(' ', $menu[$i], 2);
$itemlevel = strlen($itemlevel);
// eine/mehrere Ebene(n) zurück
if ($level > $itemlevel)
break;
// weiter "nach unten"
if ($level < $itemlevel) {
if ($level + 1 < $itemlevel)
die('Verschachtlungsfehler an Position '. $menu[$i]);
$i = einlesen($menuarray[] = array(), $menu, $i, $level + 1);
}
// gleiches Level
else
$menuarray[] = trim($item);
$i++;
} //while $i < $menu
// Rückgabewert bei Verschachtlungen: Index des nächsten zu lesenden $menu-Eintrag
return --$i;
}
/**
* ulli() - Umwandeln eines Jeena-Menü-Arrays in einen HTML-ul-li-String
*
* @param array $menuarray ein Jeena-Menü-Array
* @param string $class ul-Klassenname
* @param integer $level (optional) Einrücktiefe
* @return string HTML-String eines Jeena-Menüs
*/
function ulli($menuarray, $class='level', $level = 0) {
$ulli = '';
foreach ($menuarray as $item) {
if (is_scalar($item)) {
// vorhergehendes Item schließen, wenn vorhanden
if (strlen($ulli))
$ulli .= "</li>\n";
// nächstes Item eingerückt anfangen
$ulli .= str_repeat(' ', $level + 1) . '<li>' . htmlspecialchars($item);
}
if (is_array($item)) {
$ulli .= ulli($item, $level + 1);
}
} //foreach $menuarray
return sprintf("<ul class='%s%s'>\n%s</li>\n%s</ul>",
$class, $level, $ulli, str_repeat(' ', $level));
}
$menu = <<<MENU
- a
- b
-- ba
-- bb
-- bc
- c
-- ca
--- caa
--- cab
--- cac
---- caca
---- cacb
---- cacc
- d
-- da
- e
- f
-- fa
--- faa
MENU;
$menuarray = null;
einlesen($menuarray, $menu);
// Kontrollausgabe
print_r($menuarray);
$ulli = ulli($menuarray);
echo '<pre>' . htmlspecialchars($ulli) . '</pre>';
echo $ulli;
echo "$verabschiedung $name";