Thomas Klausner wrote:
Ovid on Perlmonks already said some of the things I would have said about needing a presentation language. For a templating system to be useful, it has to be able to deal with loops and conditionals. Your system pushes those into the Perl code, splitting the presentation control into multiple places. This fails one of my major goals: the template coders should be able to change the presentation without help from a Perl coder. What if they decide they don't want to loop through the links, but rather just print a message saying there are some? What if they only want to show the first two? What if they want to display a list with commas between the elements where they didn't use a separator before? A mature templating system can handle all of these issues without changing the main Perl module code.Yes, this is a RFC for Yet Another Templating System. I know that there are a lot of those around. But this own might be different/interesting (at least I think/hope so...)I also posted this on perlmonks: http://www.perlmonks.org/index.pl?node_id=213300
It sounds to me like you want one of the HTML attribute ones, like Petal or HTML::Seamstress. What was wrong with those?Because IMO, the main reason for using templates is to seperate code from markup.
It's not complicated, but it is somewhat confusing the first time you look at it. I don't find your approach much easier though.There is one module, CGI::FastTemplate, that does seperate code from markup completly. But the way different templates are strung together seems rather comlicated to me.
# generate a new template handlerIsn't your fill method just doing a sort of multi-level join here? All of the data is passed in already, so there is no reason to delay evaluation of the templates.
my $th=Template::YetAnother->new
({
namespace=>'acme',
template_dir=>'/projects/acme/templates/',
});
# build up a data structure
$data={
title=>$th->title('this is the title'),
breadcrumb=>[
$th->link({url=>'/index.html',text=>'Home'}),
$th->separator_breadcrumb,
$th->link({url=>'/acme/index.html',text=>'Acme'}),
$th->separator_breadcrumb,
$th->link({url=>'/acme/bleach.html',text=>'Bleach'}),
],
content=>[
$th->element({heading=>'SYNOPSIS',value=>'blabla'}),
$th->element({heading=>'DESCRIPTION',value=>'foo bar'}),
],
lastmod=>scalar localtime,
};
# fill template & print
print $th->fill({data=>$data});
More importantly, your use of AUTOLOAD to treat method calls as file names looks neat, but is not a good approach. It's limiting (all templates in one directory!) and has potential security issues with namespace clashes. These are all just the same method call with a single argument changed, so why not write them that way?
Here's the same thing written with Template Toolkit. You could use HTML::Template, CGI::FastTemplate, Text::Template, etc. here with minor changes:
my $th = Template->new({INCLUDE_PATH => '/projects/acme/templates/');
$th->process->('title.tmpl', {title => 'this is the title'});
$th->process->('link.tmpl', {url => '/index.html', text => 'Home'});
$th->process->('separator.tmpl');
$th->process->('link.tmpl', {url => '/index.html', text => 'Home'});
$th->process->('separator.tmpl');
$th->process->('link.tmpl', {url => '/acme/index.html', text => 'Acme'});
$th->process->('separator.tmpl');
... And so on.
Text::Template allows Perl code to be put in the template, and HTML::Template/TT allow loops and conditionals, but no one is going to force you to use them. They are flexible modules. I think you should look at them more closely before you go off on your own.
- Perrin