PHP-Logo
Druckansicht von http://www.php-homepage.de/artikel/artikel19.html

PHP-Logo
[ Main Menue ]
Homepage
Downloads
Artikel
Scripts
Forum
PHP-Manual
Links
News
Freelancer
Bücher
RuDolF
Suche
Misc
Über diese Seite
Kontakt
Wunschzettel
MyGuestbook
*
[ Suche ]
*
[ Partner ]


Domain Webhosting
*
[ Partner Sites ]
Dynamic-Webpages
PHP-Center
PHP-Welt
phpUG.de
Random Link
*
[ Autoren gesucht! ]
PHP-Homepage.de sucht laufend Autoren für News und Artikel
Interesse?
*

Follow on Twitter - @phphomepage

RSS Feed blogoscoop

JS-Menu aus SQL-Datenbank von Manuel Möller


  Wie es aussehen kann

JavaScript Version
als JavaScript

HTML Version
als pures HTML

  Gliederung:

  Idee

Das Menu einer Seite (wie immer es nun aussehen soll) aus ein paar Records in der Datenbank dynamisch generieren. Vorteile:

  • Es gibt eine globale Menu-Vorlage, aus der verschiedene Anzeigetypen generiert werden können:
    z.B.
    • Die Vorlage für ein JavaScript-Menu mit leckeren DHTML-Effekten.
    • Die spartanische Variante für fanatische Links-/Lynx-/Telnetsurfer.
    • Eine Flash-Variante, wenn man seinen Content in Flash komplett aus der Datenbank holt.
    • Um daraus XML zu erzeugen, ob es nun nur cool ist oder tatsächlich einen Sinn erfüllt.
    • Um PDFs davon machen zu können, obwohl ich nicht weiß, wer so etwas braucht...
    • Wenn man einmal angefangen hat, ein Content Management System aufzusetzen und sich überlegt hat, das selbst zu schreiben und nicht irgendeine fertige Lösung aus der Dose zu nehmen - auf freshmeat.net gibt es dazu genug Quellen -, ist ein dynamisches Menü der erste - vielleicht sogar der wichtigste - Schritt. BTW: Ich wollte den Leuten, die fertige CMS benutzen, nicht auf die Füße treten, aber diese Text richtet sich auch schließlich nicht an sie.
    • Das Menü wird über ein Web-Frontend konfigurierbar, sehr angenehm, wenn man mal eben eine Kategorie / einen Menüpunkt hinzufügen will und gerade die ganzen Files nicht zu Hand hat.
    • Man kann auf diese Weise DAU-feste Interfaces schreiben, mit denen wirklich (fast) jeder in der Lage ist, ein anständig aussehendes Menü zu aktualisieren
    • und und und...

    Unterstützte Browser

    Für die JavaScript-Anzeige:

    • MS Internet Explorer ab Version 4 denke ich mal, ab IE5 mit Sicherheit (getestet).
    • Netscape 4.7 (getestet)
    • Netscape 6.x (getestet)
    • Konqueror (getestet)
    Für die HTML-Version:
    • natürlich alle der obigen Browser
    • ALLE anderen Browser, die HTML anzeigen: Links, Lynx, w3m inclusive!

      Warum die Arbeit?

    man lernt dabei mit PHP und SQL umzugehen.

    Wenn man das einmal aufgesetzt hat und es läuft, spart man sich für die Zukunft eine Menge Arbeit und mögliche Fehlerquellen.

      Konkret: Der JS-Ansatz

    Ich werde hier nicht auf die JavaScript-Einzelheiten eingehen, weil ich mich
     (a) nicht besonders gut damit auskenne und weil sie
     (b) für diesen Artikel nur eine nebensächliche Rolle spielen.

    Wir haben also eins diese JS-Menüs, die man z.B. von http://www.dynamicdrive.com ziehen kann. Um ganz genau zu sein, habe ich folgendes Script, mit einigen Modifikationen benutzt:

    http://www.dynamicdrive.com/dynamicindex1/topnavbar.htm.

    Was dieser Art von Menüs in der Regel gemeinsam ist, ist die Struktur des Files, in dem die Menüpunkte festgelegt werden.
    Erst mal kommt eine Reihe von Variablen, mit denen man das Aussehen des Menüs einstellen kann; z.B. Text-/Hintergrundfarbe, Font usw.

    In meinem Beispiel:
    var NoOffFirstLineMenus=4;                      // Number of first level items
    var LowBgColor='black';                         // Background color when mouse is not over
    var LowSubBgColor='black';                      // Background color when mouse is not over on subs
    var HighBgColor='black';                        // Background color when mouse is over
    var HighSubBgColor='black';                     // Background color when mouse is over on subs
    var FontLowColor='white';                       // Font color when mouse is not over
    var FontSubLowColor='white';                    // Font color subs when mouse is not over
    var FontHighColor='white';                      // Font color when mouse is over
    var FontSubHighColor='white';                   // Font color subs when mouse is over
    var BorderColor='white';                        // Border color
    var BorderSubColor='white';                     // Border color for subs
    var BorderWidth=1;                              // Border width
    var BorderBtwnElmnts=1;                         // Border between elements 1 or 0
    var FontFamily="arial,comic sans ms,technical"; // Font family menu items
    var FontSize=9;                                 // Font size menu items
    var FontBold=1;                                 // Bold menu items 1 or 0
    var FontItalic=0;                               // Italic menu items 1 or 0
    [...]
    
    Auszug aus dem Config-File des JS-Menüs

    Danach werden in diesem Beispiel noch vier Basisfunktionen definiert, die nicht wirklich viel machen.

    function BeforeStart(){return}
    function AfterBuild(){return}
    function BeforeFirstOpen(){return}
    function AfterCloseAll(){return}
    
    die Funktionen

    Das war es auch schon mit den Vorbereitungen. Das JS-Menü erwartet die Menüeinträge als in der folgenden Form:

    1:   Menu1=new Array("void main(...)","http://www.manuelm.org","",4,20,150);
    2:     Menu1_1=new Array("long Lebenslauf","?content=lebenslauf","",0,20,150);
    3:     Menu1_2=new Array("unsigned long Studium","?content=studium/studium&menu=yes","",0);
    4:     Menu1_3=new Array("Flash-Präsentation","http://www.manuelm.org","",0);
    5:     Menu1_4=new Array("char News","?content=news&menu=yes","",0);
    6:
    7:   Menu2=new Array("char projekte(...)","http://www.manuelm.org","",6,20,125);
    8:     Menu2_1=new Array("Linux","?content=linux/main&menu=yes","",0,20,125);
    9:     Menu2_2=new Array("Kaffee-Maschine","?content=coffee/main&menu=yes","",0);
    10:    Menu2_3=new Array("Hitcounter","?content=stats/main&menu=yes","",0);
    11:    Menu2_4=new Array("Flash Spielereien","?content=portrait/main","",0);
    13:    Menu2_5=new Array("WAP","?content=linux/wap&menu=yes","",0);
    14:    Menu2_6=new Array("iKnow","?content=linux/iknow&menu=yes","",0);
    15: [...]
    
    Menüarrays

      Schritt für Schritt:

    1:   Menu1=new Array("#angezeigter Menuname#","#link#","",#Anzahl Submenus#,#Hoehe#,#Breite#);
    
    Menü 1

    Hier wird der erste Menüeintrag (deshalb Menu1) definiert, er ist gleichzeitig die Kategorie, also der Name des Menüs, der oben ganz links angezeigt wird.
    Anschießend kommen fünf wichtige Felder, in die ich hier mal die Bedeutung hineingeschrieben habe. Das sollte soweit selbsterklärend sein.
    Die Anzahle der Submenüs ist einfach die Anzahl der Einträge, die im Menü sind, die wird automatisch vom PHP-Script generiert werden.
    Analog wird die zweite Kategorie in Zeile 7 festgelegt. Die Leerzeile und die Einrückungen sind natürlich nicht nötig.

    2:     Menu1_1=new Array("Menu1 erster Menupunkt","http://www.foobar.com/der_link_dazu.html","",0,20,150);
    
    Menü 1, Menüpunkt 1

    In den Zeilen 2-5 werden jetzt nur noch die Menüeinträge festgelegt, analog für das zweite Menü in den Zeilen 8-14.

    Das solls mit JavaScript erstmal gewesen sein, jetzt kommt der SQL-Teil

      Die Struktur in der Datenbank

    Bemerkung vorweg: bei mir heißt Menunamenummer topid und Menueintragsnummer entryid
    In der Datenbank gibt es eine Tabelle, in der Menünamen und -punkte stehen. Sie sieht etwa so aus:

    topidentryidMenüeintragLink
    10void main(...)http://www.manuelm.org
    11long Lebenslauf?content=lebenslauf"
    Auszug aus der SQL-Menütabelle

    Die SQL-Querys, um eine solche Tabelle zu erstellen, sehen folgendermaßen aus:

    CREATE TABLE menu (
       topid tinyint(4) DEFAULT '0' NOT NULL,
       entryid tinyint(4) DEFAULT '0' NOT NULL,
       content text NOT NULL,
       link text NOT NULL
    );
    
    SQL-Befehle für Menu-Table

      Das PHP-Script

    Fehlt also nur noch das Script, mit dem die Arrays für das JavaScript-Menü erzeugt werden. Die ganzen Variablen können einfach so aus einer statischen Textdatei mit include() geholt werden.

    Dann sollte man den Link zur Datenbank mal aufmachen:

    1:   $host      = >dbhost<
    2:   $user      = >dbuser<
    3:   $password  = >dbpwd<
    4:   $db        = >your database<
    5:   $menutable = >name of table with menu entries<
    6:   $link = mysql_connect ($host, $user, $password)
    7:     or exit(-1);
    
    Link zur DB aufmachen

    Wichtig ist, daß das Script erstmal erkennen muß, wie viele Einträge es unter einer Kategorie gibt, schließlich muß das ja angegeben werden. Die ganze Tabelle wird deshalb für jedes Menü durchiteriert, wobei ich davon ausgehe, daß es unter einer Kategorie nur Menüpunkte gibt und nicht auch noch Unterkategorien, was das JS hergibt, mich aber nicht interessiert hat.
    Erstmal das Script im Überblick:

    0:   [...]
    1:   $query = "SELECT max(topid) FROM menu";
    2:
    3:   $result = mysql_db_query($db,$query)
    4:     or die("Fehler beim SELECT: $query");
    6:
    7:   $row2=mysql_fetch_array($result);
    8:
    9:   for ($i=1;$i<($row2[0]+1);$i++)
    10:  {
    11:      $query ="SELECT * FROM $menutable WHERE (topid = "\".$i."\") ORDER by entryid";
    12:      $result = mysql_db_query($db,$query)
    13:        or die("Fehler beim SELECT2:$query");
    14:      while ($row = mysql_fetch_array($result))
    15:      {
    16:        if ($row['entryid'] == 0)
    17:        {
    18:          /* Menu-Name */
    19:          $query2 ="SELECT topid FROM $menutable WHERE (topid = \"".$i."\")";
    20:          $num_entries = mysql_num_rows(mysql_db_query($db,$query2))
    21:            or die("Fehler beim SELECT: $query");
    22:          echo "\nMenu".$i."=new Array(\"".$row['content']."\",\"".$row['link'].
                      "&menu=1\",\"\",".($num_entries - 1).",20,150);\n";
    23:        }
    24:        else
    25:        {
    26:          /* Menu-Einträge */
    27:          echo "Menu".$i."_".$row['entryid']."=new Array(\"".$row['content']."\
                      ",\"".$row['link']."&menu=1\",\"\",0,20,150);\n";
    28:        }
    29:      }
    30:  }
    31:  [...]
    ");
    
    Der Algorithmus, um das Menü zu erzeugen

    Vorher mache ich natürlich noch die Verbindung zur Datenbank auf. Das vollständige Script stelle ich unten bei den Links zur Verfügung.

    Was dieser Teil macht:
    Der Query, der die Anzahl von Kategorien zurückliefert:

    1:   $query = "SELECT max(topid) FROM menu";
    

    Hier wird der Query ausführt, und das Ergebnis geholt:

    3:   $result = mysql_db_query($db,$query)
    4:     or die("Fehler beim SELECT: $query");
    6:
    7:   $row2=mysql_fetch_array($result);
    

    Jetzt startet die erste Schleife, die die Kategorien durchiteriert:

    9:   for ($i=1;$i<($row2[0]+1);$i++)
    
    In $row2[0] steht die Anzahl der Kategorien drin, die wir eben geholt haben.

    Nun die Kategorienamen holen. Sie sind dadurch definiert, daß ihre EntryID == 0 ist (Zeile 16):

    11:      $query ="SELECT * FROM $menutable WHERE (topid = \"".$i."\") ORDER by entryid";
    12:      $result = mysql_db_query($db,$query)
    13:        or die("Fehler beim SELECT2:$query");
    14:      while ($row = mysql_fetch_array($result))
    15:      {
    16:        if ($row['entryid'] == 0)
    17:        {
    18:          /* Menu-Name */
    19:          $query2 ="SELECT topid FROM $menutable WHERE (topid = \"".$i."\")";
    20:          $num_entries = mysql_num_rows(mysql_db_query($db,$query2))
    21:            or die("Fehler beim SELECT: $query");
    22:          echo "\nMenu".$i."=new Array(\"".$row['content']."\",\"".$row['link'].
                      "&menu=1\",\"\",".($num_entries - 1).",20,150);\n";
    23:        }
    

    Wenn die EntryID != 0 ist, muß es ein Menüeintrag sein, er wird über die TopID dem jeweiligen Menü zugeordnet:

    24:        else
    25:        {
    26:          /* Menu-Einträge */
    27:          echo "Menu".$i."_".$row['entryid']."=new Array(\"".$row['content']."\",\"
                      ".$row['link']."&menu=1\",\"\",0,20,150);\n";
    28:        }
    
    wieder nur billiges iteratives "Abgrasen" der Einträge!

    Wie leicht zu erkennen ist, sind bei mir Breite und Höhe der Menüfelder immer fest auf 20 bzw. 150 Pixel eingestellt. Wer will, kann auch das noch als Feld in der Datenbank speichern. Bei mir sind alle Menüfelder gleich groß.

      Das war es schon fast!

    Ein paar Sachen fehlen aber noch:

    1.: Script-Header:

    echo "<script type=\"text/javascript\">\n";
    echo "  function Go(){return}\n";
    echo "</script>\n";
    
    2.: Die Variablen müssen ja noch aus dem statischen File inkludiert werden (s.o):
     include('js/variables.js');

    bei mir liegt das File offensichtlich im Verzeichnis js/"

    Schmankerl: HTML-Version für deaktiviertes JS

    Bis jetzt hat das ganze ja eigentlich nur Arbeit gemacht. Jetzt kommt ein Teil, der Arbeit erspart. Da die Menüstruktur ohnehin unabhängig von der Formatierung vorliegt, läßt sich jetzt mühelos eine pure HTML-Version daraus erstellen. Ich habe hier als Beispiel mal die genommen, die ich auf meiner Seite einsetze. Wie man das HTML-Menü nun aber formatiert, bleibt jedem selbst überlassen. Hier also der Quellcode meiner Version:

     1:   //Textmenu
     2:   $link = mysql_connect ($host, $user, $password)
     3:     or exit(-1);
     4:   $query = "SELECT max(topid) FROM menu";
     5:   $result = mysql_db_query($db,$query)
     6:     or die("Fehler beim SELECT1: <b>$query</b>");
     7:   $row2=mysql_fetch_array($result);
     8:   echo "<center><table border=\\"0\\"><tr>\n";
     9:   for ($i=1;$i<($row2[0]+1);$i++)
     10:  {
     11:     $query ="SELECT * FROM $menutable WHERE (topid = \"".$i."\") ORDER by entryid";
     12:     $result = mysql_db_query($db,$query)
     13:       or die("Fehler beim SELECT: $query");
     14:     echo "<td valign=\"top\">\n";
     15:     while ($row = mysql_fetch_array($result))
     16:     {
     17:       if ($row['entryid'] == 0)
     18:        {
     19:          //Menu-Name
     20:          $query2 ="SELECT topid FROM $menutable WHERE (topid = \"".$i."\")";
     21:          $num_entries = mysql_num_rows(mysql_db_query($db,$query2))
     22:            or die("Fehler beim SELECT: <b>$query</b>");
     23:          echo "<b><a href=\"".$row['link']."\">".$row['content']."</a></b><br>\n";
     24:        }
     25:        else
     26:        {
     27:          //Menu-Einträge
     28:          echo "<a href=\"".$row['link']."\">".$row['content']."</a><br>\n";
     29:        }
     30:     }
     31:     echo "</td>\n";
     32:  }
     33:  echo "</tr>\n</table></center>\n";
    
    Scriptabschnitt für die HTML-Version

    In diesen Zeilen passiert praktisch das gleiche, wie in den vorher eingehend beschriebenen für die Erzeugung der JavaScript-Arrays, nur daß diesmal die gleichen Informationen als HTML formatiert ausgegeben werden.

    Erweiterungen

    Wie in der Einleitung angedeutet, ist auch es auf diese Weise leicht, aus dem Tabelleninhalt XML zu erzeugen und umgekehrt. Auch WML geht, zumal man da gleich die Links auf die passenden Decks setzen kann. Den Kram in ein Flashmenü zu packen geht jetzt auch einfach, entweder über den XML-"Umweg" oder direkt. Wenn man ohnehin erfaßt, ob die Clients der Seite JS aktiviert haben, kann man ihnen "automagisch" die HTML-Alternative geben. Ein Frontend zu programmieren, ist jetzt auch kein Problem mehr. Realisieren könnte man das in PHP, um das Menü im Browser ändern zu können, aber auch eine Variante, die direkt auf die DB zugreift - wenn der Provider das erlaubt - ist möglich.

    Quellcode

    Hier habe ich die Dateien nochmal zum Download zusammengestellt:

         das JS-File mit den statischen Variablen: variables.js 
         das PHP-Script, daß die ganze Arbeit macht: creator.phps 
         das JS-File mit dem eigentlichen Menü: menu.js 
         das Script, um die Tabelle für die Menüeinträge zu erstellen: menu.sql
         die Tabelle erstellt man dann einfach mit mysql -p Username < menu.sql 
         Zip mit allem, was man braucht

    Links

    http://www.dynamicdrive.com, dort gibt es Massen von JS http://www.dynamicdrive.com/dynamicindex1/topnavbar.htm, auch diese Menü könnte man nehmen The PHP Layers Menu: es gibt Leute, die das wesentlich perfekter umgesetzt haben! working demo: als Beispiel, wie das aussehen kann

    Impressum

    Der Verfasser übernimmt keine Haftung für irgendwelche Aktionen, die durch diesen Text ausgelöst werden. Vervielfältigung & Verbreitung einer veränderten Version nur mit ausdrücklicher Erlaubnis des Verfassers. Änderungen vorbehalten. (c) 2002 by Manuel Möller, mailto:contact@manuelm.org, http://www.manuelm.org


Zurück zur Übersicht
© Copyright 1999 - 2011 by Mark Kronsbein | Impressum | NutzungsbedingungenWeiterempfehlen | Seitenanfang
0.0072