[PHP] Menu op basis van arrays

Pagina: 1
Acties:
  • 320 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hoi,

Ik ben bezig aan een arraygebaseerde navigatie. Dit heb ik momenteel:
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
$navigatie = array();
$navigatie_sub = array();
$navigatie['informatief'] = "Informatief";
$navigatie_sub['informatief']['motivatie'] = "Motivatie";
$navigatie_sub['informatief']['aanpak'] = "Aanpak";
$navigatie['demonstratief'] = "Demonstratief";
echo(navigatie3($navigatie, $navigatie_sub, $pagina));
function navigatie3($navigatie, $navigatie_sub = "", $huidige_pagina){
    $lijn = "<ul>";
    foreach($navigatie as $pagina => $naam){
        $lijn .= "<li><a href=\"index.php?pagina=" . $pagina . "\">" . $naam . "</a></li>";
        if(array_key_exists($pagina, $navigatie_sub) && $pagina == $huidige_pagina){
            $lijn .= navigatie_sub3($navigatie_sub[$pagina], $huidige_pagina);
        }
    }
    $lijn .= "</ul>";
    return $lijn;
}
function navigatie_sub3($navigatie_sub, $huidige_pagina){
    $lijn = "<ul>";
    foreach($navigatie_sub as $pagina => $naam){
        $lijn .= "<li><a href=\"index.php?pagina=" . $pagina . "\">" . $naam . "</a></li>";
    }
    $lijn .= "</ul>";
    return $lijn;
}


Dat werkt op het eerste niveau erg goed, maar wanneer ik op 'motivatie' klik, klapt het menu weer dicht. Ik zou moeten controleren of die 'motivatie' deel uitmaakt van een groter geheel, maar ik zie even niet meer wat en hoe.

Een 'werkende' case vind je hier.

[ Voor 0% gewijzigd door Verwijderd op 13-04-2007 11:49 . Reden: Lap, fout in de titel... Liever: [PHP] Menu op basis van arrays ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Wat voor nut heeft het om de values van je array dezelfde tekst te laten bevatten als je keys, maar dan anders in hoofdletters?

Verder, over je probleem: je zou array_search kunnen gebruiken, zie ook de comments. Met array_key_exists kun je ook wel wat doen, maar niet als je mijn eerste opmerking in deze post begrijpt. :P Maak gewoon een recursieve functie die array_search voor elk element aanroept dat een array is, onthou met welke node je bezig bent en return dat zodat je deze uit kan klappen.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Superbedankt voor je hulp -NMe-, maar ik vrees dat ik er niet helemaal uitkom. Door eens goed naar die comments bij array_search(); te kijken, snap ik nu ook dat mijn opzet tot 2 niveaus beperkt blijft, en dat wil ik liever niet.

Zou je me een beetje verder op weg kunnen helpen?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
*Duwt een beetje*

Acties:
  • 0 Henk 'm!

  • _eXistenZ_
  • Registratie: Februari 2004
  • Laatst online: 19-09 01:03
*duwt een beetje terug, in de richting van Smarty*

Volgens mij moet je het daar zoeken, Smarty kan al een hoop dingen zoals dropdowns en lists enzo op basis van een array.

There is no replacement for displacement!


Acties:
  • 0 Henk 'm!

  • Spockz
  • Registratie: Augustus 2003
  • Laatst online: 10:08

Spockz

Live and Let Live

Pfoe. Om hiervoor nou meteen naar een templating systeem over te stappen vind ik enigzins rigoreus. Dit kan je ook makkelijk zelf oplossen.

C'est le ton qui fait la musique. | Blog | @linkedin
R8 | 18-55 IS | 50mm 1.8 2 | 70-200 2.8 APO EX HSM | 85 1.8


Acties:
  • 0 Henk 'm!

Verwijderd

Mij lijkt het dat je je datastructuur niet helemaal leuk hebt uitgedacht. Hier mijn voorstel:

PHP:
1
2
3
$menu = array(
   'Menunaam' => 'menuwaarde'
);


Als basis, waarbi menunaam de naam is die het visueel heeft en menuwaarde twee dingen kan zijn:
- een array: dan heeft het menu een submenu <en heeft zelfde structuur als hoofmenu array>.
- een Tekstuele waarde: dat is dan de link voor die pagina.

Dan zou je dus zoiets krijgen:
PHP:
1
2
3
4
5
6
7
8
$menu = array(
  'MyProfile' => array('logout' =>'logout.php', 
                       'view' => 'profile.view.php'),
   'FAQ' => 'faq.php',
   'Informatief' => array('motivatie' => 'index.php?pagina=motivatie',
                          'aanpak' => 'index.php?pagina=motivatie'),
   'Demonstratief' => 'index.php?pagina=demonstratief'
);


En om hem weer te geven:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function leukeNaamVoorZonLelijkeFunctie($input)
{
    $output = '<ul>';
    foreach ($input as $menuName => $menuValue)
    {
        $output .= '<li>';
        if (is_array($menuValue))
        {
            $output .= $menuName . leukeNaamVoorZonLelijkeFunctie($menuValue);
        }
        else
        {
            $output .= '<a href="' . $menuValue . '">' . $menuName . '</a>';
        }
        $output .= '</li>';
    }
    $output .= '</ul>';
    return $output;
}


EN dan voor je menu op te maken in HTML/Javascript:
http://alistapart.com/articles/dropdowns

Alles ongetest :) Maar als er een fout inzit, valt daar wel uit te komen gok ik

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Alleen kan je op die manier niet linken naar 'MyProfile' en 'Informatief' ;)

Hier @ GoT kan je zowel op 'MyReact' klikken, als het menu uitklappen en dáár in iets aanklikken :)

Acties:
  • 0 Henk 'm!

Verwijderd

Valt ook wel wat voor te verzinnen :)
Ik weet niet of dat een ijs is, maar dan kan je nog altijd doen:
menunaam = array(link, submenu)
en dan word de code:

PHP:
1
2
3
4
5
6
7
...
if (is_array($menuValue))
{
  $output .= '<a href="' . $menuValue[0] . '">' . $menuName . '</a>' . 
             leukeNaamVoorZonLelijkeFunctie($menuValue[1]); 
}
...


Maar licht eraan wat hij precies wil :) daar kan ie zelf wel over nadenken ter zijner tijd.

Totaal word dan:
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
28
29
30
31
32
33
34
35
<?php
$menu = array(
  'MyProfile' => array('MyProfile.php',
                       array('logout' =>'logout.php', 
                             'view' => 'profile.view.php')),
   'FAQ' => 'faq.php',
   'Informatief' => array('Informatief.php',
                          array('motivatie' => 'index.php?pagina=motivatie',
                                'aanpak' => 'index.php?pagina=motivatie')),
   'Demonstratief' => 'index.php?pagina=demonstratief'
);

function leukeNaamVoorZonLelijkeFunctie($input)
{
    $output = '<ul>';
    foreach ($input as $menuName => $menuValue)
    {
        $output .= '<li>';
        if (is_array($menuValue)) 
        { 
          $output .= '<a href="' . $menuValue[0] . '">' . $menuName . '</a>' .  
                     leukeNaamVoorZonLelijkeFunctie($menuValue[1]);  
        } 
        else
        {
            $output .= '<a href="' . $menuValue . '">' . $menuName . '</a>';
        }
        $output .= '</li>';
    }
    $output .= '</ul>';
    return $output;
}

echo leukeNaamVoorZonLelijkeFunctie($menu);
?>

[ Voor 55% gewijzigd door Verwijderd op 15-04-2007 14:32 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Wow, bedankt, Hel Gast.

Ik was een paar dagen geleden op ongeveer hetzelfde idee gekomen - eigenlijk heb ik een gevonden script wat verbasterd. Dit is het geworden:

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
28
29
30
31
32
33
34
35
<?
$menu = array(
"navtest.php?pagina=parent2"     => "Index",
"navtest.php?pagina=parent3"    => "About",
"navtest.php?pagina=parent4"     => "More",
"navtest.php?pagina=parent1" => array(0 => "Parent 1",
    "navtest.php?pagina=child1" => "Child 1",
    "navtest.php?pagina=child2" => "Child 2",
    "navtest.php?pagina=child3" => array(0 => "nog lager",
        "navtest.php?pagina=child31" => "Child 31",
        "navtest.php?pagina=child31" => "Child 32"),
    "navtest.php?pagina=parent3" => "Child 3"),
"andere.php" => "Andere pagina");
?>
<?
function tree_menu($array, $indent=0) {
    $prefix = "";
    for ($i=0; $i<$indent; $i++) {
        $prefix .= "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
    }
    while (list ($key, $value) = each($array)){
        if (is_array($value) && $_GET['pagina'] == str_replace("navtest.php?pagina=", "", $key)){
            echo $prefix . "<a href='" . $key . "'>" . $value[0] . "</a><br>";
            array_shift($value);
            tree_menu($value, $indent + 1);
        }
        elseif(is_array($value)){
            echo $prefix . "<a href='" . $key . "'>" . $value[0] . "</a><br>";
            array_shift($value);
        } else {
            echo $prefix . "<a href='" . $key . "'>" . $value . "</a><br>";
        }
    }
}
?>


Nu heb ik in ieder geval al een proper scriptje, maar nu stoot ik terug op mijn initiële probleem:
Dat werkt op het eerste niveau erg goed, maar wanneer ik op 'motivatie' klik, klapt het menu weer dicht. Ik zou moeten controleren of die 'motivatie' deel uitmaakt van een groter geheel, maar ik zie even niet meer wat en hoe.
Kan je nog even naar mijn case kijken?

Acties:
  • 0 Henk 'm!

  • Daos
  • Registratie: Oktober 2004
  • Niet online
Een meerdan1D-array is alleen makkelijk als je ook meerdere indices meekrijgt. In dit geval kan je dus het beste alleen een 1D gebruiken:
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
$name = array();
$name['informatief'] = "Informatief"; 
$name['motivatie'] = "Motivatie"; 
$name['extra'] = "Extra";
$name['aanpak'] = "Aanpak"; 
$name['demonstratief'] = "Demonstratief";
$name['praktisch'] = "Praktisch";

$parent = array();
$parent['informatief'] = NULL; 
$parent['motivatie'] = 'informatief'; 
$parent['extra'] = 'motivatie'; 
$parent['aanpak'] = 'informatief'; 
$parent['demonstratief'] = NULL;
$parent['praktisch'] = NULL;

function inPathToRoot($node, $input) 
{ 
    global $parent;

    $current = $input;

    while(isset($current)) {
        if ($current == $node)
            return true;
        $current = $parent[$current];
    }

    return false;
}

function generateSubMenu($node, $input) 
{ 
    global $parent;
    global $name;

    echo "<ul>";
    foreach(array_keys($parent, $node) as $child) {
        echo "<li><a href=\"test45.php?pagina=" . $child . "\">";
        if ($child == $input)
            echo "<b>".$name[$child]."</b>";
        else
            echo $name[$child];
        echo "</a></li>"; 

        if (inPathToRoot($child, $input))
            generateSubMenu($child, $input);
    }

    echo "</ul>";
}

generateSubMenu(NULL, $_GET['pagina']);

Acties:
  • 0 Henk 'm!

  • Daos
  • Registratie: Oktober 2004
  • Niet online
Ander voorbeeldje (er zijn meerdere wegen die naar Rome leiden):
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
$name = array();
$name['informatief'] = "Informatief"; 
$name['motivatie'] = "Motivatie"; 
$name['extra'] = "Extra";
$name['aanpak'] = "Aanpak"; 
$name['demonstratief'] = "Demonstratief";
$name['praktisch'] = "Praktisch";

$menu = array( 
  'informatief' => array('motivatie' => array('extra' => NULL),
                         'aanpak' => NULL), 
  'demonstratief' => NULL, 
  'praktisch' => NULL);


function stripMenu($menu, $input) {
    $newmenu = array();
    $inputseen = false;

    foreach($menu as $item => $submenu) {
        if ($item == $input) {
            $inputseen = true;
            if (isset($submenu))
               foreach(array_keys($submenu) as $subitem)
                   $submenu[$subitem] = NULL;
            $newmenu[$item] = $submenu;
        }
        else if (isset($submenu)) {
            $submenu = stripMenu($submenu, $input);
            $newmenu[$item] = $submenu;
            $inputseen |= isset($submenu);
        }
        else {
            $newmenu[$item] = NULL;
        }
    }

    if ($inputseen)
        return $newmenu;
    else
        return NULL;
}

function generateMenu($menu, $input) { 
    global $name;

    echo "<ul>";
    foreach($menu as $item => $submenu) {
        echo "<li><a href=\"test46.php?pagina=".$item."\">";
        if ($item == $input)
            echo "<b>".$name[$item]."</b>";
        else
            echo $name[$item];
        echo "</a></li>"; 

        if (isset($submenu))
            generateMenu($submenu, $input);
    }

    echo "</ul>";
}

$input = $_GET['pagina'];
$newmenu = stripMenu($menu, $input);
if (!isset($newmenu)) {
    $newmenu = $menu;

    foreach(array_keys($newmenu) as $item)
        $newmenu[$item] = NULL;
}
generateMenu($newmenu, $input);


Je ziet dus dat het algoritme al een heel stuk moeilijker (= grotere kans op bugs) wordt als je je menu in een meerdan1D array zet.

Acties:
  • 0 Henk 'm!

  • Daos
  • Registratie: Oktober 2004
  • Niet online
Nog een voorbeeldje (meerdan1D-array en meerdere inputs):
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
$name = array(
  'informatief' => 'Informatief',
  'motivatie' => 'Motivatie',
  'extra' => 'Extra',
  'aanpak' => 'Aanpak',
  'demonstratief' => 'Demonstratief',
  'praktisch' => 'Praktisch'); 

$menu = array(  
  'informatief' => array('motivatie' => array('extra' => NULL), 
                         'aanpak' => NULL),  
  'demonstratief' => NULL,  
  'praktisch' => NULL); 

function generateMenu($menu, $level, $input) {  
    global $name; 

    echo '<ul>'; 
    foreach($menu as $item => $submenu) { 
        echo '<li><a href="test48.php?';
        for ($i = 0; $i < $level; $i++)
            echo 'l'.$i.'='.$input[$i].'&';
        echo 'l'.$level.'='.$item.'">';

        if ($level == count($input) - 1 && $item == $input[$level])
            echo '<b>'.$name[$item].'</b>';
        else
            echo $name[$item];
        echo '</a></li>'; 

        if (isset($submenu) && $item == $input[$level])
            generateMenu($submenu, $level + 1, $input);
    } 
    echo '</ul>'; 
} 

$input = array();
$i = 0;
while (array_key_exists('l'.$i, $_GET)) {
    $input[$i] = $_GET['l'.$i];
    $i++;
}

generateMenu($menu, 0, $input);


Je ziet dus dat het algoritme al een heel stuk makkelijker wordt als je meerdere inputs gebruikt bij een menu in een meerdan1D-array. Maar mijn voorbeeld van een 1 input en een 1D array was toch nog iets simpeler...

[ Voor 16% gewijzigd door Daos op 16-04-2007 22:07 . Reden: code simpeler gemaakt ]

Pagina: 1