- Ad -
php-resource



Zurück   PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr > Entwicklung > PHP Developer Forum
 

Login

 
eingeloggt bleiben
star Jetzt registrieren   star Passwort vergessen
 

 

 

 


PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Fragen zu Laravel, YII oder anderen PHP-Frameworks.

Antwort
 
LinkBack Themen-Optionen Thema bewerten
  #1 (permalink)  
Alt 10-01-2016, 05:47
Theryl
 Registrierter Benutzer
Links : Onlinestatus : Theryl ist offline
Registriert seit: Jan 2016
Beiträge: 1
Theryl befindet sich auf einem aufstrebenden Ast
Exclamation Problem mit mehrstufiger Navigation mit php

Hallo zusammen ich habe da ein hoffentlich nur kleines Problem. Und zwar geht es um eine mehrstufige Navigation. Ich habe das die Datei im Netz gefunden und bin schwer begeistert davon.
Ich hätte nun lieber anstatt der zwei level, drei level.
Also so sieht es nun aus:
Code:
1
1.1
1.2
2
2.1
2.2
2.3
3
4.1
schön wäre es wenn sie so aussehen könnte
Code:
1.
1.1
1.1.1
1.1.2
2
3
4.1.1
Ich hoffe mir kann einer bei diesem Problem helfen und Danke jetzt schon mal im voraus.

Hier ist die .php Datei

PHP-Code:
<?php
$siteRoot
="index.php?inhalt_mitte=";
$menuStruct = array("Vorwort"=>array("root"=>$siteRoot."content/vorwort.inc.php""CSS Dateien strukturieren"=>$siteRoot."content/strukturieren.inc.php"),
                    
"Eigenschaften"=>array("root"=>$siteRoot."content/eigenschaften.inc.php"),
                    
"Aufgaben"=>array("root"=>$siteRoot."content/aufgaben.inc.php","Formularfelder"=>$siteRoot."content/formularfelder.inc.php","Listen"=>$siteRoot."content/listen.inc.php","Buttons"=>$siteRoot."content/buttons.inc.php")
                   );
$aktuell $_GET["inhalt_mitte"];
$url $siteRoot.$aktuell;
foreach(
$menuStruct as $key=>$value)
{
  if(
$url == $value['root'])
  {
    echo 
"<a  class=\"fstLevelActive\" href=".$value['root'].">$key</a>\n";
  }
  else
  {
    echo 
"<a class=\"fstLevel\" href=".$value['root'].">$key</a>\n";
  }
  foreach(
$value as $key2=>$value2)
  {
    if(
array_search($url,$value))
    {
      if(
$key2 != "root")
      {
        if(
$url == $value2)
        {
          echo 
"<a class=\"secLevelActive\" href=".$value2.">$key2</a>\n";
        }
        else
        {
          echo 
"<a class=\"secLevel\" href=".$value2.">$key2</a>\n";
        }
      }
    }
  }
}
?>
Mit Zitat antworten
  #2 (permalink)  
Alt 11-01-2016, 10:24
mermshaus
 Registrierter Benutzer
Links : Onlinestatus : mermshaus ist offline
Registriert seit: Jun 2009
Beiträge: 393
mermshaus wird schon bald berühmt werden
Standard

Willkommen im Forum.

Ich fürchte, das ist nicht so leicht, weil der Code ziemlich „speziell“ für die Aufgabe geschrieben ist, die er aktuell erfüllt.

Etwa so was…

Code:
if(array_search($url,$value))
…, das vermutlich bedeuten soll, dass… Ehrlich gesagt: Ich habe keine Ahnung, was das genau bedeuten soll. Untermenüs klappen sich wieder ein, sobald ein Element daraus ausgewählt wird, weil $url dann nicht mehr in $value liegt?

Wie auch immer: Man kann veruschen, dir da irgendwie was reinzubasteln, aber das wird voraussichtlich auf Anhieb nicht so werden, wie du es haben willst. Und bevor das dann ein ewiges Hin und Her gibt, könnte man besser gleich ne ordentliche Lösung wählen, die etwa auch mit einer beliebigen Anzahl an Ebenen umgehen kann und die ordentlichen HTML-Code erzeugt (mit Listen).
Mit Zitat antworten
  #3 (permalink)  
Alt 12-01-2016, 14:49
Benutzerbild von fireweasel fireweasel
 Registrierter Benutzer
Links : Onlinestatus : fireweasel ist offline
Registriert seit: Sep 2008
Ort: At home
Beiträge: 840
fireweasel wird schon bald berühmt werdenfireweasel wird schon bald berühmt werden
fireweasel eine Nachricht über AIM schicken fireweasel eine Nachricht über Yahoo! schicken
Standard Verschachtelte Menüs, Nested Menus, Bäume und Trees, Walk, Traverse, ...

Zitat:
Zitat von Theryl Beitrag anzeigen
Hallo zusammen ich habe da ein hoffentlich nur kleines Problem. Und zwar geht es um eine mehrstufige Navigation. Ich habe das die Datei im Netz gefunden und bin schwer begeistert davon.
Ich hätte nun lieber anstatt der zwei level, drei level.
Prinzipiell könntest du einfach eine weitere foreach()-Ebene hinzufügen. Aber man kann die Aufgabenstellung auch generalisieren und beliebige Verschachtelungstiefen zulassen. Dazu benötigt man zwar Rekursion[0], dafür kommt man mit einer foreach()-Schleife aus.

Hinzu kommt, dass hier (möglicherweise) vom Benutzer eingegebene Daten (Zeichenketten) in einen HTML-Zusammenhang gebracht werden. Das schreit nach HTML-Escaping. Leider unterstützt uns PHP dabei nicht konsequent, wir müssen also selbst darauf achten, keine einzige Variable zu vergessen. Und über ein ganzes Script verstreute HTML-Fragmente führen auch ganz schnell zu invalidem Markup.

Ich hab da mal schnell was gebastelt. Die Formatierung ist getrennt vom Durchlaufen des Menü-Baums. Damit ist das HTML-Escaping an einer Stelle konzentriert, und die HTML-Fragmente ebenfalls.

PHP-Code:
interface MenuFormatter {
    function 
formatList($children$level 0);
    function 
formatItem(
        
$children ''// rendered text
        
$level 0// indentation level
        
$href ''// url, path
        
$desc null// description
        
$selected false // whether this item is the current one or not
    
);
}

class 
HtmlListFormatter implements MenuFormatter {
    static function 
esc($cdata) {
        
// or whatever suits your needs
        
return htmlspecialchars($cdataENT_QUOTES'UTF-8');
    }

    private 
$styleClassMenu;
    private 
$styleClassSelected;

    function 
__construct() {
        
// initialize vars
        
$this->styleClassMenu();
        
$this->styleClassSelected();
    }

    
// template for html class attribute
    
const cssClass ' class="%s"';

    
// set class for the surrounding ul-element
    
function styleClassMenu($class 'menu') {
        
$this->styleClassMenu sprintf($this::cssClass$this::esc($class));
        return 
$this;
    }

    
// set class for selected item
    
function styleClassSelected($class 'selected') {
        
$this->styleClassSelected sprintf($this::cssClass$this::esc($class));
        return 
$this;
    }

    const 
nl "\n";
    const 
indent '    ';

    const 
listTemplate '%1$s<ul%2$s>%3$s%1$s</ul>';

    function 
formatList(
        
$children,
        
$level 0
    
) {
        
$indent $this::nl str_repeat($this::indent$level);
        return 
sprintf(
            
$this::listTemplate,
            
$indent,
            
$level $this->styleClassMenu '',
            
$children
        
);
    }

    const 
itemTemplate '%s<li%s><a href="%s">%s</a>%s%s</li>';

    function 
formatItem(
        
$children '',
        
$level 0,
        
$href '',
        
$desc null,
        
$selected false
    
) {
        
$indent $this::nl str_repeat($this::indent$level);
        return 
sprintf(
            
$this::itemTemplate,
            
$indent,
            
$selected $this->styleClassSelected '',
            
$this::esc($href),
            
$this::esc($desc),
            (string) 
$children,
            empty (
$children) ? '' $indent
        
);
    }
}

class 
NestedMenu {
    static function 
hasValidStructure(Array $hmenu) {
        
// insert your menu structure validation code here
        // ...
        
return true;
    }

    private 
$selectedShortPath '';
    private 
$fmtr// MenuFormatter::
    
private $menu// array() menu structure

    
function __construct(
        Array 
$menu,
        
MenuFormatter $fmtr null
    
) {
        if (!
$this::hasValidStructure($menu)) {
            throw new 
Exception('invalid menu structure given');
        }
        
$this->fmtr $fmtr ?? new HtmlListFormatter();
        
$this->menu $menu;
    }

    function 
__toString() {
        return (string) 
$this->render($this->menu);
    }

    
// set the class names in the HtmlListFormatter:: class (if available)
    
function styleClass($what$name) {
        if (!
method_exists($this->fmtr$func "styleClass$what")) {
            throw new 
Exception('invalid style class given');
        }
        return 
$this->fmtr->$func($name);
    }

    
// set the current short path, so the MenuFormatter:: can highlight it
    
function selectedShortPath($spath) {
        
$this->selectedShortPath = (string) $spath;
        return 
$this;
    }

    
// get valid URL or localpath from given short path
    
function buildPath($short_path) {
        return 
$short_path;
    }

    const 
parentName '.';

    
/// return something which is convertible to string
    
function render(
        Array 
$nodes// nested Array; for structure see usage example below
        
$level /// int(0...)
    
) {
        
$out '';
        foreach (
$nodes as $name => $node) {
            if (
$this::parentName === $name) {
                continue;
            }
            if (empty (
$node) && is_array($node)) {
                continue; 
// empty lists make no sense, so we do not render them
            
}
            
$short_path is_array($node)
                ? 
$node[$this::parentName] ?? ''
                
$node;
            
$out .= $this->fmtr->formatItem(
                
is_array($node) ? $this->render($node$level 2) : '',
                
$level 1,
                
$this->buildPath($short_path),
                
$name,
                
$short_path === $this->selectedShortPath
            
);
        }
        if (!isset (
$out[0])) {
            return 
null// skip empty lists
        
}
        return 
$this->fmtr->formatList($out$level);
    }

Die Anwendung ist simpel. Ein Beispiel:
PHP-Code:
$from = array (
    
'Vorwort' => array (
        
'.' => 'vorwort.inc.php',
        
'CSS Dateien strukturieren' => 'strukturieren.inc.php',
    ),
    
'Eigenschaften' => array (
        
'.' => 'eigenschaften.inc.php',
    ),
    
'Aufgaben' => array (
        
'.' => 'aufgaben.inc.php',
        
'Formularfelder' => array (
            
'.' => 'formularfelder.inc.php',
            
'Texteingabefelder' => 'textinput.inc.php',
            
'Optionslisten' => 'optionen.inc.php',
        ),
        
'Listen' => 'listen.inc.php',
        
'Buttons' => 'buttons.inc.php',
    ),
);
$menu = new NestedMenu($from);
$menu->selectedShortPath('formularfelder.inc.php');
$menu->styleClass('Selected''active'); 
echo 
$menu;

// dump html source
echo '<pre>'HtmlListFormatter::esc($menu), '</pre>'
Damit die Links auch "funktionieren", musst du noch die Funktion ->buildPath() anpassen (oder besser in einer abgeleiteten Klasse überschreiben). Wenn du einmal dabei bist, kannst du auch gleich die "short-paths" im Menü-Array um die wiederholten ".inc.php" kürzen.
... und darüber nachdenken, ob es sinnvoll ist, Inhalte als PHP-Dateien einzubinden, statt nur als HTML.

Aus deinem "root"-Key hab ich "." gemacht. Das erschien mir sinnvoller: Root ist das Wurzelverzeichnis, nicht das übergeordnete oder aktuelle. Außerdem tippt sich das schneller. Wenn dir das nicht gefällt, musst du die Konstante :: parentName ändern.

Spezielle visuelle Effekte (wie Hervorhebung oder Einklappen benachbarter Untermenüs) lassen sich über CSS realisieren. Dazu enthält das erzeugte HTML (meiner Meinung nach) ausreichend Kennzeichnungen durch class-Attribute.

Das Implementieren einer Überprüfung der Menüstruktur auf formale Korrektheit in ::hasValidStructure() ist als Übungsaufgabe gedacht.

--
[0] Ich wollte da eigentlich einen Wikipedia-Artikel verlinken, aber zumindest die beiden deutschsprachigen Artikel (Rekursion, Rekursive_Programmierung) sind vollkommen nutzlos, um das rekursive "Durchforsten" von Baum-Strukturen (oder verschachtelten Listen) zu verstehen.

Geändert von fireweasel (18-01-2016 um 22:50 Uhr) Grund: korrigierte li-ul-Verschachtelung + ::parentName im Fließtext wurde zum :-P-Smiley ...
Mit Zitat antworten
  #4 (permalink)  
Alt 12-01-2016, 21:44
h3ll
 Registrierter Benutzer
Links : Onlinestatus : h3ll ist offline
Registriert seit: Mar 2008
Beiträge: 3.419
h3ll befindet sich auf einem aufstrebenden Ast
Standard

Eine weitere Variante von mir:
PHP-Code:
class NavigationNode {
    public 
$title;
    public 
$url;
    public 
$children;
    
    public function 
__construct($title ''$url '', array $children = []) {
        
$this->title $title;
        
$this->url $url;
        
$this->children $children;
    }

PHP-Code:
class NavigationHtmlListRenderer {
    private 
$rootNode;
    private 
$charset;
    
    public function 
__construct(NavigationNode $rootNode$charset 'utf-8') {
        
$this->rootNode $rootNode;
        
$this->charset $charset;
    }
    
    public function 
render($activeUrl ''$formatOutput false) {
        
$dom = new DOMDocument('1.0'$this->charset);
        
        
$rootElement $this->renderNode($dom$this->rootNode);
        
        
$listElement $dom->createElement('ul');
        
$listElement->appendChild($rootElement);
        
$rootElement->appendChild($this->renderChildren($dom$this->rootNode));
        
        
$dom->appendChild($listElement);
        
        foreach (
$dom->getElementsByTagName('a') as $linkElement) {
            if (
$linkElement->getAttribute('href') === $activeUrl) {
                
$linkElement->setAttribute('class''active');
            }
        }
        
        if (
$formatOutput) {
            
$dom->formatOutput true;
        }
        return 
$dom->saveXML($listElement);
    }
    
    private function 
renderNode(DOMDocument $domNavigationNode $node) {
        
$linkElement $dom->createElement('a'$node->title);
        
$linkElement->setAttribute('href'$node->url);
        
        
$listItemElement $dom->createElement('li');
        
$listItemElement->appendChild($linkElement);
        
        return 
$listItemElement;
    }
    
    private function 
renderChildren(DOMDocument $domNavigationNode $parentNode) {
        
$listElement $dom->createElement('ul');
        
        foreach (
$parentNode->children as $node) {
            
$listItemElement $this->renderNode($dom$node);
            if (!empty(
$node->children)) {
                
$listItemElement->appendChild($this->renderChildren($dom$node));
            }
            
            
$listElement->appendChild($listItemElement);
        }
        
        return 
$listElement;
    }

PHP-Code:
$navigation = new NavigationNode('Home''/', [
    new 
NavigationNode(
        
'Main''/main', [
            new 
NavigationNode(
                
'Main Page 1''/main/1'
            
),
            new 
NavigationNode(
                
'Main Page 2''/main/2'
            
),
            new 
NavigationNode(
                
'Main Page 3''/main/3', [
                    new 
NavigationNode(
                        
'Sub Page 1''/main/3/1'
                    
),
                    new 
NavigationNode(
                        
'Sub Page 2''/main/3/2'
                    
)
                ]
            )
        ]
    ),
    new 
NavigationNode(
        
'Contact''/contact'
    
)
]);

$renderer = new NavigationHtmlListRenderer($navigation);
echo 
$renderer->render('/main/3/1'true); 
Ausgabe:
HTML-Code:
<ul>
  <li>
    <a href="/">Home</a>
    <ul>
      <li>
        <a href="/main">Main</a>
        <ul>
          <li>
            <a href="/main/1">Main Page 1</a>
          </li>
          <li>
            <a href="/main/2">Main Page 2</a>
          </li>
          <li>
            <a href="/main/3">Main Page 3</a>
            <ul>
              <li>
                <a href="/main/3/1" class="active">Sub Page 1</a>
              </li>
              <li>
                <a href="/main/3/2">Sub Page 2</a>
              </li>
            </ul>
          </li>
        </ul>
      </li>
      <li>
        <a href="/contact">Contact</a>
      </li>
    </ul>
  </li>
</ul>

Geändert von h3ll (12-01-2016 um 21:47 Uhr)
Mit Zitat antworten
Antwort

Lesezeichen

Stichworte
navigation, php


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Problem mit horizontaler Navigation RazorCko Projekthilfe 4 16-03-2010 10:59
Navigation mit Bild - Problem mit Schleife stocki PHP Developer Forum 2 29-12-2008 16:29
Problem mit bestehender Seiten-Navigation teriax PHP Developer Forum 2 23-12-2004 20:55
Navigation mit Include Befehl/ problem Aerox19 PHP Developer Forum 16 08-12-2004 00:01
Problem: Navigation mit JavaScript Miroculix HTML, JavaScript, AJAX, jQuery, CSS, Bootstrap, LESS 10 14-10-2002 16:42

Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an


PHP News

Multi-Branchen-Marktplatzsoftware 7.2.2 veröffentlicht
Multi-Branchen-Marktplatzsoftware 7.2.2 veröffentlichtDie Software ebiz-trader steht in der Version 7.2.2 zur Verfügung.

28.10.2016 | Berni

Zeit ist Geld, PC einfach selbst reparieren!
Zeit ist Geld, PC einfach selbst reparieren!Wenn der PC nicht richtig läuft, wirft sie das in Ihrem Arbeitsalltag meist zurück. Dabei können Sie einige Probleme mit relativ wenig Aufwand und ohne intime Kenntnisse Ihres Rechners selbst lösene

18.04.2016 | Berni


 

Aktuelle PHP Scripte

SMT by palle

Server &Service Monitor Tool AND Server & Service Management Tool SMT wurde von einem Administrator für Administratoren entwickelt. Es soll den Alltag mit verschiedenen Systemen vereinfachen und die richtigen Mitarbeiter über die richtigen Ereignisse b

14.11.2016 palle | Kategorie: PHP
Umfrage-Script - Abstimmen auf Ihrer Webseite ansehen Umfrage-Script - Abstimmen auf Ihrer Webseite

Das Umfrage-Script ist ein PHP-Programm zur online-Befragung oder online-Abstimmung. Es können eine oder mehrere Fragen mit den entsprechenden Auswahlantworten gestellt werden. Die Ergebnisse des Voting werden summiert und können als Balkendiagramm....

13.11.2016 j-hummel | Kategorie: PHP/ Umfragen
MySync MySQL Datenbanksynchronisierung

MySync benötigt keine ODBC-Verbindung, sondern synchronisiert die MySQL Datenbank per FTP und PHP Zugriff. Sie können beliebig viele Jobs definieren, die dann automatisch zeitgesteuert die Daten zwischen der Client und der Webdatenbank abgleichen. Außerde

08.11.2016 bjoern@ | Kategorie: MYSQL/ Database
 Alle PHP Scripte anzeigen

Alle Zeitangaben in WEZ +2. Es ist jetzt 03:52 Uhr.