Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

The hidden charm of Template::Toolkit (and templates generally)

by roman (Monk)
on Jan 06, 2008 at 20:02 UTC ( #660685=perlquestion: print w/ replies, xml ) Need Help??
roman has asked for the wisdom of the Perl Monks concerning the following question:

Experienced monks,

i am about to do some web programming in Perl, so I started to learn about Catalyst and MVC. I have some previous experience with HTML::Mason, but Catalyst uses Template::Toolkit as the first option for view components.

Why? Why is it worth to use (and learn) a different language for the template? I ask, I don't argue, because obviously many people dot it and someone even presented TT as a standard tool for web page development at Vienna.pm lightning talks.

So far I found only 3 reasons hardly applicable in our environment:

  • It is language (Perl) independent. Which seems of no concern for me, since we develop all of our application in Perl (or PL/SQL :-)).
  • It is safer, since the template developer has no access to naked Perl. It also seems of no concern because the template developer is me or my office mate.
  • Different template languague supports the separation of the view from the model and controller. It seems a bit academic for me now.

Am I wrong? Is there any other - sound and general reason to prefer TT from Mason?

But even If HTML::Mason is the appropriate choice for my environment I can go a bit further. Why to use ANY template engine at all? Why don't use ordinary Perl for the view components?

Everytime I tried a template based development (Perl + HTML::Mason and a bit of PHP + Smarty) I ended up with quite a messy template with lots of iterations and conditions intertwined with plain text.

Where is the advantage of mason template:

<table> <tr><th>Title</th><th>Rating</th><th>Author(s)</th></tr> % for $book (@books){ <tr> <td><% $book->title %></td> <td><% $book->rating %></td> <td> <%perl> my @authors = $book->authors; </%perl> (<% scalar @authors %>) <% join(', ', @authors) %> </td> </tr> %} </table>

over Perl code (I use fictional function-to-html interface, I believe there must be plenty of them)?

print html_table( html_tr( html_th('Title'), html_th('Rating'), html_th('Authors'), ( map { my $book = $_; html_tr( html_td( $book->title ), html_td( $book->rating ), html_td( do { my @authors = $book->authors; scalar(@authors) . ' ' . join( ', ', @auth +ors ); } ) ); } @books ) ) );

Comment on The hidden charm of Template::Toolkit (and templates generally)
Select or Download Code
Re: The hidden charm of Template::Toolkit (and templates generally)
by pemungkah (Priest) on Jan 06, 2008 at 22:10 UTC
    The separation of "creating the data" and "showing the data" is actually quite critical in providing a robust development environment for your application.

    Consider: if the data generation and display reside in the same subroutine, you've restricted your development in two different ways: one, there's no easy way to reuse the code that generates the data for another purpose without a refactor. Second, a change to the code that outputs the data can possibly break the code that generates it.

    Code that is decoupled into parts that generate data for someone else to consume, and parts that take data and display it, are now WAY easier to test as well. The generator code can be tested quite easily: call it, and is the right stuff returned. The display code can be tested by feeding it data which you have control of, verifying that the right thing is displayed.

    So the separation vastly simplifies the process, which gives you more time to get things done, and makes it easier to be more adventurous in other places. For instance, all those building blocks can be used now to build a REST interface, simply by expanding different templates with the data they feed you.

      I agree. I don't have any problem to find reason for Model-View-Controller separation. The question regards solely the technology for the View component.

      What is the advantage of template system not using Perl (Template::Toolkit) over templates using Perl for control structures, expanded expression, ... (HTML::Mason) over view component, which uses no templates just plain Perl code printing the HTML?

        The reason why it makes sense to use an entirely different language for the templates is quite simply to avoid using Perl. You may be very proficient in writing Perl code, but quite often the people who deal with the templates (and in general the 'View' part of the equation) are web designers. Those people are more likely to be better at HTML and CSS, and it therefore makes more sense to teach them how to use a simple template syntax (% s.name %) instead of teaching Perl (print $s{name}).

        Even if all your web designers are Perl hackers, I think it still makes sense to learn a different templating language just for the sake of code clarity. I find it much easier to do all the hard work in my Perl in my Controller class, shove those variables in the stash (I use Catalyst), and then simply print and loop through the variables with the Template Toolkit.

        All in all, TT is a very powerful system, and a language of its own. I once designed an entire web page that didn't need any "real" dynamic content, so I didn't have to write one line of Perl code: the whole thing was developed using Template toolkit and the ttree helper application.

Re: The hidden charm of Template::Toolkit (and templates generally)
by eserte (Deacon) on Jan 06, 2008 at 22:29 UTC
    My rule of thumb is: if you need to generate text, then use a templating language if the dynamic part is much smaller than the already present static part of the text. I use Template-Toolkit for a lot of text generating, not necessarily HTML. Often it's just existing Makefiles or mapserver files or crontabs or some configuration files, which just need minor tweaks when running in different environments. So I can leave the files nearly as is, put some templating directives in it, and do not need to wrap it in a perl script.

    Using a templating system is not necessary for the separation of concerns (layout vs. logic). If you're fine with generating html by perl code, and you really don't need any HTML coders to create the html, then do it so! But do it in a different function or module than the code doing the logic. This is enough to separate logic and layout.

Re: The hidden charm of Template::Toolkit (and templates generally)
by CountZero (Bishop) on Jan 06, 2008 at 22:52 UTC
    If the web-page skeletons are written by perl-savvy developers, there is no benefit in using a templating system over perl-code. Actually, the perl-code you present could be considered some sort of a templating system in its own right.

    The beauty of an MVC-system is not that it uses a templating system but makes a clear separation of concerns between the Model, Controller and View parts of the application. How each of these components is practically implemented is of far less importance and a templating system is but one possibility.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      I think I disagree. You seem to be saying that the template (the View) is basically unnecessary if the Perl (the Controler) does all the lifting for it. It's true you can do it that way but as you can see, you are left with a MC instead of an MVC. Anything that manipulates (without changing) data purely for display should be in the View (unless it's complex to a degree as to make the template/View version toxic for readability/debugging compared to a more direct Perl/Controller version).

        Not at all, I said that the View does not have to be a templating system and may very well be pure perl-code. In an MVC it is the separation of concerns that is key, not the way each separate part of it is implemented.

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: The hidden charm of Template::Toolkit (and templates generally)
by exussum0 (Vicar) on Jan 07, 2008 at 03:02 UTC
    The best reason to use any template language, in any system, is in the readability and functionality a template language brings.

    Yes, your function is somewhat readable. Very much so. The problem is, it doesn't scale. For any HTML entity, any visual reference, it can affect another entity or reference. If I want to apply css, js and what not, I don't have a single document that contains everything in a single view. What's worse is, to find any particular piece, I have to go backwards and figure out what calls what. In a template, things are intended to be more flat - like a program w/ no user defined functions. Everything reads top down, loops get hit, variables get assigned an life goes on.

    The intended target is also valuable. I can hand a template to a designer and state, "This is the syntax, be it simple like Html Tmplate, or Mason, tweak it so it's a horizontal scrolling page instead of vertical." Less things to break. The separation is nice because it is a controlled separation. Sure you can get around it, but it's fairly obvious when it gets complex. The reverse is true too. I can take an HTML file, and replace a mockup of a few rows into a loop quite easily, pass it back and ensure life is good.

      The best reason to use any template language, in any system, is in the readability and functionality a template language brings.

      Readability: only if you have a high ratio of static/dynamic code; functionality: only if restricting is a benefit.

      The problem is, it doesn't scale. For any HTML entity, any visual reference, it can affect another entity or reference. If I want to apply css, js and what not, I don't have a single document that contains everything in a single view. What's worse is, to find any particular piece, I have to go backwards and figure out what calls what.

      What do you mean by 'scaling'? A template doesn't save you from "entities affecting each other". You have a single document only in the case of trivial pages with sparse dynamic content. If you have e.g. inclusions (of other templates), reading gets equally difficult, an you have to go back to look where each bit comes from.

      And if you have a different language, e.g. that of Template::Toolkit, you have to go back to the calling code to see what every token means.

      [% INCLUDE debugtxt msg="file: $error.info" %]
      Quick, was is info here? A hash key, a method, function, something else?

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
        What do you mean by 'scaling'? A template doesn't save you from "entities affecting each other". You have a single document only in the case of trivial pages with sparse dynamic content. If you have e.g. inclusions (of other templates), reading gets equally difficult, an you have to go back to look where each bit comes from.
        By scaling I mean, you start out w/ HTML (or text) and you add logic to it. Some pages will be horridly complex and things start to get messy, sure, as we go off to infinity. Point is, you start off w/ a document and start to add the logic. If there's very little, the template looks pretty much like what you started w/. Doing it as code, it starts out as something highly unreadable, and it takes diligence to make it not look like a mess.

        And yes, I can include to death, but I shouldn't be using goto, i mean spaghetti code, I mean includes except as a matter of large scale convenience.

        In the end, I could throw it all away and say it really doesn't matter. It's all turing complete and equivalent. You can create the same mess in any fashion. It's the starting point and the usability of the tech that a) promotes a certain type of usage and b) gives you a good starting point. For template languages it's, start off w/ large documents and then make them dynamic. It's not, take something dynamic and make it output HTML.

        Same holds true for other things. SQL is equivalent by using hashsets and mutex locks to mimic the behaviour, but hell, I'll make people cry doing that. I can probably do business logic in PL/SQL or TransactSQL, but that's not very nice either.

        As for tokens meaning something, I hope you are using variables in templates that mean something. I hope there's documentation, be it wireframe or graphical mockups. :)

Re: The hidden charm of Template::Toolkit (and templates generally)
by harsha.reddy (Acolyte) on Jan 07, 2008 at 06:23 UTC

    A tumbler is half empty or a tumbler is half filled is one and the same for me.. except that the perspectives differ..

    In the mason template code that you have mentioned:

    I still can see lot of Perl code in it, like:

    $book->title, my @authors = $book->authors;

    I look at <%perl>, <%... %> as special html tags...

    (Ah! Perl is so intelligent that it recognizes Perl code present in HTML as well.. taking things this way one will see this as feature rather than as a thing that will confuse..)

    I see that (from what you have said above) you aim is to learn "about Catalyst and MVC" and not to get lost in templating stuff..

    It is better go through this recursion rather than staying away.. that adds up to ones experience.

    All the very best.

    20080109 Janitored by Corion: Removed PRE tags, added formatting, code tags, as per Writeup Formatting Tips

      To quote the post preview page:

      If you think you're going to use <pre> tags — don't! Use <code> tags instead! This applies to data as well as code.

Re: The hidden charm of Template::Toolkit (and templates generally)
by naikonta (Curate) on Jan 07, 2008 at 07:16 UTC
    It is safer, since the template developer has no access to naked Perl. It also seems of no concern because the template developer is me or my office mate.
    IMHO, it's not because the template developers have access to "naked Perl". Rather, it's to protect them from having to code in complex programming language. The term "separating content (data) from display (view)" is really for roles in development instead of persons. I'm mostly a team on my own (except when I'm in a Real Team) so I need to think as programmer when coding Perl, think as designer when preparing the template, for instance.

    I know it's hard to switch repeatedly among Perl, SQL, CSS, JavaScript, and HTML (not to mention various types of config file), all alone at once. Sometimes I don't know which one drives another :-) But once you (if you happen to be a single fighter (yes, for now)) get the rythm, you'll have some fun. As a bonus, when you have a company or two, the only thing they need is to read the rules or specs or whatever it is to join the team as whatever role they'll play.

    To the question and examples at the end of your node, it's very clear. In your "pure" Perl implementation, "you" are thinking twice over two things in one session. In the templating solution "you" are thinking once for each thing in one or two sessions.


    Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

      Rather, it's to protect them from having to code in complex programming language.

      That argument is always brought up to defend template meta languages. But hey -

      • complex stuff shouldn't be in a template anyways
      • template developers themselves use a complex language
      • template developers aren't exposed to the hard bits of perl

      I wonder why "preventing them from being exposed to perl" should do them any good? or to perl, for that matter?

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: The hidden charm of Template::Toolkit (and templates generally)
by johnnywang (Priest) on Jan 07, 2008 at 09:45 UTC
    To add another perspective, the same question has been asked for other languages. And in many cases, the "original language" was chosen as the default template system.

    For example, PHP itself is already a template system, but other template systems like Smarty have been created. I always felt that's a little over-done, but it does allow better enforcement of the separation of presentation (most of these templates allow embedding of the original language anyway, but discouraged). Some recent frameworks in PHP have chosen to stay with PHP for its view component, at least by default, notebly CakePHP and CMS systems like Drupal and Joomla.

    Ruby made the same decision in Rails, where the default template is rhtml/erb, where ruby code is direclty put in html.

    Java has jsp where java is directly embedded, but then people have been arguing that servlet plus a template system like Velocity is philosophically better.

    Back to perl, TT does give me a much warmer-fuzzier feeling. I also like the fact that I can, and do, use it outside of the web environment.

      To clarify:

      One doesn't have to put java code INTO JSP to make it functional. You can make it act quite like velocity using tags alone.

      The compilation of JSP->java->bytecode is equivalent to a servlet that compiles a velocity template into memory, ala perl.

      Only diff between velocity and JSP is that your base language set is limited.

Re: The hidden charm of Template::Toolkit (and templates generally)
by danmcb (Monk) on Jan 07, 2008 at 09:59 UTC

    From personal experience, what I like with TT (in Catalyst) is that it gives a nice degree of abstraction. You can pass an object, hashref, array or whatever, and it just works out what to do with it. It is much more like a very loose script language that doesn't worry itself too much about data types and just keeps going trying to get the job done. Perl is also a bit like that, but less so. I find the change in feel to be about right.

    If you're talking about Catalyst though, you almost certainly can do it the way you propose, if you wish. Anything can be a View, I think.

Re: The hidden charm of Template::Toolkit (and templates generally)
by shmem (Canon) on Jan 07, 2008 at 10:08 UTC
    Separation of data generation and view code is good, as you already have stated, so no need to discuss that.

    Using a templating engine makes sense only if:

    • the non-perl/perl ratio is significantly higher than 0.5
    • the template can be rendered by its appropriate engine without template processing, and static / dynamic results don't differ significantly
    • the template can be edited with an appropriate editor for the given template language without placeholder or control constructs being dropped
    • you develop the views starting from static stuff which you "dynamise" later

    Another reason could be wanting to have a visual distinction between model/controller and view code.

    Using a non-perl templating language brings benefits only if you need to discipline yourself to use only a subset of what is possible in perl. As merlyn has put it -

    It's not so much a restriction as merely a place where it starts getting interestingly harder.

    I don't consider the edge-of-road markers that make a very loud noise in my car when I start to drift a "restriction" either. After all, I can ignore the noise, and keep driving off to the emergency shoulder, as I might need to do occasionally. However, it's a nice warning that I need to rethink what I'm doing.

    So, if you have to "fight your tool" you either have a design flaw, or the tool is inappropriate for the task.

    I don't buy the argument that

    $authors[$index]->{$book}->{title}

    is less readable than

    authors.index.book.title

    In the latter,no clue is given about what each token is; perl sigils actually increase readability.

    It is not too hard to explain the meaning of sigils in perl. It is not too hard to explain what brackets and curlies mean. The sigils give a clue of what each token is, and it is a feature of perl we all love. Why not propagate that appreciation to non-perl coders?

    Anyways, if "the html whackers" don't grok that, they shouldn't probably touch embedded code at all - be it perl or some other language.

    The argument of "language independency" doesn't hold. What other languages implement e.g. Template's placeholder language? or that of HTML::Template ?

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      It is not too hard to explain the meaning of sigils in perl. It is not too hard to explain what brackets and curlies mean. The sigils give a clue of what each token is, and it is a feature of perl we all love. Why not propagate that appreciation to non-perl coders?

      Anyways, if "the html whackers" don't grok that, they shouldn't probably touch embedded code at all - be it perl or some other language.

      I agree, "code monkeys" should never even touch HTML 'cause if they can't grok the finner points of HTML, they're probably breaking stuff. Yes, I know devs who are far more brilliant than us, but they don't know HTML, yet need a way to interact w/ others when the need calls for it.

      Language dependency does hold. I hope you aren't writing arithmetic formulas in English. Hell, any formula would make my eyes bleed. :)

      Update: Dear God shoot me for my inability to use English so early in the morn. Added a comma here, spelled dependency right there.... righting? oi!

Re: The hidden charm of Template::Toolkit (and templates generally)
by jbert (Priest) on Jan 07, 2008 at 12:58 UTC
    I quite like Text::Template, which to me combines the best of both worlds.

    It's a template approach (like TT) as opposed to your print function.

    But the templating language is perl. You don't need to print, the value returned from a perl block is interpolated into the template.

    To me, the main advantage of TT is "it's what everybody else does", which means you're more likely to find web designers who are happy with it.

Re: The hidden charm of Template::Toolkit (and templates generally)
by dragonchild (Archbishop) on Jan 07, 2008 at 15:13 UTC
    First and foremost, you need to do what makes the most sense for you and your project, taking into account the people currently working on it and the people likely to be hired to work on it in 2 years. If those needs are met by your function-to-html interface, then that's absolutely great.

    But, whenever I run into a question like this, I always turn to history. There is a reason why very smart people chose to make templating modules rather than function-to-X interfaces. And, I think it has to do with the X part in that last sentence.

    About 5 years ago, I took over maintainership of PDF::Template. I did so because the PDF generation tool $work was using didn't scale appropriately. Now, P::T was very cool to us because it takes the exact same data structure that HTML::Template takes. This meant that the code that actually figured out what to do didn't have to worry about how the result was going to be rendered. It just had to come up with the data in some massaged data structure and pass that onto the View.

    Skip forward about a year and I'm writing Excel::Template (and the aborted Graph::Template). All of a sudden, I'm able to render the same data structure into four rather different formats, all with a change of which module I'm instantiating. That's pretty darn powerful. And, it's something your function-to-X mechanism isn't going to support very well. That's why, I think, templating engines seem to be popular. They force you to create a proper interface boundary which, in turn, allows you to do really neat things for very cheap.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: The hidden charm of Template::Toolkit (and templates generally)
by sundialsvc4 (Abbot) on Jan 07, 2008 at 18:28 UTC

    Oooh! Did you just intend to open-up a can of religious worms?

    ;-)

    Well anyway, let me try to set a realistic scenario for you. Fast-forward the time-clock about five years.

    “Ooh, did you hear what happened to Roman and his office-mate?”
    “Yeah, wasn't that freaky? A tsunami roared-in to their cubicle and they were both just gone! The bread truck that was gonna smoosh them didn't even get into the building!”
    “So what's gonna happen to the Perl code they've been maintaining?”
    “I dunno.   They understood it, I guess, but nobody else could. The display logic and the decision logic were all so mashed together...”
    “Did they ever get started on the international translation issue?”
    “You kiddin'?   They were always finding excuses for that... we'll get started real soon now, they always said ... but they knew how many if-statements that would add to their code, so as far as I know they never 'got around to it.'”
    “Bummer... by the way, be sure to tell me your "dice.com" user-id so I can use you as a reference.   I'm not gonna get stuck maintaining that dog-pile!”
    “You got that right...”

    It really does make sense that display and business process are two entirely separate things, and that they should be “entirely separated” as much as possible. This is why Template systems have grown more and more advanced. They do that in order to give the page designer ... the visual designer ... freedom to change the arrangement of a page without affecting the code that produces or processes the data. Sometimes those changes need to be very substantial to properly handle the needs of an entirely different (human) language.

    I suggest that you “go with the flow,” because there really is a good reason for it. If you ever allow yourself to become “the only person who really understands how thus-and-so very important application actually works,” your chances for promotion just dropped to zero. And no matter how much you enjoy doing what you're doing now, right now, one day you're going to want to do something else.

Re: The hidden charm of Template::Toolkit (and templates generally)
by roman (Monk) on Jan 08, 2008 at 13:12 UTC

    Dear monks,

    thanks for your insightful comments.

    I will "go with the crowd" as sundialsvc4 in Re: The hidden charm of Template::Toolkit (and templates generally) suggested, with the (probably less populous) mason crowd.

    Although I think modules are equivalent to mason components, the mason componenents use different (lowercased) names and path tree which distinguish them better from Controller and Model components, than some MyApp::View::Books, ... view perl modules. Also Mason is already used in my company.

    I don't want to bother you with repeating myself, the following lines are meant mostly for my relief.

    Personally I consider templates being "false mistresses". They are seducing you with: "Don't code, let's go templating", but soon after start you will meet variables, loops, conditions, methods, ...

    The example below is taken from Catalyst tutorial, it is pretty simple and yet it contains a bit of programming, while the authors are not even linked.

    [% FOREACH book IN books -%] <tr> <td>[% book.title %]</td> <td>[% book.rating %]</td> <td> [% tt_authors = [ ]; tt_authors.push(author.last_name) FOREACH author = book.a +uthors %] [% # Now use a TT 'virtual method' to display the author cou +nt in parens -%] ([% tt_authors.size %]) [% # Use another TT vmethod to join & print the names & comm +a separators -%] [% tt_authors.join(', ') %] </td> </tr> [% END -%]

    In Mason, you start with plain HTML interspersed with occasional perl lines and end up with components, subcomponents, filtering, attributes, methods, ...

    However If the only risk of inappropriate tool for view implementation are difficulties caused by my cubicle being tsunamized (Re: The hidden charm of Template::Toolkit (and templates generally)) I stay calm. In Czech republic, I can take the risk. :-)

      In my experience, one killer reason for using Template::Toolkit is Jemplate (also on CPAN).

      With this, you can use exactly the same templates server-side as client-side, and this provides a convenient way of achieving dynamic effects without writing them twice.

      I like the option of building static copies of the site with ttree and tpage, which is useful for high traffic sites that just refresh content every N minutes instead of dealing with a Perl interpreter for each connection. Of course, you can do this with plain Perl, but I find Template::Toolkit just a bit easier.

      p.s. Your example seems a little overcomplicated, wouldn't this do the job instead?

      <td>[% book.authors.join(', ') %] ([% book.authors.size %])</td>

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://660685]
Approved by Corion
Front-paged by shmem
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (5)
As of 2014-12-28 14:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (181 votes), past polls