Jeena Paradies: Baum-Menü Struktur Verwaltungstool

Hallo,

Ich sitze gerade an einem Problem bei welchem ich alleine nicht weiterkomme und deshalb ein wenig Beratung eurerseits brauche.

Ich habe mir eine Software geschrieben, die mir aus einem multidimmensionalen (PHP) Array ein Menü erstellt.

Jetzt versuche ich irgendwie eine Software zu schreiben, die es dem Benutzer auf möglichst einfache Weise erlaubt ein solches Menü zu erstellen. Das scheint gar nicht so einfach zu sein. Das Menü soll dann im Endeffekt aus einigen verschachtelten Listen bestehen und in etwa so ausehen (zum Schluss natürlich noch viel größer):

|-Weblog
  |-Madagaskar
  |-FIRMA
   |-Wer ist FIRMA
   |-Tätigkeitsbereiche
    |-Reisen mit FIRMA
     |-Bla
    |-Projektmanagement
    |-Kulturprojekte
   |-Kontakt
  |-Land & Leute
  |-Produkte
  |-Reiseinfo

Jetzt habe ich mir überlegt, dass ich das eigentlich mit JavaScript am einfachsten umsetzen könnte. Ich würde ein ganz großes Formular anlegen, welches auch wunderbar, durch die gleiche Listenverschachtelung wie im späteren Menü, formatiert ist, so dass man die Struktur gleich erfassen kann und seine Menüpunkte an geeigneter Stelle einfügen kann. Bei jedem Punkt würde es dann Buttons zum Einfügen (eine Ebene tiefer, bzw. in der gleichen Ebene unten drunter) geben. So weit so gut. Die einzelnen Inputfelder würden dann im name Attribut gleich das Array abbilden, welches dann zum Schluss herauskommen soll, hier ein Beispiel aus dem oberen Menü und zwar dem Punkt "Projektmanagement" und dem Inputfeld für das Linkziel:

href: <input type="text" name="menu[2][1][1]['href']" value="" />

Wenn ich jetzt eine neue Ebene erstellen will, die genau drunter eröffnet wird, dann lese ich den Inhalt den name Attributes aus, und ersetze ['href'] durch [0]['href'] das klappt noch sehr gut. Mein wirklich großes Problem ist, wie schaffe ich es einen Neuen Menüpunkt in der gleichen Ebene zu machen, dieser müsste ja dann den namen menu[2][1][2]['href'] bekommen. wie kann ich da irgendwie die letzte Zahl in einer Klammer auslesen und um eines hochzählen (könnte ja auch eine zweistellige Zahl sein, oder noch tiefer Verschachtelt)?

Oder hat jemand eine revolutionär viel einfachere Variante um ein solches PHP Array zu erzeugen, auf die ich bisher noch nicht gekommen bin? Es muss vor allem sehr einfach und nachvollziehbar für den Benutzer sein.

Grüße
Jeena Paradies

--
Vlona Koorbash Grafiken - PDF-Magazin mit Grafiken meiner Frau erschienen | Jlog | Gourmetica Mentiri
  1. Huhu Jeena

    Oder hat jemand eine revolutionär viel einfachere Variante um ein solches PHP Array zu erzeugen, auf die ich bisher noch nicht gekommen bin? Es muss vor allem sehr einfach und nachvollziehbar für den Benutzer sein.

    Naja revolutionär ist es vielleicht nicht, aber einfach schon

    so kommt es rein
    so kommt es raus

    Ich arbeite ansonsten meist mit einer ParentId um solche hierarchischen Gebilde zu verwalten.
    Das kann man auch sehr einfach in eine Array-Struktur verwandeln.

    ParentIds

    Vielleicht hilft Dir das eine oder andere davon ja weiter.

    Viele Grüße

    lulu

    --
    bythewaythewebsuxgoofflineandenjoytheday
    1. Hallo,

      Naja revolutionär ist es vielleicht nicht, aber einfach schon
      so kommt es rein
      so kommt es raus

      Interessante Vorgehensweise, was passiert eigentlich wenn der User mal zu viele - Zeichen eingibt?

      Ich arbeite ansonsten meist mit einer ParentId um solche hierarchischen Gebilde zu verwalten.
      Das kann man auch sehr einfach in eine Array-Struktur verwandeln.
      ParentIds

      Irgendwie scheint mir das auch am sinnvollsten zu sein, nur muss ich dann jeden einzelnen Link vorcher durch PHP durchschleifen und kann da keine sinnvollte struktur mit JavaScript erzeugen :-/

      Grüße
      Jeena Paradies

      --
      Vlona Koorbash Grafiken - PDF-Magazin mit Grafiken meiner Frau erschienen | Jlog | Gourmetica Mentiri
  2. echo $begrüßung;

    multidimmensionalen (PHP) Array

    Wäre nicht verschachtelt anstatt multidimensional ein passenderer Ausdruck?

    Ich zitiere mal etwas aus dem gegebenene Link:

    array (
            href  => "firma/",
            text  => "FIRMA",
            title => "Wer ist FIRMA?",

    array (
                href  => "firma/",
                text  => "Wer ist FIRMA",
                title => "",
            ),

    array (
                href  => "firma/taetigkeitsbereiche/",
                text  => "Tätigkeitsbereiche",
                title => "",

    array (
                    href  => "firma/taetigkeitsbereiche/reisen/",
                    text  => "Reisen mit firma",
                    title => "",

    array (
                        href  => "firma/taetigkeitsbereiche/reisen/bla",
                        text  => "Bla Blub",
                        title => "",
                    ),
                ),

    Ich finde das eine sehr ungünstige Struktur. (Außerdem fehlen '' oder "" jeweils um href, text und title.)
    Eigenschaften des jeweiligen Eintrages befinden sind in der gleichen Ebene wie die Kinder. Es wird umständlich werden, über die Kinder zu "foreachen", da jedesmal auf die Eigenschaften des Menüeintrages geprüft werden muss, um diese zu ignorieren.

    Mein Vorschlag für ein Element wäre:

    $menu = array(  
      array( // ein Menüelement  
        'href' => 'foo',  
        'text' => 'bar',  
        'title' => 'foobar',  
        'children' => array( // ein Array für alle Kinder  
          array( // ein Kind  
            'href' => ...,  
            ...  
            'children' => array(...)  
          ),  
          array( // noch ein Kind  
            'href' => ...,  
            ...  
            'children' => array() // für keine Kinder sollte _immer_ ein leeres Array angelegt werden  
          ),  
        ),  
      array(...)  // noch ein Menüelement  
      ...  
    );
    

    Kinder werden so hinzugefügt:

    $menuitem['children'][] = array('href' => ..., ..., 'children' => array());

    Alle Kinder eines Elements kannst du dann so durchlaufen:

      foreach($menuitem['children'] as $child) {  
        ... = $child['href'];  
        $child['text'] = ...;  
        ...  
      }
    

    foreach beschwert sich, wenn es kein Array übergeben bekommt, deshalb sollte children immer ein Array sein, ohne Kinder dann halt ein leeres.

    Du kannst natürlich auch eine Klasse für den Menüeintrag definieren...

    echo "$verabschiedung $name";

    1. Hallo,

      Wäre nicht verschachtelt anstatt multidimensional ein passenderer Ausdruck?

      Warscheinlich hast du recht.

      Eigenschaften des jeweiligen Eintrages befinden sind in der gleichen Ebene wie die Kinder. Es wird umständlich werden, über die Kinder zu "foreachen", da jedesmal auf die Eigenschaften des Menüeintrages geprüft werden muss, um diese zu ignorieren.

      Die Lösche ich einfach jedes mal davor, dann stören sie nicht.

      Kinder werden so hinzugefügt:
      $menuitem['children'][] = array('href' => ..., ..., 'children' => array());

      Interessanter Ansatz, dann bräuchte ich mich mit den genauen Zahlen gar nicht herumärgern, und könnte auch leichter die Reihenfolge ändern...

      Alle Kinder eines Elements kannst du dann so durchlaufen:

      Jo, das ist dann kein Problem mehr, das Problematische war ja vor allem das mit dem hinzufügen und den festen Zahlen.

      Du kannst natürlich auch eine Klasse für den Menüeintrag definieren...

      Vielleicht, ich werde mir das jetzt erst einmal durch den Kopf gehen lassen.

      Grüße
      Jeena Paradies

      --
      Vlona Koorbash Grafiken - PDF-Magazin mit Grafiken meiner Frau erschienen | Jlog | Gourmetica Mentiri
    2. Hallo,

      $menuitem['children'][] = array('href' => ..., ..., 'children' => array());

      Da fällt mir aber was ein; Da habe ich doch das absolut gleiche Problem, wie mir meiner Struktur, wenn ich sie als Formular abbilden möchte:

      ~~~html href: <input type="text" name="menu[children][]['href']" value="" />
        href: <input type="text" name="menu[children][]['text']" value="" />
        href: <input type="text" name="menu[children][]['title']" value="" />

        
      Also würde ich alles umschreiben und praktisch genau da stehen wo ich jetzt schon bin :-( nur dass ich eine sinnvollere Struktur hätte.  
        
      Grüße  
      Jeena Paradies
      
      -- 
      [Vlona Koorbash Grafiken](http://jeenaparadies.net/weblog/2005/jul/vlona-grafiken) - PDF-Magazin mit Grafiken meiner Frau erschienen | [Jlog](http://jeenaparadies.net/webdesign/jlog/) | [Gourmetica Mentiri](http://jeenaparadies.net/gourmetica-mentiri/)
      
      1. echo $begrüßung;

        href: <input type="text" name="menu[children][]['href']" value="" />

        Hier (im HTML-Code) darfst du keine '' um das href tun, PHP macht das von selbst, nur innerhalb von PHP-Code sollten sie verwendet werden.

        Also würde ich alles umschreiben und praktisch genau da stehen wo ich jetzt schon bin :-( nur dass ich eine sinnvollere Struktur hätte.

        Da meine Elemente bei ähnlich gelagerten Fällen aus einer (flachen) Datenbank-Tabelle kommen haben die eine eindeutige ID (nebst Verweis auf das Vaterelement, damit die Struktur wiederhergestellt werden kann). Über die werden die Elemente eindeutig angesprochen. Die Verschachtelung stört dann beim Referenzieren eines Elementes nicht mehr.

        Für das Eingeben neuer Elemente werden die Elemente, so wie sie aktuell verschachtelt sind, dargestellt mit jeweils einem Radio-Button daneben, über den das Element unterhalb dessen das neue eingefügt werden soll, ausgewählt werden kann. (Das imaginäre Root-Element nicht vergessen!)
        Darunter kommen dann die Eingabefelder der sonstigen Objekteigenschaften.
        Der Radio-Button erhält als Wert die ID des Elements (für Root die 0) und diese dient dann beim Neueintrag als Eltern-ID.

        Wie hattest du dir vorgestellt, die Menüeinträge zu speichern?

        echo "$verabschiedung $name";

        1. Hallo,

          Da meine Elemente bei ähnlich gelagerten Fällen aus einer (flachen) Datenbank-Tabelle kommen haben die eine eindeutige ID (nebst Verweis auf das Vaterelement, damit die Struktur wiederhergestellt werden kann). Über die werden die Elemente eindeutig angesprochen. Die Verschachtelung stört dann beim Referenzieren eines Elementes nicht mehr.

          Diese ID fehlt bei mir gänzlich.

          Wie hattest du dir vorgestellt, die Menüeinträge zu speichern?

          Ich habe mir vorgestellt einfach eine PHP Datei zu erzeugen, die nur <?php $menu = array( /* das ganze Menü Array hier rein */ ) ?> enthält. Das hätte den vorteil, dass ich sie immer nur includieren muss und alles gleich in dieser Array Struktur hätte, mit welcher ich per foreach das ganze Menü sehr schnell erzeugen könnte. Ich müsste keine Datenbank kontaktieren, kein XML umwandeln oder solche sachen, sondern hätte gleich das schöne Array im Speicher. Das müsste ich nur ganz ganz Selten verändern, wenn eine neuer Eintrag ins Menü reinkommen würde, vielleicht ein mal alle drei Monate oder so.

          Für das Eingeben neuer Elemente werden die Elemente, so wie sie aktuell verschachtelt sind, dargestellt mit jeweils einem Radio-Button daneben, über den das Element unterhalb dessen das neue eingefügt werden soll, ausgewählt werden kann. (Das imaginäre Root-Element nicht vergessen!)

          Das verstehe ich noch nicht ganz, du meinst ich sollte also das ganze als eine fertige Linkliste erstellen (oder auch ohne Link) (so was wie eine Sitemap) und neben jeden Link einen Button machen mit dem angegeben wird wohin der nächste Menüeintrag einfefügt wird? Eigentlich eine gute Idee.

          Darunter kommen dann die Eingabefelder der sonstigen Objekteigenschaften.

          wie darunter? Meinst du ganz ganz unter alle Menülinks? Das wäre sinnvoll.

          Der Radio-Button erhält als Wert die ID des Elements (für Root die 0) und diese dient dann beim Neueintrag als Eltern-ID.

          Oha wirklich raffiniert, werde ich mal versuchen umzusetzen. Dazu bräuchte man ja eigentlich gar kein JavaScript mehr, ellegant.

          Grüße
          Jeena Paradies

          --
          Vlona Koorbash Grafiken - PDF-Magazin mit Grafiken meiner Frau erschienen | Jlog | Gourmetica Mentiri
          1. echo $begrüßung;

            Ich habe mir vorgestellt einfach eine PHP Datei zu erzeugen, die nur <?php $menu = array( /* das ganze Menü Array hier rein */ ) ?> enthält. [...] Das müsste ich nur ganz ganz Selten verändern, wenn eine neuer Eintrag ins Menü reinkommen würde, vielleicht ein mal alle drei Monate oder so.

            Und dafür willst du dann eine aufwändige Verwaltungssoftware schreiben? In dem Fall erscheint es mir angebrachter einfach zu dokumentieren, wie so ein Eintrag auszusehen hat.

            echo "$verabschiedung $name";

            1. Hallo,

              Und dafür willst du dann eine aufwändige Verwaltungssoftware schreiben? In dem Fall erscheint es mir angebrachter einfach zu dokumentieren, wie so ein Eintrag auszusehen hat.

              Das war ein extra ausgesprochener Wunsch des Kunden. Aber recht hast du irgendwie schon :-/ vielleicht sollte ich ihm versuchen dass doch auszureden, oder das mit der Textdatei, was lulu vorgeschlagen hat versuchen umzusetzen.

              Grüße
              Jeena Paradies

              --
              Vlona Koorbash Grafiken - PDF-Magazin mit Grafiken meiner Frau erschienen | Jlog | Gourmetica Mentiri
  3. Hallo Jeena,

    Dein Problem ist den String "menu[2][1][2]['href']" zu zerlegen?
    Das ist doch nicht so kompliziert. Zuerst bestimmst Du die Position des ersten [ und des letzten ] und schnippelst die und alles davor/danach weg.
    Dann zerlegst Du den String mit split anhand von ][ in ein Array und kannst auf alle Komponenten zugreifen.
    Die letzte davon wirfst Du halt weg, wenn Du die nicht brauchst.

    Ich habe kürzlich auch eine Javascript-Oberfläche für eine kompliziertere Datenstruktur geabstelt. Ich hab' die Daten dann aber an den Server geschickt, indem ich mit Javascript XML erzeugt und an den Server geschickt habe. (In einem versteckten Formularfeld, man könnte aber natürlich auch einen XML-HTTP-Request nehmen.)
    Die Lösung hat den Vorteil, dass Du Dich nicht darum kümmern musst, dass die GUI so aufgebaut ist, dass da die richtige Datenstruktur rauskommt.
    Du musst natürlich aus den XML-Daten Serverseitig Deine Datenstruktur generieren, wogegen Dir die bei Deiner Lösung PHP erzeugt.

    Grüße

    Daniel

    1. Hallo,

      Dein Problem ist den String "menu[2][1][2]['href']" zu zerlegen?
      Das ist doch nicht so kompliziert. Zuerst bestimmst Du die Position des ersten [ und des letzten ] und schnippelst die und alles davor/danach weg.
      Dann zerlegst Du den String mit split anhand von ][ in ein Array und kannst auf alle Komponenten zugreifen.
      Die letzte davon wirfst Du halt weg, wenn Du die nicht brauchst.

      Hm wenn man sich das so ansieht ist das wirklich gar nicht so kompliziert wie ich dachte, das werde ich mal ausprobieren, dann könnte ich alles andere gleich so lassen, das würde mir viel Arbeit ersparen.

      Ich habe kürzlich auch eine Javascript-Oberfläche für eine kompliziertere Datenstruktur geabstelt. Ich hab' die Daten dann aber an den Server geschickt, indem ich mit Javascript XML erzeugt und an den Server geschickt habe.

      Jo, dafür kann ich wohl noch zu wenig JavaScript und gleichzeitig komme ich mit XML und PHP4 noch nicht ganz so richtig zurecht, erstellen (z.B. RSS) ist kein Problem aber auslesen, dafür müsste ich irgendeine PEAR Klasse installieren usw. das ist mir zur Zeit noch zu viel Aufwand, da ich das vorher noch nie gemacht habe.

      Grüße
      Jeena Paradies

      --
      Vlona Koorbash Grafiken - PDF-Magazin mit Grafiken meiner Frau erschienen | Jlog | Gourmetica Mentiri