Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[PHP] Multi-level menu

Pagina: 1
Acties:

Onderwerpen


  • juiced01
  • Registratie: December 2009
  • Laatst online: 27-11 08:13
Ik ben bezig met een multi-level menu. Ik heb de methode van Crisp gebruikt, op tweakers blog. Maar, nou wil ik ook dat de URL's kloppen.

Stel ik heb een menu:
  • Home
  • Producten
    • Moederbord
    • CPU
  • Over ons
    • Het team
Dan zou ik de volgende URL's willen hebben:
  • /
  • /Producten/
    • /Producten/Moederbord/
    • /Producten/CPU/
  • /Over-ons/
    • /Over-ons/Het-team/
Maar, hoe onthoud ik in die recursive functie in welke parent ik bezig ben? Dus stel ik ben bij menu-item CPU, hoe weet ik dan dat de parent Producten is?

Verwijderd

Hmmm ... ik raad een directe link tussen je menustructuur en je URL's meestal wel af eigenlijk .. maar da's voor je 'probleem' niet echt belangrijk.


Als het goed is heb je in je DB table een parentID toch ?
het enige wat je dan hoeft te doen is :

1) opzoeken welke node je nu zit
2) parent van de huidige node gebruiken om recursief terug te zoeken naar de hoofd id

c'est ca

Verwijderd

In de functie buildMenu geef je de parentID mee, dus daarmee weet je ook wat de naam ervan is met
PHP:
1
2
3
4
5
$parentItem = $menuData['items'][$parentid];

$parentId = $parentItem['id']; // <---
$parentName = $parentItem['name']; // <---
$parentParent = $parentItem['parent_id']; // <---


Het wordt lastiger als je nog dieper gaat, bv /Over-ons/Het-team/John-Doe/

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 23:45
Verwijderd schreef op maandag 14 maart 2011 @ 17:14:
Het wordt lastiger als je nog dieper gaat, bv /Over-ons/Het-team/John-Doe/
Hoeft niet, kwestie van recursief werken en je path tot dan toe meegeven. Dus iets als:
PHP:
1
2
3
4
5
function parseChild ($parent, $node) 
{
    $node -> path = $parent -> path . $node -> basePath;
    parseChild($node, $node -> child);
}

Q&D voorbeeld, voordat het echt werkt zul je ook de randgevallen moeten aanpassen ed

Dan klopt je pad altijd, hoe diep je ook gaat :)

[ Voor 13% gewijzigd door FragFrog op 14-03-2011 18:10 . Reden: Code format ]

[ Site ] [ twitch ] [ jijbuis ]


  • Matis
  • Registratie: Januari 2007
  • Laatst online: 26-11 20:59

Matis

Rubber Rocket

Misschien ook wel interessant om te lezen van onze eigen crisp :)
Crisp's blog: Formatting a multi-level menu using only one query

If money talks then I'm a mime
If time is money then I'm out of time


  • FrameWork.
  • Registratie: September 2007
  • Laatst online: 21:24
Ik heb hier wat aan gehad. Nagenoeg dezelfde code als Crisp alleen heeft diegene een paar dingen aangepast.

De output die er bij mij uitkomt:

HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<div id="menu">
  <ul>
    <li><a href='http://localhost/'>Home</a></li>
    <li><a href='/bedrijfsprofiel/'>Bedrijfsprofiel</a></li>
    <li> <a href='/producten/'>Producten</a>
      <ul>
        <li><a href='/producten/overzicht.html'>Product overzicht</a></li>
        <li><a href='/producten/product-1.html'>Product 1</a></li>
        <li><a href='/producten/product-2.html'>Product 2</a></li>
      </ul>
    </li>
    <li><a href='/news/'>Nieuws</a></li>
    <li> <a href='/referenties/'>Referenties</a>
      <ul>
        <li> <a href='/referenties/nummer.html'>Nummer</a>
          <ul>
            <li><a href='/referenties/1.html'>1</a></li>
            <li><a href='/referenties/2.html'>2</a></li>
            <li><a href='/referenties/3.html'>3</a></li>
          </ul>
        </li>
        <li><a href='/referenties/nummer-twee.html'>2</a></li>
      </ul>
    </li>
    <li><a href='/contact/'>Contact</a></li>
  </ul>
</div>


note: ik heb de linknamen even aangepast ;)

  • juiced01
  • Registratie: December 2009
  • Laatst online: 27-11 08:13
Het is me inmiddels gelukt. Was toch een stuk minder moeilijk dan ik dacht op m'n maandagmiddag ;) Nog even finetunen, maar 't idee is er :). Thanks!

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
    function get_child($parent_id, $menu_data, $menu_id)
    {
        $items = array();
        if($parent_id > 0)
        {
            $parent_item = $menu_data[$menu_id]['items'][$parent_id];
            $items[] = $parent_item->slug;
            $items[] = $this->get_child($parent_item->parent_id, $menu_data, $menu_id);
        }
        $items = array_reverse($items);
        $slug = implode("/", $items);
        return $slug;
    }

[ Voor 0% gewijzigd door juiced01 op 15-03-2011 10:05 . Reden: codetags ]


  • Tux
  • Registratie: Augustus 2001
  • Laatst online: 26-11 08:51

Tux

Dus nu bouw je eerst recursief je menu op, terwijl je later met een andere recursieve functie de url's berekent? Dat lijkt mij niet erg efficient.

Volgens mij is het prima mogelijk om in de buildMenu()-functie een parameter toe te voegen met de url.

Dat gaat dan ongeveer als volgt:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php 
// menu builder function, parentId 0 is the root 
function buildMenu($parentId, $menuData, $url = '/') 
{ 
    $html = ''; 

    if (isset($menuData['parents'][$parentId])) 
    { 
        $html = '<ul>'; 
        foreach ($menuData['parents'][$parentId] as $itemId) 
        { 
            $html .= '<li><a href="' . $url . $menuData['items'][$itemId]['name'] . '/">' . $menuData['items'][$itemId]['name'] . '</a>'; 

            // find childitems recursively 
            $html .= buildMenu($itemId, $menuData, $url . $menuData['items'][$itemId]['name'] . '/'); 

            $html .= '</li>'; 
        } 
        $html .= '</ul>'; 
    } 

    return $html; 
} 

// output the menu 
echo buildMenu(0, $menuData); 
?>


Voor het root-item krijg je dus url '/', en voor elk niveau dieper wordt de naam van een item eraan geplakt.

The NS has launched a new space transportation service, using German trains which were upgraded into spaceships.


  • juiced01
  • Registratie: December 2009
  • Laatst online: 27-11 08:13
Verwijderd schreef op maandag 14 maart 2011 @ 17:09:
Hmmm ... ik raad een directe link tussen je menustructuur en je URL's meestal wel af eigenlijk .. maar da's voor je 'probleem' niet echt belangrijk.
Interessant. Hoe los jij dat op? In dit project is het mogelijk om menu-items aan te maken en te plaatsen in menu's (header, footer, etc..). Bij een menu-item hoort een 'url naam', welke in de database staan. Deze wordt automagisch gevormd aan de hand van de naam in het menu, of je maakt 'm zelf aan. Stel je voegt een menu-item over ons aan, dan maakt 'ie er 'over-ons' van als 'naam in de url'.

Hoe zou jij menu-items opslaan? Een aparte tabel met volledige slug, bijvoorbeeld?

  • juiced01
  • Registratie: December 2009
  • Laatst online: 27-11 08:13
Tux schreef op dinsdag 15 maart 2011 @ 10:15:
Dus nu bouw je eerst recursief je menu op, terwijl je later met een andere recursieve functie de url's berekent? Dat lijkt mij niet erg efficient.

Volgens mij is het prima mogelijk om in de buildMenu()-functie een parameter toe te voegen met de url.

Dat gaat dan ongeveer als volgt:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php 
// menu builder function, parentId 0 is the root 
function buildMenu($parentId, $menuData, $url = '/') 
{ 
    $html = ''; 

    if (isset($menuData['parents'][$parentId])) 
    { 
        $html = '<ul>'; 
        foreach ($menuData['parents'][$parentId] as $itemId) 
        { 
            $html .= '<li><a href="' . $url . $menuData['items'][$itemId]['name'] . '/">' . $menuData['items'][$itemId]['name'] . '</a>'; 

            // find childitems recursively 
            $html .= buildMenu($itemId, $menuData, $url . $menuData['items'][$itemId]['name'] . '/'); 

            $html .= '</li>'; 
        } 
        $html .= '</ul>'; 
    } 

    return $html; 
} 

// output the menu 
echo buildMenu(0, $menuData); 
?>


Voor het root-item krijg je dus url '/', en voor elk niveau dieper wordt de naam van een item eraan geplakt.
8)7 Je hebt helemaal gelijk. Haha!
Pagina: 1