Toon posts:

[PHP] Recursive tree menu met Xtemplate

Pagina: 1
Acties:
  • 128 views sinds 30-01-2008

Verwijderd

Topicstarter
Hoi,

Ik ben bezig met het maken van een recursive tree menu, nou krijg ik dit wel voor elkaar zonder xtemplate, maar met gebruik van xtemplate is het iets moeilijker.

En ik moet persee met xtemplate werkend hebben.

Kan iemand mij hier mee helpen ?
Dit is wat ik tot nu toe heb:

PHP:
code:
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
public function parse_menu() 
{
    $menu = $this->get_menu();
    
    $this->__xtpl = new XTemplate(PATH_TEMPLATES.'/global/frontend.menu.html');
    
    foreach ($menu as $item) 
    {       
        $this->parse_menu_item($item);          
    }           
    $this->__xtpl->parse('main');
    
    $this->xtpl->assign('menu', $this->__xtpl->text());
}

private function parse_menu_item($item) 
{
    if (empty($item['childs'])) 
    {
        $this->__xtpl->assign('item', $item);
        $this->__xtpl->parse('main.item.without_child');
    }
    else
    {
        $this->__xtpl->assign('item', $item);
        
        foreach($item['childs'] as $child) 
        {
            // hier zou ik normaal gesproken de functie parse_menu_item moeten aanroepen, maar ik raak de weg kwijt bij de levels.
            $this->__xtpl->parsign('child', $child, 'main.item.with_child.child_item');
        }
        
        $this->__xtpl->parse('main.item.with_child');
    }

    $this->__xtpl->parse('main.item');
}

private function get_menu($parent_id=false, $level=false) 
{       
    $level = $level ? $level++ : 1;
    
    $rebuild = array();
    
    $menu = $this->db->getAll(tbl('menu'), array('parent_id' => $parent_id ? $parent_id : '0'));
    
    foreach ( (array) $menu as $item ) {

        $item['level'] = $level;
        
        ## make link
        if ( is_numeric($item['menu_link']) ) {
            $arrPage = $this->db->getRow(tbl(session_read('menu.table')), array('page_id' => $item['menu_link']));
            $item['menu_link'] = getUrl(array(0 => 'page', 1 => $arrPage['page_label']));
        }
        
        $item['childs'] = $this->get_menu($item['menu_id'], $level+1);
    
        $rebuild[] = $item;
    }
    
    return $rebuild;
}


HTML:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- BEGIN: main -->
<ul>
    <!-- BEGIN: item -->
    
        <!-- BEGIN: without_child -->
        <li><a href="{item.menu_link}">{item.menu_label}</a></li>
        <!-- END: without_child --> 
        
        <!-- BEGIN: with_child -->
        <li>
            <a href="{item.menu_link}">{item.menu_label}</a>
            <ul>
                <!-- BEGIN: child_item -->
                    <li><a href="{child.menu_link}">{child.menu_label}</a></li>
                <!-- END: child_item -->
            </ul>
        </li>
        <!-- END: with_child -->
        
    <!-- END: item -->
</ul>
<!-- END: main -->

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Zo even op het eerste gezicht denk ik dat je dit niet voor elkaar krijgt. Ik ken XTemplate niet, maar tenzij XTemplate zelf een mechanisme kent om de tree te doorlopen (foreach, apply-template, includes, etc) en tenzij je in de phpcode "alvast" templates kunt parsen, krijg je dit niet voor elkaar met een recursieve input.

Wat je wel kunt doen is de array dusdanig ombouwen dat je een platte lijst van items krijgt, waarbij bij elk item de depth is opgegeven. Als je daar doorheen kunt foreach'en in de template, kun je daarin kijken of de depth groter is dan de "vorige" depth; zo ja <ul> en <li> openen, als hij gelijk is niks doen, en als hij kleiner is </li> en </ul> weer afsluiten.

Maar ik ben smarty gewend, dus ik weet niet in hoeverre dit allemaal voor elkaar te krijgen is in xtemplate.

[ Voor 7% gewijzigd door drm op 21-06-2007 14:43 ]

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Verwijderd

Topicstarter
Nou dit moet toch zeker wel mogelijk zijn lijkt mij.. maar wat jij zegt een platte array maken met daar in de diepte van elke item zou ook kunnen werken. dat krijg ik nog wel voor elkaar, ik ga even proberen moment. :D

Verwijderd

Zo uit me hoofd:


HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- BEGIN: main -->
    <!-- BEGIN: child -->
    <li>{item.name}</li>
    <!-- END: child -->
    
    <!-- BEGIN: parent -->
    <li>{item.name}
        <ul>
            {childs}
        </ul>
    </li>
    <!-- END: parent -->
<!-- END: main -->


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
function parse_menu() {

    $menu = get_menu();
    $html = '';
    foreach ($menu as $item) 
    {
        $html.= parse_item($item);
    }
    // $html is je menu
}

function parse_item($item) {

    $xtpl = new XTemplate('menu.html');

    if (empty($item['childs'])) 
    {
        ## heeft geen child items
        $xtpl->assign('item', $item);
        $xtpl->parse('main.child');
    }
    else
    {
        ## heeft child items
        $childs = '';
        foreach ($item['childs'] as $child)
        {
            $childs.= $this->parse_item($child);
        }       
        $xtpl->assign('childs', $childs);
        
        $xtpl->assign('item', $item);
        $xtpl->parse('main.parent');    
    }
    $xtpl->parse('main');
    
    return $xtpl->text();
}


Fouten voorbehouden :)

I know, beetje vies, maar wel met XTemplate :Y) en het werkt (?)

[ Voor 4% gewijzigd door Verwijderd op 21-06-2007 15:04 ]


Verwijderd

Topicstarter
Bedankt man, alleen zaten wel wat fouten in .. oplossing:

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
<?
private function get_menu($parent_id=false, $level=false) 
{       
    $level = $level ? $level++ : 1;
    
    $rebuild = array();
    
    $menu = $this->db->getAll(tbl('menu'), array('parent_id' => $parent_id ? $parent_id : '0'));
    
    foreach ( (array) $menu as $item ) {

        $item['level'] = $level;
        
        ## make link
        if ( is_numeric($item['menu_link']) ) {
            $arrPage = $this->db->getRow(tbl(session_read('menu.table')), array('page_id' => $item['menu_link']));
            $item['menu_link'] = getUrl(array(0 => 'page', 1 => $arrPage['page_label']));
        }
        
        $item['childs'] = $this->get_menu($item['menu_id'], $level+1);
    
        $rebuild[] = $item;
    }
    
    return $rebuild;
}

function parse_menu() {

    $menu = $this->get_menu();
    $html = '';
    foreach ($menu as $item) 
    {
        $html.= $this->parse_item($item);
    }
    echo $html;
}

function parse_item($item) {

    $xtpl = new XTemplate(PATH_TEMPLATES.'/global/frontend.menu.html');
    
    if (empty($item['childs'])) 
    {
        ## heeft geen child items
        $xtpl->assign('item', $item);
        $xtpl->parse('main.child');
    }
    else
    {
        ## heeft child items
        $childs = '';

        foreach ($item['childs'] as $child)
        {
            $childs.= $this->parse_item($child);
        }        
        
        $xtpl->assign('childs', $childs);
        
        $xtpl->assign('item', $item);

        $xtpl->parse('main.parent');    
    }
    $xtpl->parse('main');

    return $xtpl->text();
}
?>


Nu werkt het inderdaad :) thanks.

Verwijderd

OMG, er zaten geen fouten in. Je had het gecopy paste en fout aangepast. Je kan het niet hebben dat je er niet uit kwam en ik wel.

(just for the record, hij zit tegenover me :P)


Haal volgende keer ff code weg die niet van toepassing is op je probleem, dat maakt het wat duidelijker voor de rest ;)

[ Voor 37% gewijzigd door Verwijderd op 21-06-2007 15:50 . Reden: typersfout ]


Verwijderd

Topicstarter
Houd uw mond. slotje.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 30-11 15:10

Creepy

Tactical Espionage Splatterer

Graag, maar niet omdat je probleem is opgelost maar omdat je nogal wat informatie vergeet te geven in je starttopic. Je code dumpen en roepen "het werkt niet" is hier not done. Zie Programming Beleid en dan met name Programming Beleid - De Quickstart

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney

Pagina: 1

Dit topic is gesloten.