Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: Code and html separation - always or mostly doable?

by Aragorn (Curate)
on Jun 16, 2004 at 10:36 UTC ( [id://367168]=note: print w/replies, xml ) Need Help??


in reply to Code and html separation - always or mostly doable?

I have no experience with HTML::Template, but I use Template Toolkit for my templating needs. Skimming through the documentation of HTML::Template, it seems to me that the Template Toolkit has a bit more features which support code/logic separation better, like default values of variables, and more sophisticated control structures.

There is in my opinion practically always a certain gray area where complete separation of code and presentation is impossible. I try to let the program logic be as generic and modular as possible, and let the template present return values from functions or objects in HTML.

What I tend to do in such cases is to build up an html string, and then feed that string, together with other tmpl outputs, to the template file.
I just give TT a bunch of scalars, arrays and/or hashes which I want to present in HTML, and let the templating engine deal with that.

Arjen

Replies are listed 'Best First'.
Re^2: Code and html separation - always or mostly doable?
by Joost (Canon) on Jun 16, 2004 at 11:24 UTC
    Template::Toolkit is a great system.

    One of the problems I find when making pages with lots of interactivity is that you want to make "subroutines" that create parts of the HTML.

    Example: in a CMS that I'm making - yes, another one - I have a page that lists the document tree, with "nieuw" links that open the editor for a new page. These links can be put on several parts of the page. To simplify this, i made a BLOCK, like so:

    [% BLOCK new_page %] <td width=10><a href="[% editbase %]?action=open&type=page&parent=[% p +age.id %]"><img src="[% imgurl %]/filenew.gif" alt="N"></a></td><td c +olspan="[% span %]" align="left"><a href="[% editbase %]?action=open& +type=page&parent=[% page.id %]" class="new">Nieuw</a></td> [% END %]
    Here, the page items are Class::DBI objects. Now, whenever I want to to show these links, I do:
    [% IF form.action == 'new' %] [% INCLUDE new_page page=some_page span=2 %] [% END %]

    TT uses the same syntax to include other templates, so if needed, I can move the BLOCK to a seperate file without having to change the calling code.

    By the way, I use a seperate hash-ref "form" to store the values I want to set in the form on the editor.

    This $form hashref is initially filled with the values from the CGI request, but it allows me to change the values in "form" (for instance, with data from the $page object from the database) but still have the original request object lying around if I need it. This is a nice seperation of concerns that is very much used in the Struts java MVC framework, and works pretty well for more complicated interactions.

      Another feature of TT that works well with blocks is the macro stuff. It allows you to write "functions" to do various things. i.e.

      this takes a scalar and a list or scalar. If the scalar matches the other scalar or matches a value in the list the macro resolves to "selected" otherwise it does nothing. (used to find selected values in a <select> list.

      [% # sets selected if both values match # tries to see if either side is an array to try and find a match # out of an array of possibly selected values. This will work for m +ultiple # select lists. %] [%- MACRO is_selected(val1, val2) BLOCK -%] [% IF val1 == val2 %] selected [%- selected = 1 %] [% END %] [% IF !selected %] [%- FOREACH value = val1 -%] [%- IF value == val2 -%] selected [%- selected = 1 -%] [%- LAST -%] [%- END -%] [%- END -%] [% END %] [%- IF !selected -%] [%- FOREACH value = val2 -%] [%- IF value == val1 -%] selected [%- LAST -%] [%- END -%] [%- END -%] [%- END -%] [%- END -%]
      This lets you do things like. . . .
      [% # selected items is a list of what should be selected # from this list %] <select name=foo> [% FOREACH select_item = option_list.keys %] <option value="[% option_list.$select_item.value %]" [% is_select +ed(option_list.$select_item.value, selected_items %]> [% option_list.$select_item.display_name %] </option> [% END %] </select>
      I have not seen anything in HTML::Template that will let me come close to being able to do this. Most of the work that the template is doing would have to be shifted into the perl code. with html::Template (afaik, I stopped using after I got approval to use TT). In the above example option_list is a hash (that for sake of argument I got from a library call that I don't control). In H::T I'd have to re-write that structure into an array, I'd also have to resolve the selected attribute inside the perl code. The only place where those things are needed are for the display, so why should they be in the perl code.

      Granted, there is logic in the templates now, but it is solely DISPLAY logic. It is not processing logic. The split I try to get is to not have ANY display logic in the perl code and to not have ANY processing logic in the template. Stuff like properly formatting a date gets put into the template. Stuff like cooking data before it is put into the database lives in the perl code. There seems to be a fairly large camp that does not want to put any logic inside the templates. They are right too. :)

      Sorry if this is a bit long winded but I really enjoy working with this stuff.

        there's an even easier way to do that one ...

        [% mycgi.popup_menu( '-name' => 'mylist', '-values' => [ 1,2,3 ], '-de +fault' => 2 ) %]
        i used that all the time when i was using TT. let the CGI.pm plug-in do its job.
      I've started working in this mode as well since switching to CGI::Application, using templates for layout and CGI for form generation. Can you share some MVC style perl here?
Re^2: Code and html separation - always or mostly doable?
by davis (Vicar) on Jun 16, 2004 at 10:49 UTC
    like default values of variables
    <TMPL_VAR NAME="monkey" DEFAULT="fred">

    davis
    It wasn't easy to juggle a pregnant wife and a troubled child, but somehow I managed to fit in eight hours of TV a day.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://367168]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (9)
As of 2024-04-18 07:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found