in reply to Re: RFC - Template::Empty
in thread RFC - Template::Empty

I covered a few people's attempts at this in my Choosing a Template System essay.
Well..... every system you cover falls into the models you describe in your overview - pipeline or callback. Seamstress and XMLC do not fit into either of those categories. Both pipeline and callback are pull-style. XMLC and Seamstress are push-style.
My favorite example of this type is the now defunct HTML_Tree. It never really caught on.
There is a book called "The Outsider" by Colin Wilson which explains things like this. Some things are not supposed to catch on... take a look at the bell curve and it would be clear why... Einstein did not catch on.. Dvorak did not catch on...
There have been other tries in Java, like XMLC. They also failed to gather a large following.
XMLC is a pretty solid project. Sure, it's a minority product, but it is the presentation layer of the Enhydra Application Server. . It is also used in the Barracuda MVC framework. And finally Sams published a book on it.

I would agree that it does not have a _large_ following. But it definitely is a proven industrial strength technology, with active development and user base over 6 years. Not only that, but they use DOM to do it... Java people seem to handle verbosity much better than us Perlers.

Most people stayed with things like JSP and Velocity.
I would agree with you. But staying with something doesnt mean it's better. It could be for legacy reasons, familiarity reasons, etc.

I think the reality is that DOM-based HTML manipulation gets cumbersome for complex templates.
well DOM _is_ cumbersome.. HTML::Tree is a very Perlish DOM. a very slick product indeed. All hail Sean Burke for a job more than well-done. And Python has some very slick XML mungers, 4suite for instance is incredibly elegant for munging XML.
It also ties your code very tightly to the presentation.
Now perrin what do you mean by that? If the code is supposed to present something, then of course it is tied to it. :) But again, you are using "your code" in the same vague sense that Rhandom used "code layer" -- both of you speak about it, but provide no examples, either in your replies or link to any document on the web, peer-reviewed or not.

Do me a favor and demonstrate the flaws. All through this thread, I am providing CODE to back up the seamstress approach. I need you two to meet me on that practical level, not verbal theoretical level.

So, if you want to pursue this, I'd suggest moving away from the DOM-like approach in your example and going to something more like HTML_Tree, HTML::Seamstress, and XMLC.
HTML_Tree is not like Seamstress or XMLC. HTML_Tree is like Petal.

Petal and Seamstress share one benefit - you are 100% guaranteed HTML which can be viewed with HTML tools with no choking on mini-language constructs. But the approach to use Petal and HTML_Tree (and Data::DRef from back in the day:) is vastly different from XMLC and Seamstress.

HTML_Tree is pull-style. The other notable push-style thing I've run across besides stringtemplate is meld3 by Chris mcDonough in Python. It is a very nice tool to work with. Too bad it is based on elementtree which is one of the weaker HTML/XML engines for Python.

I have beheld the tarball of 22.1 on ftp.gnu.org with my own eyes. How can you say that there is no God in the Church of Emacs? -- David Kastrup
[tag://html,templating,push-style]
Enforce strict model-view separation in template engines via HTML::Seamstress The car is in the cdr, not the cdr in the car

Replies are listed 'Best First'.
Re: HTML::Seamstress - the Outsider
by perrin (Chancellor) on Feb 25, 2008 at 20:14 UTC
    Both pipeline and callback are pull-style. XMLC and Seamstress are push-style.

    "Pipeline" in my essay means that the code is in charge of control flow rather than the template. In a callback style, decisions about what do next are in the template. Seamstress is pipeline.

    The issue I referred to with code being tied to presentation in a DOM approach is that you have to know the structure of the DOM. For example, filling in a variable in a specific paragraph or table requires you to say exactly which paragraph or table cell to fill. You have to write code like this:

    $node->children()->[0]->text( $flavor_name );

    If you use ID or CLASS attributes on the HTML tags instead, you can move them around without changing your DOM calls. I don't think we disagree, since your examples all use ID or CLASS attributes, not DOM location. You probably just have a different name for what I call DOM manipulation, like maybe XPATH.

    HTML_Tree is not like Seamstress or XMLC. HTML_Tree is like Petal.

    I don't see how. Petal embeds a programming language in XML files. HTML_Tree and Seamstress and XMLC all use ID and CLASS attributes to specify parts of an HTML file to replace or modify without embedding loops or conditionals in the template itself. (HTML_Tree can use XPATH-like code if you choose to, and I suspect the others can too, but that would be a bad idea for most situations.)

      Pipeline" in my essay means that the code is in charge of control flow rather than the template. In a callback style, decisions about what do next are in the template. Seamstress is pipeline.
      Seamstress is push-style. Every other system on CPAN, whether callback or pipeline, is pull-style... oops! Template::Recall is push-style also. I have had little success in trying to email the author to chat
      Petal embeds a programming language in XML files.
      haha! told you fergal (grin).
      HTML_Tree and Seamstress and XMLC all use ID and CLASS attributes to specify parts of an HTML file to replace or modify without embedding loops or conditionals in the template itself.
      I see where you are coming from
      • they all only use Perl and HTML (no mini-language).
      • There is no embedding in the template.

      I have some comments on your article, having read it closely:

      HTML::Template is fairly rigid about insisting on a pipeline approach. It doesn't provide methods for calling back into Perl code during the HTML formatting stage; you have to do the work before running the template. The author of the module consider this a feature since it prevents developers from cheating on the separation of application code and presentation.
      You might mention that HTML::Template::Expr adds callback support for HTML::Template.
      There is a third approach, based on parsing an HTML document into a DOM tree and then manipulating the contents of the nodes. The only module using this approach is HTML_Tree.
      That is not true. Seamstress does that. In fact Seamstress is on CPAN and maintained. HTML_Tree cant claim either of these things.
      (said about HTML_Tree) This allows it to use genuine valid HTML documents as templates, something which none of these other modules can do.
      You mention Petal in your survey. It (and Seamstress) certainly guarantees this. HTML::Template and tt have support for changing the template delimeter to an HTML comment, which might help.
      I have beheld the tarball of 22.1 on ftp.gnu.org with my own eyes. How can you say that there is no God in the Church of Emacs? -- David Kastrup
      [tag://push-style,html,templating]
      Enforce strict model-view separation in template engines via HTML::Seamstress The car is in the cdr, not the cdr in the car
Re: HTML::Seamstress - the Outsider
by Rhandom (Curate) on Feb 25, 2008 at 19:38 UTC
    But again, you are using "your code" in the same vague sense that Rhandom used "code layer" -- both of you speak about it, but provide no examples, either in your replies or link to any document on the web, peer-reviewed or not.


    I've given an example in an above reply. To be specific. The code layer is the perl layer. It is written in perl and is either modules or cgi script. The presentation layer is either a template file or a template string (yes template strings are useful too - so you can put your template in a database for instance). The code layer picks which template to display and gathers data that the presentation layer may need. But then it is up to the presentation layer to lay it out.

    All of the in house HTML designers I have worked with at any of my jobs have wanted to have the flexibility to manipulate the data so that they page shape could change. I've enjoyed not having to change my perl whenever they've needed to reformat the page.

    Just out of curiosity - what do you use when you need to send a templatized css file, or js file, or text email. To me, the XML/HTML DOM template systems seem to be heavy handed at forcing you to have well formed HTML. HTML is just a subset of what you need to deal with in web development. Do you use multiple template systems - or worse do you try to force css/js/email into the same slot as HTML? I've seen people do this and the templates are usually quite ugly. XML is usually the wrong hammer.

    my @a=qw(random brilliant braindead); print $a[rand(@a)];
      I've given an example in an above reply. To be specific. The code layer is the perl layer. It is written in perl and is either modules or cgi script. The presentation layer is either a template file or a template string (yes template strings are useful too - so you can put your template in a database for instance). The code layer picks which template to display and gathers data that the presentation layer may need. But then it is up to the presentation layer to lay it out.
      What you call a "code layer" sound like a dispatch mechanism... analogous to the controller if we were doing a webapp... but remember dynamic html generation doesnt need cgi/mod_perl at all. So yes, that would be in Perl. And the presentation layer for me, is also 100% pure Perl. And the "template" is a lifeless HTML file, preferably containing some div, class and id tags but nothing more.

      Do you see anything suspect with the code I posted?

      I have beheld the tarball of 22.1 on ftp.gnu.org with my own eyes. How can you say that there is no God in the Church of Emacs? -- David Kastrup
      [tag://html-seamstress]
      Enforce strict model-view separation in template engines via HTML::Seamstress The car is in the cdr, not the cdr in the car
        Do you see anything suspect with the code I posted?
        Absolutely not! Your code is great. Your separation of model/view/controller is textbook quality. Academically, it is sound.

        It just doesn't look like fun. But that is me. It might be to you. I just like that if I can make the "lifeless HTML file" just a little less lifeless, it can greatly simplify my coding load. I can generate data, pass it along and let it be consumed in optimum fashion. But that is "optimal" to me. EMWV (everyone's mileage will vary).

        my @a=qw(random brilliant braindead); print $a[rand(@a)];
      Just out of curiosity - what do you use when you need to send a templatized css file, or js file, or text email.
      Well, that's a good question. I've never had to do those things. Part of your extra extra credit was to create a text version. And here it is:
      package View::bullet::text; use base qw(View::bullet); use Data::Dumper; use HTML::FormatText; my $file = 'html/bullet.html'; sub new { __PACKAGE__->new_from_file($file); } sub render { my $tree = shift; my $model = shift; my $tree = $tree->SUPER::render($model); my $formatter = HTML::FormatText->new(leftmargin => 0, rightmargin = +> 80); my $text = $formatter->format($tree); return $text; } 1;
      I have beheld the tarball of 22.1 on ftp.gnu.org with my own eyes. How can you say that there is no God in the Church of Emacs? -- David Kastrup
      [tag://html,templating,seamstress,oop]
      Enforce strict model-view separation in template engines via HTML::Seamstress The car is in the cdr, not the cdr in the car