Print Story Template Toolkit rocks my world
Diary
By coryking (Sun Jun 18, 2006 at 01:09:11 PM EST) template toolkit, blocks, boxes, templates, scoop, other system, your mom (all tags)
  1. The academy awards of CPAN modules.
  2. My arguements against homebrew templating systems.


I'd like to take this moment to thank my friends:

 - HTML::Prototype for making it damn easy to do cool shit like auto-completing forms.

 - Test::Class for giving me a really nice framework to run unit testing in.

 - Bricolage for giving me a good understanding of how to manage database fixtures inside a test case.

 - Catalyst for showing me how to do a web framework right.

 - Rose::DB::Object for an ORM package that works the way I do.

And the library I'd like to thank the most is: Template::Toolkit.
Template Toolkit provides an excellent template library with just enough richness to do cool shit.  It was the perfect choice to to replace scoop's block/box/var system with.  It has shown me just how wrong this comment is.

Simple scripting & conditionals do belong in the template system.  If you dont have them there, then you are putting display-code into places it doesn't belong.  The result?  You write giant functions that do mostly HTML generation (like to display the contents inside a list) that should be somewhere else.

I'm not just dissing on scoop's block/box system by the way.  I once worked on a system using a roll-your-own template system simialar to scoop's.  The result was Perl, SQL and HTML all mixed together into a huge ball of mud.  Adding new features took forever.  A simple shopping cart was 3000 lines of code.  Every feature was full of holes and impossible to test.

If you really looked at it, most of the code-bloat was doing a trivial pattern:

  1. Display the HTML header.  But do it just a little different if you are condition B instead of A
  2. Loop through all the objects I'm displaying, check a conditional or two, spit out HTML.
  3. Now display some kind of footer for this object.
  4. Repeat for every object in the document.
It takes a hell of a lot of logic to do something as simple as draw a cart!  In that system, the display logic was so intertangled into the code that all one could do was give up and copy&paste the logic used elseware in the system.  The codebase was rife with copy & paste jobs that would be virtually impossible to refactor.

Enter the template system with some control logic.    The example I gave is exactly the kind of problem template systems were designed to fix.  Rather then putting all the display logic in the code, you instead merely hand the template system an object, tell 'em which view to render, wash your hands, and walk away to do better things with your time.  They do all the heavy lifting of figuring how which cases to display and when.

In scoop's case, they could be used do all the "does this session have the permission to display X?".  In the other system, they could have handled all the various ways to display something "automatically".  300 lines of display code inside your modules turn into two or three.

"Ohhhh.... but they are all bloated.  TT, HTML::Template, et. al have done nothing but create a yet-another programming language," they say.  "Pretty soon we will have a perl interpreter ontop of perl interpreter and then what have we gained?"  This argument has some merit, some template languages appear to be nothing more than perl-on-perl. It is foolish, however, to use such an argument to dismiss the use of any kind of control logic inside a template.  A good template system provides just the right amount control and no more.

"Ohhh.... but they are slow and use a ton of memory! My homebrew super-wiz-bang template system uses assembler and uses only 6 bytes of memory."2  People who make this argument doing realize that something has to perform all the nasty crap required to spit out HTML.  Rather then into some simple templates, people with homebrew systems are forced to put it into their code instead.  While I can't prove it, I'd imagine the memory & cpu usage is way higher in such systems thanks to all the copy&pasting that starts to happen.  Dont forget the costs involved too.  Programmers cost WAY more then memory and CPU.  The nasty rats-nests concoted by those using ghetto-homebrew template systems take much, much more time to work on then those who have good, "stock" systems.  Basically, this arguement is nothing more then premature optimization at it's finest.

To sum it up, any time you roll your own template system, for whatever reason, god kills a kitten.  Just dont do it.

1 aka, you the template programmer.
2 http://scoop.kuro5hin.org/?op=comments&sid=2000/12/8/1364/10645&pid=3#4

Anyway... happy fathers day.  I gotta jet and I dont have time to fully proof-this.  Sorry.

< Oh yes: stuff | BBC White season: 'Rivers of Blood' >
Template Toolkit rocks my world | 8 comments (8 topical, 0 hidden) | Trackback
I would be major time f'd by cam (2.00 / 0) #1 Sun Jun 18, 2006 at 01:22:37 PM EST
if it wasnt for velocity.

cam
Freedom, liberty, equity and an Australian Republic

Velocity is good by Weapon of Pack Destruction (2.00 / 0) #2 Sun Jun 18, 2006 at 02:20:44 PM EST
Freemarker looks like a better idea.  With Velocity I'm screwed without VelocityTools.  JSP 2.0 with liberal use of the EL comes close.  Still too many pointy tags though.

[ Parent ]
You can jam stuff into the context by cam (2.00 / 0) #4 Sun Jun 18, 2006 at 03:34:33 PM EST
including some gateway object from your API. Why do you feel reliant on velocity tools?

cam
Freedom, liberty, equity and an Australian Republic

[ Parent ]
Here's why: by Weapon of Pack Destruction (2.00 / 0) #5 Sun Jun 18, 2006 at 04:49:03 PM EST
RenderTool

I used this to build <spring:bind> - like macros to autopopulate the id, name, value and for attributes of label/form element pairs.

Uniform access to the Form object in struts: FormTool

Simplified access to Commons Validator:
ValidatorTool

Actually when I was using Velocity with Struts, I used the whole VelocityStruts library.

And then there's the broken way Velocity accesses arrays, necessitating ArrayTool (deprecated by ListTool).  I understand that Freemarker handles that much more transparently.

Here you go: Velocity vs. Freemarker

[ Parent ]
While prototype totally rocks, by Weapon of Pack Destruction (2.00 / 0) #3 Sun Jun 18, 2006 at 02:27:09 PM EST
there is something just ugly about taking a javascript library that bitchslaps javascript into Ruby shape, and then grafting perl accessors on top of it.  It reminds me of a pigeonrat.  But then again, perl is an ugly, ugly language to start with, so that's probably where most of my aesthetic displeasure is coming from.

I tried using AjaxTags, which is a similar effort to JSPify Prototype, and found that it was easier to just write out the JSONs than to write the JSP wrappers.

Prototype by coryking (2.00 / 0) #6 Sun Jun 18, 2006 at 07:49:52 PM EST
I'm almost with you on the prototype thing.  It looks like all the thing is doing is acting as a code generator for the script.aculo.us library.

I suspect that once I get more comfortable with the underlying javascript API, I'll stop using the prototype library and just write to the API instead.  Hence, I belive, it's name "prototype" :-)

As for perl, people write ugly code, not languages.  Sadly the perl community is rife with poor programmers.  Once you "get" perl and if you care about writing readable code, perl is a thing of beauty.  I love it!


-------------
Dog food. Snack for some. Feast for others.

[ Parent ]
Getting terms straight by Weapon of Pack Destruction (2.00 / 0) #7 Sun Jun 18, 2006 at 08:13:52 PM EST
I think you're saying that you'll dump the perl prototype library and just use script.aculo.us instead, in which case I'd agree.

The name "prototype" refers to two things.  First, Sam Stephenson's "prototype" javascript library, which script.aculo.us and moo.fx are built on.  Second, a language feature of javascript, whereby you can dynamically add objects and methods to a class, and have those objects and methods then accessible by any instance of that class.  Sam uses this to extend javascript built-in classes and provide a very Ruby-like interface.

Go look here or just google "prototype"  It's worth it just for the $ function, but the $$ function rocks my world.

$$(div#main form input.required) returns an array of all input elements of class "required" that are members of a form that is inside a div with the id of "main"

For information about prototyping languages, here you go

[ Parent ]
Oh wow by coryking (2.00 / 0) #8 Mon Jun 19, 2006 at 07:10:07 AM EST
you learn something every day!  Thanks for the link!

I dont know who does what in the AJAX world I guess. 


-------------
Dog food. Snack for some. Feast for others.

[ Parent ]
Template Toolkit rocks my world | 8 comments (8 topical, 0 hidden) | Trackback