Jeena Paradies: Verwirrende verschachtelungen eines Menüs

Hallo,

Ich habe zwar schon früher damit gekämpft, aber die alte Lösung gefällt mir überhaupt nicht mehr und sie ist auch so unübersichtlich, dass ich sie selbst nicht mehr kappiere. 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. Hier mal ein Beispiel wie so eine Textdatei vereinfacht aussehen würde:

  • a
  • b
    -- ba
    -- bb
    -- bc
  • c
    -- ca
    --- caa
    --- cab
    --- cac
    ---- caca
    ---- cacb
    ---- cacc
  • d
    -- da
  • e
  • f

Und das sollte das Ergebniss werden:

<ul>  
 <li>a</li>  
 <li>b  
   <ul>  
    <li>ba</li>  
    <li>bb</li>  
    <li>bc</li>  
  </ul>  
 </li>  
 <li>c  
   <ul>  
    <li>ca  
      <ul>  
       <li>caa</li>  
       <li>cab</li>  
       <li>cac  
         <ul>  
          <li>caca</li>  
          <li>cacb</li>  
          <li>cacc</li>  
         </ul>  
       </li>  
      </ul>  
    </li>  
   </ul>  
 </li>  
 <li>d  
  <ul>  
   <li>da</li>  
  </ul>  
 </li>  
 <li>e</li>  
 <li>f</li>  
</ul>

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?

Grüße
Jeena Paradies

  1. Hi,

    wenn ich das machen würde, würde ich nach folgendem Prinzip vorgehen, ob es klappt weiß ich nichtg, hab sowas noch nie ausprobiert:

    zuerst ganze datei einlesen (war ja nicht so schwer was ;-)
    danach eine for oder while schleife, mit der du jede zeile einzeln abarbeitest.
       {
         in dieser Schleife hast du eine Variable die immer die anzahl an - (Strichen) der vorzeile im kopf hat
         Wenn die Anzahl der Striche in der neuen Zeile mit der alten übereinstimmt, gibst du ein " <li>TEXT<\li>\n" aus.
         Wenn die Anzahl der Striche größer dem vorigen ist, gibst du   " <ul>\n  <li>TEXT<\li>\n" aus.
         Wenn die Anzahl der Striche kleiner dem vorigen ist, gibst du   so oft "</ul>\n" und addierst +1 zur Variablen bis sie bei gleich der vorigen variable ist. danach gibst du "<li>TEXT<\li>\n" aus.
       }

    Und am Ende dann noch ein Abschließendes </ul> damit die syntax schön ist.

    Musst du mal ausprobieren, würfte aber denke ich mal so klappen.
    Bis denne, stefan

    1. Hallo Stefan!

      Wenn die Anzahl der Striche kleiner dem vorigen ist, gibst du   so oft "</ul>\n" und addierst +1 zur Variablen bis sie bei gleich der vorigen variable ist. danach gibst du "<li>TEXT<\li>\n" aus.

      Nicht ganz, er muß meiner Ansicht nach "</li></ul>\n" ausgeben, weil ja sonst noch ein offener und nicht geschlossener Listenpunkt in der Liste steht.
      Man muß, bevor man die n schreibt schon schauen, ob die Tiefe in Zeile n+1 größer wird.
      So, wollte noch ein bis zwei Sätze schreiben, muß aber los ...

      MfG
      Götz

      --
      Losung für Montag, 17. Oktober 2005
      Ich will singen von der Gnade des Herrn ewiglich und seine Treue verkünden mit meinem Munde für und für. (Psalm 89,2)
      Auf alle Gottesverheißungen ist in ihm das Ja; darum sprechen wir auch durch ihn das Amen, Gott zum Lobe. (2. Korinther 1,20)
      (Losungslink)
      1. Lieber Götz,

        Nicht ganz, er muß meiner Ansicht nach "</li></ul>\n" ausgeben, weil ja sonst noch ein offener und nicht geschlossener Listenpunkt in der Liste steht.
        Man muß, bevor man die n schreibt schon schauen, ob die Tiefe in Zeile n+1 größer wird.

        mir erscheint es sinnvoller, anhand der "-"-Zeichen die Zeilen in ein Array (assoziativ) aufzudröseln, um über die entstehende Array-Struktur die Listen-Struktur zu erhalten. Ich habe das oben ja schon gepostet. Dort werden Strings (ehemals Text-Zeilen) mit "/" zu Arrays explodiert, hier könnte man das analog mit "-" machen.

        Das Zurückwandeln in die HTML-Liste (<ul>) habe ich oben schon gepostet. Das lässt sich sicherlich ganz einfach übernehmen. Der Bequemlichkeit halber habe ich die CSS-Klassen und Anker-Tags (mit href-Attribut) in der Funktion gelassen. Die sind sicherlich nicht ganz unnützlich (und schnell wieder rausgeschmissen).

        Mit regulären Ausdrücken kann man dann den Link der aktuellen Seite wieder aus der Liste entfernen, bzw. dieses Listenelement dann noch mit einer CSS-Klasse (oder ID) entsprechend "behandeln".

        Liebe Grüße aus Ellwangen,

        Felix Riesterer.

  2. Lieber Jeena,

    • a
    • b
      -- ba
      -- bb
      -- bc
    • c
      -- ca
      --- caa
      --- cab
      --- cac
      ---- caca
      ---- cacb
      ---- cacc
    • d
      -- da
    • e
    • f

    das sieht mir doch sehr nach einem assoziativen Array aus. Ich habe mir mal die Dateistruktur meines Webspaces in ein solches Array umgewandelt, um es dann als eine <ul> auszugeben (Adminbereich, Explorer-Tree).

    Ich werde mal nach dem Script kramen und sehen, ob es etwas für Dich ist.

    Diese Funktionen habe ich etwas "gesäubert", da Du ja keinen Dateibaum als Explorer-Tree anzeigen möchtest.

      
     // Funktion zum erstellen einer <ul> aus Dateistruktur  
      
        function dateistruktur($verzeichnis_pfad)  
           {  
         // Verzeichnisstruktur ermitteln und als Liste darstellen  
           $alle_dateien = make_tree($verzeichnis_pfad, "all");  
      
           $verzeichnis_array = array();  
      
           for($i=0;$i<count($alle_dateien);$i++)  
              {  
              $alle_dateien[$i] = "html/".substr($alle_dateien[$i], 5);  // das "html/" vorne im Pfad entfernen  
              $alle_dateien[$i] = explode("/", $alle_dateien[$i]);  
              $temp_array = array();  
              while(count($alle_dateien[$i]) > 0)  
                 {  
                 $test = array_pop($alle_dateien[$i]);  
                 if(count($temp_array) > 0)  
                    {  
                    $temp_array = array($test => $temp_array);  
                    }  
                  else  
                    {  
                    $temp_array = array($test => "");  
                    }  
                 }  
              $verzeichnis_array = array_pad($verzeichnis_array, count($verzeichnis_array)+1, $temp_array);  
              }  
      
           $verzeichnisse = array();  
           foreach($verzeichnis_array as $temp)  
              {  
              $verzeichnisse = array_merge_recursive($verzeichnisse, $temp);  
              }  
      
         // Verzeichnisliste zu einer HTML-Liste wandeln  
           $datei_baum = baum_vorbereiten($verzeichnisse, "/");  // Verzeichnisstruktur als <ul> herstellen  
           return $datei_baum;  
           }  
      
      
     // Funktion für die Dateibaum-Liste (rekursive Funktion!)  
      
        function baum_vorbereiten($verzeichnisse, $pfad)  
           {  
           $tabs = preg_replace("/[^\/]*(\/)[^\/]*/", "\t", $pfad);  
           $liste = $tabs."<ul>\r\n";  
           foreach($verzeichnisse as $stamm => $zweig)  
              {  
              if($stamm != "0")  
                 {  
                 if(is_array($zweig))  
                    {  
                    $pfad .= $stamm."/";  
                    $liste .= $tabs."\t<li".' class=""><a href="">'.$stamm."</a>\r\n";  
                    $liste .= baum_vorbereiten($zweig, $pfad, $liste);  
                    $pfad = substr($pfad, 0, strlen($pfad) - strlen($stamm)-1);  
                    $liste .= $tabs."\t</li>\r\n";  
                    }  
                  else  
                    {  
                    $liste .= $tabs."\t<li".' class=""><a href="">'."$stamm</a></li>\r\n";  
                    }  
                 }  
              }  
           $liste .= $tabs."</ul>\r\n";  
           return $liste;  
           }  
      
      
     // Funktion für Verzeichnisbaum  
      
        function make_tree($path, $mode)  
           {  
           $list = array();  
           $handle=opendir($path);  
           while($a=readdir($handle))  
              {  
              if(!preg_match('/^\./',$a))  
                 {  
                 $full_path="$path/$a";  
                 switch($mode)  
                    {  
                    case "all": $list[]=$full_path; break;  
                    case "dir": if(is_dir($full_path)) $list[]=$full_path; break;  
                    case "file": if(is_file($full_path)) $list[]=$full_path; break;  
                    }  
                 if(is_dir($full_path))  
                    {  
                    $recursive=make_tree($full_path, $mode);  
                    for($n=0; $n<count($recursive); $n++)  
                       {  
                       $list[]=$recursive[$n];  
                       }  
                    }  
                 }  
              }  
           closedir($handle);  
           return $list;  
           }  
    
    

    Möge es von Nutzen sein.

    Liebe Grüße aus Ellwangen,

    Felix Riesterer.

  3. 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";

  4. Lieber Jeena,

    konntest Du Dein Problem lösen?

    Du informierst das Forum doch auch sonst über Deine Erfolge bei Hilfeanfragen... *neugierig guck*

    Würde mich echt interessieren, wie Du's letzten Endes gemacht hast.

    Liebe Grüße aus Ellwangen,

    Felix Riesterer.

    1. Hallo,

      konntest Du Dein Problem lösen?

      Ich bin noch dabei, es ist nämlich ein wenig komplexer als das hier dargestellte, außerdem komme ich gerade irgendwie sehr schlecht dazu zu programmiern weil ich die ganze Zeit irgendwo gebraucht werde und irgendetwas machen muss.

      Du informierst das Forum doch auch sonst über Deine Erfolge bei Hilfeanfragen... *neugierig guck*

      Wie gesagt bin noch nicht fertig ;-).

      Würde mich echt interessieren, wie Du's letzten Endes gemacht hast.

      Ich bin gerade beim ausgeben der ersten Ebene in einem extra <ul>, welches dann als Hauptnavigation oben horizontal eingebunden wird. Das funktioniert so weit auch ganz gut:

      function firstLevel($menuarray, $request = '', $class = '') {  
        $ulli = "\n <ul".$class.">\n";  
        foreach($menuarray as $item) {  
          unset($url, $text, $title, $liclass);  
          list($url, $text, $title) = explode(",", $item);  
          if(isParent($menuarray, $url, $request)) $liclass = "parent";  
          if(!empty($title)) $title = " title='".trim($title)."'";  
          if(is_scalar($item)) {  
            if($request == $url) $ulli .= "  <li".$liclass."><a href='".trim($url)."'".$title.">".trim($text)."</a></li>\n";  
            else $ulli .= "  <li><strong".$title.">".trim($text)."</strong></li>\n";  
          }  
        }  
        return $ulli." </ul>\n";  
      }
      

      Was mir noch fehlt ist die Funktion isParent() sie soll überprüfen, ob der gerade zu erzeugende Menüpunkt ein Elternelement von dem gerade aufgerufenen Menüpunkt ist und falls ja ein true zurückgeben.

      Grüße
      Jeena Paradies

      --
      Hotlinking bei Bildern unterbinden - eine unkonventionelle Methode | Jlog | Gourmetica Mentiri
      1. Lieber Jeena,

        function firstLevel($menuarray, $request = '', $class = '') {

        $ulli = "\n <ul".$class.">\n";
          foreach($menuarray as $item) {
            unset($url, $text, $title, $liclass);
            list($url, $text, $title) = explode(",", $item);
            if(isParent($menuarray, $url, $request)) $liclass = "parent";
            if(!empty($title)) $title = " title='".trim($title)."'";
            if(is_scalar($item)) {
              if($request == $url) $ulli .= "  <li".$liclass."><a href='".trim($url)."'".$title.">".trim($text)."</a></li>\n";
              else $ulli .= "  <li><strong".$title.">".trim($text)."</strong></li>\n";
            }
          }
          return $ulli." </ul>\n";
        }

        
        >   
        > Was mir noch fehlt ist die Funktion isParent()  
        
        kann isParent() anhand des übergebenen Parameter denn erkennen, ob weitere Menüpunkte folgen? Du sagst nix über die Struktur Deines $menuarray aus... Ich hatte in meinem Beispiel ja die Verschachtelung in ein assoziatives Array gepackt. Da konnte ich sehr gut prüfen, ob im ($key => $value)-Paar $value auch ein Array ist. Wenn ja, dann gab es Unterpunkte.  
          
        Liebe Grüße aus [Ellwangen](http://www.ellwangen.de/),  
          
        Felix Riesterer.
        
        1. Hallo,

          kann isParent() anhand des übergebenen Parameter denn erkennen, ob weitere Menüpunkte folgen? Du sagst nix über die Struktur Deines $menuarray aus... Ich hatte in meinem Beispiel ja die Verschachtelung in ein assoziatives Array gepackt. Da konnte ich sehr gut prüfen, ob im ($key => $value)-Paar $value auch ein Array ist. Wenn ja, dann gab es Unterpunkte.

          Ich übergebe da einfach das was die Funktion einlesen(), die du mir gegeben hast, weiter oben als Array ausgibt (bzw. in $menuarray reinschreibt).

          Ich habe mir überlegt, dass ich dann irgendwie nach $request in $menuarray suchen muss, und von dort aus schrittweise nach oben gehen muss und gucken ob es weiter oben in der Struktur einen Eintrag gibt, welcher $url gleicht. Falls ja, wird true ausgegeben, ansonsten false. So weit so gut.

          Nur kriege ich keinen praktischen ansatz zusammen, mit welchem ich das umsetzen könnte.

          Grüße
          Jeena Paradies

          --
          Hotlinking bei Bildern unterbinden - eine unkonventionelle Methode | Jlog | Gourmetica Mentiri
          1. Lieber Jeena,

            Ich übergebe da einfach das was die Funktion einlesen(), die du mir gegeben hast, weiter oben als Array ausgibt (bzw. in $menuarray reinschreibt).

            weder die Funktion einlesen(), noch die Funktion ulli() sind von mir. Die hast Du von dedlfix' Posting übernommen. Da ich diese Funktionen noch nicht eingehend analysiert habe, kann ich über die Datenstruktur Deines Arrays nix sagen. Leichter wäre es, wenn Du einen kleinen print_r($menuarray) ausgeben könntest...

            Ich fürchte dedlfix' Version ist mit der meinen nicht so sehr kompatibel, aber das kriegen wir schon hin!

            Liebe Grüße aus Ellwangen,

            Felix Riesterer.

            1. Hallo,

              weder die Funktion einlesen(), noch die Funktion ulli() sind von mir. Die hast Du von dedlfix' Posting übernommen. Da ich diese Funktionen noch nicht eingehend analysiert habe, kann ich über die Datenstruktur Deines Arrays nix sagen. Leichter wäre es, wenn Du einen kleinen print_r($menuarray) ausgeben könntest...

              Array  
              (  
                  [0] => jeena/bla, a, ich bin es  
                  [1] => hallo, b, jaja  
                  [2] => Array  
                      (  
                          [0] => ba  
                          [1] => bb  
                          [2] => bc  
                      )  
                
                  [3] => c  
                  [4] => Array  
                      (  
                          [0] => ca  
                          [1] => Array  
                              (  
                                  [0] => caa  
                                  [1] => cab  
                                  [2] => cac  
                                  [3] => Array  
                                      (  
                                          [0] => caca  
                                          [1] => cacb  
                                          [2] => cacc  
                                      )  
                
                              )  
                
                      )  
                
                  [5] => d  
                  [6] => Array  
                      (  
                          [0] => da  
                      )  
                
                  [7] => e  
                  [8] => f  
                  [9] => Array  
                      (  
                          [0] => fa  
                          [1] => Array  
                              (  
                                  [0] => faa  
                              )  
                
                      )  
                
              )
              

              Ich fürchte dedlfix' Version ist mit der meinen nicht so sehr kompatibel, aber das kriegen wir schon hin!

              :-(

              Irgendwie bin ich zur Zeit total durch den Wind und kann mich nur schlecht konzentrieren. Aber ich werde mich anstrengen. Ich glaube aber, dass die dedelfixsche Funktion es nicht so einfach (wenn überhaupt) erlaubt die Verwandschaftsverhältnisse zwischen den einzelnen Ebenen zu ermitteln.

              Grüße
              Jeena Paradies

              --
              Hotlinking bei Bildern unterbinden - eine unkonventionelle Methode | Jlog | Gourmetica Mentiri
              1. Lieber Jeena,

                danke für das Listing! Es macht die Sache schon wesentlich transparenter!

                Irgendwie bin ich zur Zeit total durch den Wind und kann mich nur schlecht konzentrieren. Aber ich werde mich anstrengen.

                Locker bleiben! Bin zur Zeit auch krank gemeldet (und habe daher für dieses Forum so viel Zeit ;-) )...

                Ich glaube aber, dass die dedelfixsche Funktion es nicht so einfach (wenn überhaupt) erlaubt die Verwandschaftsverhältnisse zwischen den einzelnen Ebenen zu ermitteln.

                Das scheint mir auch so. In meiner Array-Struktur wäre es leicht anders. Hier ein (leicht gefälschter) Auszug meiner Dateistruktur der Schulhomepage, für die ich dieses Script entwickelt habe:

                Array  
                (  
                    [main] => Array  
                        (  
                            [csshover.htc] =>  
                            [download] => Array  
                                (  
                                    [0] =>  
                                    [NWT] => Array  
                                        (  
                                            [0] =>  
                                            [AnalogDigitalWandler] => Array  
                                                (  
                                                    [0] =>  
                                                    [ADWBericht.doc] =>  
                                                )  
                  
                                            [Fahrrad] => Array  
                                                (  
                                                    [0] =>  
                                                    [0 Projektvorstellung.ppt] =>  
                                                    [1 Entfaltung.xls] =>  
                                                    [2a Leistung beim Fahrradfahren.doc] =>  
                                                    [2b Leistung.xls] =>  
                                                    [2c Leistung beim Fahrradfahren Lösungen.doc] =>  
                                                    [3a Drehmoment.ppt] =>  
                                                    [3b Drehmoment Arbeitsblatt.doc] =>  
                                                    [4 Biomechanik Arbeitsblatt.doc] =>  
                                                    [5 Tagebuch.doc] =>  
                                                )  
                                        )  
                                )  
                            [explorer.css] =>  
                            [favicon.ico] =>  
                            [images] => Array  
                                (  
                                    [0] =>  
                                    [anfahrt-pg.png] =>  
                                    [gaestebuch] => Array  
                                        (  
                                            [0] =>  
                                            [biggrin.gif] =>  
                                            [blink.gif] =>  
                                            [cool.gif] =>  
                                            [devil.gif] =>  
                                            [dry.gif] =>  
                                            [edit.gif] =>  
                                            [email.gif] =>  
                                            [happy.gif] =>  
                                        )  
                                    [hintergrund.png] =>  
                                    [icons] => Array  
                                        (  
                                            [0] =>  
                                            [home.gif] =>  
                                            [zip.gif] =>  
                                        )  
                                    [pfeil_top.gif] =>  
                                )  
                            [index.html] =>  
                            [pg-style-druckansicht.css] =>  
                            [pg-style-standard.css] =>  
                        )  
                )
                

                Durch die Beziehung zwischen $key und $value meiner Array-Elemente ist eine Zuordnung von Parent und Child einfacher, als bei deldfix (finde ich). Im $key steht immer der Name der Datei oder des Verzeichnisses (also parent). Sollte es eine tiefere Ebene (also ein child) geben, so ist sie im $value als Array gespeichert. Sollte es keine tiefere Ebene (also kein child) geben, so ist $value leer. Natürlich bedeutet "tiefere Ebene", dass dort mehrere Elemente (child_ren_) sein können...

                Was mir noch nicht gelungen ist, sind die Array-Elemente, die mit "0" beginnen. In meinem Code müssen die wohl von irgendwoher kommen, aber in der Weiterverwendung werden solche Einträge dann eliminiert (wie man sehen kann).

                Liebe Grüße aus Ellwangen,

                Felix Riesterer.

                1. Hallo,

                  Das scheint mir auch so. In meiner Array-Struktur wäre es leicht anders.

                  Jo, und das Problem was ich habe ist eine solche funktion zu schreiben, die aus diesem Menütext ein solches Array macht.

                  Durch die Beziehung zwischen $key und $value meiner Array-Elemente ist eine Zuordnung von Parent und Child einfacher, als bei deldfix (finde ich). Im $key steht immer der Name der Datei oder des Verzeichnisses (also parent).

                  Ja aber wie kriege ich deine Funktion so umgebaut dass sie als Quelle diese Textdatei nimmt?

                   function makeArray() {  
                   # Diese Methode erstellt das Menü als PHP-Array und schreibt es in eine vollständige Datei  
                    $minus_old = 0;  
                    $menu_array = '<?php \$menu_array = array(';  
                    
                    foreach($this->txt_array AS $m) {  
                     $m_temp = explode(" ", trim($m));  
                     $minus = trim($m_temp[0]);  
                     if(!preg_match("/^-+$/", $minus)) continue;  
                     unset($m_temp[0], $title);  
                     list($text, $href, $title) = array_map(create_function('$n', 'return trim($n);'), explode(",", implode(" ", $m_temp)));  
                    
                     $i = strlen($minus) - strlen($minus_old);  
                     $minus_old = $minus;  
                     $a = 0;  
                    
                     if($i === 0) $menu_array .= "),";  
                     elseif($i < 0) {  
                      while($a > $i) {  
                       $menu_array .= "),";  
                       --$a;  
                      }  
                      $menu_array .= "),";  
                     }  
                     $menu_array .= "\n array( 'href' => '".$href."', 'title' => '".$title."', 'text' => '".$text."',";  
                    }  
                    
                    $i = 1 - strlen($minus_old);  
                    $a = 0;  
                    while($a > $i) {  
                     $menu_array .= ")";  
                     --$a;  
                    }  
                    
                    $menu_array = str_replace('\$menu_array = array(),', '$menu_array = array(', $menu_array)."));?>";  
                    
                    return $menu_array;  
                   }
                  

                  Mit dieser Funktion habe ich es damals geschafft ein solches Array in eine Datei zu schreiben. Leider wurde der PHP Quellcode dieser Datei total kaputt gemacht wenn der übergebene Text (den man bearbeitet hat) leer war. Sie hat damals ein solches Array ausgegeben: http://phpfi.com/72845

                  Hier noch mal der Link zum damaligen Thread.

                  Grüße
                  Jeena Paradies

                  --
                  Hotlinking bei Bildern unterbinden - eine unkonventionelle Methode | Jlog | Gourmetica Mentiri
                  1. Lieber Jeena,

                    Ja aber wie kriege ich deine Funktion so umgebaut dass sie als Quelle diese Textdatei nimmt?

                    das ist (denke ich) ganz einfach! Meine Original-Funktion hatte als Ausgangs-Inhalt ein Array, in dem Strings gespeichert waren, in denen die Pfade der Dateien und Verzeichnisse enthalten waren (Rückgabe-Wert der Funktion make_tree()):

                    [0] => "main/datei1.xyz"
                    [1] => "main/ordner"
                    [2] => "main/ordner/dateix.xyz"
                    usw.

                    Deine Datenvorlage ist ähnlich:

                    • a
                    • b
                      -- ba
                      -- bb
                      -- bc
                    • c
                      -- ca
                      --- caa
                      --- cab
                      --- cac
                      ---- caca
                      ---- cacb
                      ---- cacc
                    • d
                      -- da
                    • e
                    • f

                    Um jetzt das assoziative Array herzustellen nimmt die Funktion dateistruktur() dieses Array und explodiert die Elemente nach Slashes (weil damit die Verzeichnis-Struktur umgesetzt wird). In Deinem Fall ist die Datenvorlage so noch nicht dazu geeignet.

                    Mein Vorschlag:
                    Schreib eine Funktion oder Schleife, die Deine Textvorlage entsprechend "umschreibt", so dass hinterher folgende Struktur für meine Funktion entsteht:

                    - a  
                    - b  
                    - b - a  
                    - b - b  
                    - b - c  
                    - c  
                    - c - a  
                    - c - a - a  
                    - c - a - b  
                    - c - a - c  
                    - c - a - c - a  
                    - c - a - c - b  
                    - c - a - c - c  
                    - d  
                    - d - a  
                    - e  
                    - f  
                    - f - a  
                    - f - a - a
                    

                    Jetzt kannst Du die Zeilen anhand von "- " explodieren und erhälst ein Array, mit dem Du meine Funktion "dateistruktur()" 1:1 weiterverwenden kannst.

                    Mit einer simplen For-Schleife sollte es möglich sein, in jeder Zeile zwischen die Buchstaben (oder wofür sie auch immer stehen) entsprechende Trennzeichen ("-") einzufügen...

                    Bin jetzt aber sehr auf Deine Antwort gespannt!

                    Liebe Grüße aus Ellwangen,

                    Felix Riesterer.

                    1. Nachtrag

                      Deine Datenvorlage ist ähnlich:

                      • a
                      • b
                        -- ba
                        -- bb
                        -- bc
                      • c
                        -- ca
                        --- caa
                        --- cab
                        --- cac
                        ---- caca
                        ---- cacb
                        ---- cacc
                      • d
                        -- da
                      • e
                      • f

                      Mein Vorschlag:

                      • a
                      • b
                      • b - a
                      • b - b
                      • b - c
                      • c
                      • c - a
                      • c - a - a
                      • c - a - b
                      • c - a - c
                      • c - a - c - a
                      • c - a - c - b
                      • c - a - c - c
                      • d
                      • d - a
                      • e
                      • f
                      • f - a
                      • f - a - a
                        
                      Naja, das würde dann nicht zu der von Dir gewünschten Liste führen, sondern zu dieser:  
                       ~~~HTML
                      <ul>  
                        <li>a</li>  
                        <li>b  
                          <ul>  
                           <li>a</li>  
                           <li>b</li>  
                           <li>c</li>  
                         </ul>  
                        </li>  
                        <li>c  
                          <ul>  
                           <li>a  
                             <ul>  
                              <li>a</li>  
                              <li>b</li>  
                              <li>c  
                                <ul>  
                                 <li>a</li>  
                                 <li>b</li>  
                                 <li>c</li>  
                                </ul>  
                              </li>  
                             </ul>  
                           </li>  
                          </ul>  
                        </li>  
                        <li>d  
                         <ul>  
                          <li>a</li>  
                         </ul>  
                        </li>  
                        <li>e</li>  
                        <li>f</li>  
                       </ul>
                      

                      Die Listenelemente heißen dann zwar nur noch "b", ohne dass der Bezug zum parent im Listenelement selbst enthalten ist, aber in der Struktur ist es völlig klar ersichtlich (denn "b" steht in "c", das wiederum in "a" steht, welches child von "c" ist).
                      Wenn das jetzt trotzdem "passt", dann ist ja prima. Aber wenn Du in den <li>-Elementen jetzt trotzdem noch den Bezug zum Elternelement brauchst (z.B. "cacb" anstatt "b"), dann müsste man Deine Textvorlage etwas komplexer umschreiben... Aber auch das ist machbar!

                      Ich hatte geschrieben:

                      Jetzt kannst Du die Zeilen anhand von "- " explodieren

                      Aber wenn Du Deine ursprünglich gepostete HTML-Liste haben willst, dann müsste man Deine Textvorlage vorher auf folgende Struktur "umbauen":

                      - a  
                      - b  
                      - b - ba  
                      - b - bb  
                      - b - bc  
                      - c  
                      - c - ca  
                      - c - ca - caa  
                      - c - ca - cab  
                      - c - ca - cac  
                      - c - ca - cac - caca  
                      - c - ca - cac - cacb  
                      - c - ca - cac - cacc  
                      - d  
                      - d - da  
                      - e  
                      - f
                      

                      Das kriegst Du aber hin, oder?

                      Liebe Grüße aus Ellwangen,

                      Felix Riesterer.

              2. echo $begrüßung;

                Ich glaube aber, dass die dedelfixsche Funktion es nicht so einfach (wenn überhaupt) erlaubt die Verwandschaftsverhältnisse zwischen den einzelnen Ebenen zu ermitteln.

                Da glaubst du richtig. Mir ist auch kein Variablenkonstrukt unter PHP bekannt, bei der solch eine Beziehung eindeutig herauszufinden geht. Es lassen sich immer nur Variablen_inhalte_ vergleichen, nicht jedoch ob beispielsweise zwei Referenzen auf das gleiche Ziel verweisen.

                Du benötigst mindestens eine ID, also ein garantiert eindeutiges Kriterium. Eine ID kann man beispielsweise beim Einlesen aus einer Sequenz entnehmen:

                function getSequenzValue($reset = false) {  
                  static $value = 0;  
                  if ($reset)  
                    $value = 0;  
                  return $value++; // Die Inkrementierung erfolgt nach dem Verwenden des Variableninhalts als Funktionsergebnis  
                }
                

                Diese ID müsstest du irgendwie in die Werte "reinfummeln". Damit lässt sich wiederum durch rekursives Durchlaufen das Element ermitteln, das eine bestimmt ID als Kind enthält. Dabei müsste dann jedes Mal der ID-Wert wieder extrahiert werden ...

                Spätestens jetzt würde ich für die Menüpunkte eine Klasse erstellen, die die einzelnen Teilwerte eines Menüeintrages in separaten Eigenschaften verwaltet. Das erhöht die Übersichtlichkeit und spart das ständige Separieren an irgendwelchen Trennzeichen.

                echo "$verabschiedung $name";

  5. Hallo,

    So ich habe mir mal meine Alte Version noch einmal genauer angeschaut und es irgendwie doch geschafft diese zum laufen zu bekommen, fragt mich aber nicht wie ;-)

    Hier ist das ganze Plugin fertig, falls es jemanden noch interessiert:

    http://phpfi.com/83761

    Grüße
    Jeena Paradies

    1. Lieber Jeena,

      Hier ist das ganze Plugin fertig, falls es jemanden noch interessiert:

      http://phpfi.com/83761

      "Plugin"? Sieht nach einer PHP-Klasse aus... aber davon verstehe ich (noch) nix, da ich noch nicht wirklich objektorientiert Programmiere (soweit man das in Javascript "umgehen" kann).

      Sehe ich das jetzt richtig, dass man für eine Menüstruktur bei Verwendung Deiner Klasse (alias "Plugin") eine Textdatei wie im OP gezeigt entwerfen muss? Mal sehen, ob ich auf der von Dir verlinkten Seite Hinweise zur exakten Syntax dieser Textvorlage finde. Klingt nicht uninteressant! :-)

      Liebe Grüße aus Ellwangen,

      Felix Riesterer.