tinita has asked for the wisdom of the Perl Monks concerning the following question:

hello monks, i'm using HTML::Template and TMPL_LOOP. i think i don't need a more complex templating system, there are only two little things at the moment i miss with this module. suppose i have data like:
my $data = { name => 'name', id => 1, categories => [ { id => 1, title => 'projects', ...}, { id => 2, title => 'index', ...}, ], };
and the template:
<TMPL_VAR NAME=ID>: <TMPL_VAR NAME=NAME><br> <TMPL_LOOP NAME=CATEGORIES> <TMPL_VAR NAME=ID>/<TMPL_VAR NAME=TITLE> | </TMPL_LOOP>
then it outputs:
1: name<br> 1/projects | 2/index |
first thing is: i only want one pipe | between the items, like in perl join " | ", @$items.
do you know any way to do that with HTML::Template?

the second thing: i'd like to be able to control the order of the items from the template (reason: the code is part of a kind of framework or CMS, and i don't want to hardcode it).

what i've done for the second problem:

i added a tag: <TMPL_VAR NAME=SET_REVERSE> which has to be inside of the loop. before i generate the template i use the query()-function to detect if the tag SET_REVERSE is in that loop, and then i reverse the list.
foreach my $key (keys %$result) { if ($self->template()->query( name => $key) eq 'LOOP') { if ($self->template()->query( name => [$key, 'SET_REVE +RSE'])) { @{$result->{$key}} = reverse @{$result->{$key} +}; } } }
this seems to work fine (i'm working only with one level deep data structures, fortunately). but it seems unelegant. do i need a different templating system? anyone can recommend one? or does this look reasonable to you?
thanks for any comments...

Replies are listed 'Best First'.
Re: HTML::Template - loop order
by ccn (Vicar) on Aug 03, 2004 at 18:44 UTC
    i only want one pipe | between the items, like in perl join

    turn on loop_context_vars and use __last__

    <TMPL_VAR NAME=ID>: <TMPL_VAR NAME=NAME><br> <TMPL_LOOP NAME=CATEGORIES> <TMPL_VAR NAME=ID>/<TMPL_VAR NAME=TITLE> <TMPL_UNLESS NAME=__last__>|</TMPL_UNLESS> </TMPL_LOOP>
      turn on loop_context_vars and use __last__
      great, thanks. saved my day =)
      next time i'll read the docs more carefully

        concerning the second problem I can suggest two ways

        • If you can use unique names for you LOOPs in a html, then you may use global vars like "SOMENAME_REVERSED" in the begin of html not inside of deep structures
        • If your LOOPs are not huge then you may provide the both direct and reversed representations of the list for each LOOP. e.g. <TMPL_LOOP NAME='NAME'> and <TMPL_LOOP NAME='NAME_REVERSED'>. So you don't need to detect anything
Re: HTML::Template - loop order
by waswas-fng (Curate) on Aug 03, 2004 at 21:29 UTC
    Problem one is already solved above. Problem two is very solvable as well. You really have a few options. Sure you can switch templating systems to one that has more control of the data -- but to me that puts you on a slippery slope. It makes it easy for you to one off break the barrier of model-view-controller design. I would have my templates show the data and form the data in the right order etc in my code. Have some sort of flag that sets how data is sorted on the screen you are working on and expose the data to the template pre sorted in that way. Once you start tossing code in your templates they become much less valuable to you.


    -Waswas
      i absolutely agree to do as much as possible in the code and not in the template. the more possibilities the template has, the more you are tempted to use them, i guess.

      but setting the order of items (not something more complicated like 'sortby column ...') sounds like something to me that the html designer can have control over.

      but i could also make the sort order an option which as to be set for the 'View'. mmh, difficult. i'll decide later =)

Re: HTML::Template - loop order
by Aristotle (Chancellor) on Aug 03, 2004 at 18:44 UTC

    first thing is: i only want one pipe | between the items, like in perl join " | ", @$items.

    <TMPL_VAR NAME=ID>: <TMPL_VAR NAME=NAME><br> <TMPL_LOOP NAME=CATEGORIES> <TMPL_VAR NAME=ID>/<TMPL_VAR NAME=TITLE><TMPL_UNLESS __last__> | </TMP +L_UNLESS> </TMPL_LOOP>

    i'd like to be able to control the order of the items from the template (reason: the code is part of a kind of framework or CMS, and i don't want to hardcode it).

    From my quick skimming of docs, that doesn't seem possible. Personally, I use the Template Toolkit II for all my templating needs.

    Makeshifts last the longest.

      thanks, too.
      i think someday i have to look at other templating systems anyway, so maybe i've got time to switch to tt2.
Re: HTML::Template - loop order
by antirice (Priest) on Aug 03, 2004 at 18:59 UTC

    First problem can be fixed by turning on loop_context_vars and using the following:

    <TMPL_VAR NAME=ID>: <TMPL_VAR NAME=NAME><br> <TMPL_LOOP NAME=CATEGORIES> <TMPL_VAR NAME=ID>/<TMPL_VAR NAME=TITLE><TMPL_UNLESS __last__> | </TMP +L_UNLESS> </TMPL_LOOP>

    As for the second problem, I don't see another way around your problem beyond what you already have. The template is just presenting the data you gave it.

    antirice    
    The first rule of Perl club is - use Perl
    The
    ith rule of Perl club is - follow rule i - 1 for i > 1