[PHP/Smarty] Recursie

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • mcdronkz
  • Registratie: Oktober 2003
  • Laatst online: 16-04 12:44
Goed, ik ben een beetje de weg kwijt. :)

Ik bouw een website in boekvorm, en het idee is dat er hoofdstukken zijn, en dat hoofdstukken weer onder andere hoofdstukken kunnen vallen, etc. Het parent/child verhaal dus.

Je moet je dat een beetje zo voorstellen:
  • Home
  • Accommodatie
    • Licht
    • Koken en verwarmen
      • Frituurpan
  • Brochureaanvraag
etc etc.

Nu heb ik het artikeltje van crisp gelezen, en ik denk dat ik dat aardig begrijp. Met enkel PHP code is er niks aan de hand, ik krijg een fraaie nested list.

Maar zoals de topictitel al doet vermoeden maak ik gebruik van een templateparser, Smarty. Ik heb eea. opgezocht en kwam toen hier uit, maar dat topic helpt je volgens mij alleen verder als je een nested array levert aan Smarty, en het is me een raadsel hoe ik van de array die ik nu heb (zoals in het artikel van crisp) een nested array moet maken.

Ik zou het liefst m'n template in elkaar zetten zoals de code van crisp, dat lijkt me het makkelijkst. Dan zou ik dus een functie moeten definen en die vervolgens aanroepen binnen de template. Maar hoe doe ik dat in vredesnaam? Moet ik daar dan eerst een plugin voor schrijven, of is er een makkelijkere oplossing?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$cSQL = mysql_query("SELECT
                        *
                    FROM
                        vv_chapters
                    ORDER BY
                        cParent, cNavigationOrdering");
                                
$pages = array();
                            
while($cResult = mysql_fetch_assoc($cSQL))
{
    $pages['items'][$cResult['cName']] = $cResult;
    $pages['parents'][$cResult['cParent']][] = $cResult['cName'];
}
        
$smarty->assign("pages", $pages);


Geeft me dus de volgende array:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Array
(
    [] => Array
        (
            [0] => 404
            [1] => home
            [2] => accommodatie
        )

    [accommodatie] => Array
        (
            [0] => koken_verwarmen
            [1] => slapen
            [2] => savonds
            [3] => licht
        )

    [koken_verwarmen] => Array
        (
            [0] => frituurpan
        )

)


Heeft iemand dit wel eens gedaan, wie kan me een beetje sturen?

[ Voor 21% gewijzigd door mcdronkz op 24-07-2009 05:38 ]


Acties:
  • 0 Henk 'm!

  • NielsNL
  • Registratie: Januari 2002
  • Laatst online: 08-09 20:14

NielsNL

DigiCow

Zo te zien heb je al netjes een nested array.
Wat nog niet in je post staat is het stukje smarty code, die de array verwerkt,zet die er eens bij...

M'n Oma is een site aan het haken.


Acties:
  • 0 Henk 'm!

  • AW_Bos
  • Registratie: April 2002
  • Laatst online: 01:30

AW_Bos

Liefhebber van nostalgie... 🕰️

Kijk anders eens op: http://www.smarty.net/man...uage.function.foreach.php
Staan prachtige voorbeelden over je met Smarty door een array kan wandelen. :)

Telecommunicatie van vroeger
🚅Alles over spoor en treintjes


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 19-09 08:51

Janoz

Moderator Devschuur®

!litemod

NielsNL schreef op vrijdag 24 juli 2009 @ 06:51:
Zo te zien heb je al netjes een nested array.
Waar dan? Ik zie hem niet. Ik zie alleen maar een 2 dimensionale array.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 19-09 12:39

MBV

Waarom geen nested array gebruiken?
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Array
(
    [home] => content

    [accommodatie] => Array
        (
            [koken_verwarmen] => Array 
              (
                  [Frituurpan] => Content
              )
            [slapen] => Content
            [savonds] => Content
            [licht] => Content
        )

)


En ik heb geen idee waarom je Smarty gebruikt, maar kennelijk is dit iets wat niet met smarty lukt. Dan zal je een concessie moeten doen: maximaliseer de diepte van je nested array op 3, en maak de templates zo dat ze ermee om kunnen gaan. Over het algemeen is een willekeurig diepe boomstructuur toch niet echt makkelijk qua layout ;)

offtopic:
Dit is dus de reden dat je geen template engine moet gebruiken: daar heb je PHP al voor >:)

[ Voor 7% gewijzigd door MBV op 24-07-2009 11:00 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Gewoon wat voorbeeld code uit een smarty template die ik ooit eens gemaakt heb:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
{section name="index" loop="$berekeningen"}
  <!-- bla bla -->
  {assign var="Afwijkingen" value="`$berekeningen[index].Ruimteverwarming`"}
  {section name="aindex" loop="$Afwijkingen"}
    {if isset($Afwijkingen[aindex].Figuren)}
      {assign var="Figuren" value="`$Afwijkingen[aindex].Figuren`"}
      {section name="findex" loop="$Figuren"}
      <!-- toon iets -->
      {/section}
    {/if}
  {/section}
  <!-- bla bla -->
{/section}


Sowieso is foreach wat netter, maar dit werkte toen en moet wel een goede indicatie geven hoe en wat mogelijk is.

Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 18-09 17:57
MBV schreef op vrijdag 24 juli 2009 @ 10:59:
offtopic:
Dit is dus de reden dat je geen template engine moet gebruiken: daar heb je PHP al voor >:)
Of juist wel; nu wordt de TS "verplicht" na te denken over wat hij met zijn data doet voor het naar de presentation layer gaat - een van de grootste voordelen van Smarty in mijn opinie is dat het ervoor zorgt dat mensen niet met een zut syntax duizend verschillende databronnen nog eens tijdens de presentatie aan elkaar gaan lopen knopen. Mind you, er zijn ook mensen die er exact omgekeerd over denken, laten we alsjeblieft niet voor de miljoenste keer weer in die discussie vallen :+

Recursie is in Smarty trouwens prima toe te passen. Een mogelijke oplossing hiervoor is om een aparte file te maken voor het weergeven van een child - de code inclusief foreach tags zet je dan in een apart bestand wat je in die foreach weer aanroept:
code:
1
2
3
4
5
6
{foreach from=$parent item=child}
  {if $child.hasChildren}
    {include file='deze_foreach.tpl' parent=$child.children}
  {/if}
  [overige presentatie van de child nodes]
{/foreach}

(Overigens is die if eigenlijk zelfs overbodig, Smarty doet die controle ook zelf zodat als ik me niet vergis het geen E_NOTICE oplevert).

Merk trouwens op dat bij er een variable assignment in de include zit. Dit zorgt ervoor dat $parent in het geinclude blok de waarde krijgt die je toekent - als $child.children dan een array is met andere nodes, elk eventueel weer met nog meer granchildren krijg je een prima mooie recursieve lijst items :)

[ Voor 10% gewijzigd door FragFrog op 24-07-2009 14:14 ]

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • mcdronkz
  • Registratie: Oktober 2003
  • Laatst online: 16-04 12:44
'k Heb het nu als volgt opgelost:

code:
1
2
3
4
5
6
7
8
9
10
<ul>
    {foreach from=$pages.parents.0 item=item}
        <li>{$pages.items.$item.cNavigationName}</li>
        {if $pages.parents.$item}
            <ul>
                {include file="admin_contents/pages_recursion.tpl" parent=$pages.parents.$item}
            </ul>
        {/if}
    {/foreach}
</ul>


&

code:
1
2
3
4
5
6
7
8
{foreach from=$parent item=item}
    <li>{$pages.items.$item.cNavigationName}</li>
    {if $pages.parents.$item}
        <ul>
            {include file="admin_contents/pages_recursion.tpl" parent=$pages.parents.$item}
        </ul>
    {/if}
{/foreach}


Misschien niet de meest toffe oplossing, maar 't werkt prima.

edit:
Inderdaad FragFrog!

Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 19-09 12:39

MBV

FragFrog schreef op vrijdag 24 juli 2009 @ 14:11:
Mind you, er zijn ook mensen die er exact omgekeerd over denken, laten we alsjeblieft niet voor de miljoenste keer weer in die discussie vallen :+
offtopic:
Vandaar dat ik hem tussen off-topic tags had staan en er een evil-smiley achter had gezet... En ik kan wel goed genoeg programmeren, ik denk over dat soort dingen zelf wel na. Trouwens: zou heel PHP niet de presentation layer moeten zijn? O-)
Oh shit, doe 'k het weer.
Recursie is in Smarty trouwens prima toe te passen. Een mogelijke oplossing hiervoor is om een aparte file te maken voor het weergeven van een child - de code inclusief foreach tags zet je dan in een apart bestand wat je in die foreach weer aanroept:
code:
1
2
3
4
5
6
{foreach from=$parent item=child}
  {if $child.hasChildren}
    {include file='deze_foreach.tpl' parent=$child.children}
  {/if}
  [overige presentatie van de child nodes]
{/foreach}
Ik ken een ander (in-house ontwikkeld, niet zo goed als Smarty) template-systeem, en dit was het soort situaties dat je nauwelijks nog kon debuggen :X Suc6 als het fout gaat.

Acties:
  • 0 Henk 'm!

  • _Sunnyboy_
  • Registratie: Januari 2003
  • Laatst online: 19-09 14:58

_Sunnyboy_

Mooooooooooooooooo!

Dat is waarom ik na experimenten met Smarty en andere template systemen afgestapt ben van een echte template engine. Smarty was de enige goeie oplossing die ik kon vinden, maar is nogal zwaar en ik vroeg me af waarom ik een nieuwe taal (Smarty) zou moeten leren als alles ook in php zelf kan.

Mind you ik breng wel een duidelijke scheiding aan tussen mijn business logica & mijn display logica. In feite zit de display logica in een apart bestand dat bestaat uit html met display php erdoorheen. Het klopt dat me met bijv Smarty wordt gedwongen meer in zo'n scheiding tussen display & business logica te denken, maar het ook prima zonder, en dat is voor mij in ieder geval de beste oplossing in ieder geval.

In any case success. Zoals al eerder door iemand gezegd zal je voor navigatie toch niet een oneindig diepe boom gaan weergeven, omdat dat er netjes uit te laten zien al gauw onmogelijk wordt. Er zijn volgens mij weinig goeie sites die meer dan 3 niveau's gebruiken. Daarom moet je je afvragen of je hiervoor wel echte recursie nodig hebt.

Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life


Acties:
  • 0 Henk 'm!

  • Slagroom
  • Registratie: Juni 2001
  • Laatst online: 05-10-2024
Ik denk dat je hier je antwoord vindt:
http://www.phpinsider.com...79822209698bda38bc6632cca
Pagina: 1