Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

mini-languages for MVC view/controller manipulation

by metaperl (Curate)
on Dec 26, 2004 at 17:38 UTC ( [id://417468]=perlmeditation: print w/replies, xml ) Need Help??

Something struck me 2 days ago, but I didn't want to present it until I was fairly sure it was worth talking about. It appears that the use of mini-languages to generate views is a new concept.

For example, people have been taking advantage of the MVC paradigm for more than 20 years. But during my schooling days we used Smalltalk and C primarily and whenever we did MVC, all 3 components were written in the same language. In fact, for the things we did (e.g., race car games, ray tracing, ATM machines), it would've been nearly impossible to embed display logic in a view template.

Which brings me to my point: the use of mini-languages within view templates seems to occupy a very small and recent slice in the history of MVC frameworks, motivated primarily by the need to dynamically generate HTML. They are immensely popular in Perl.

  • Could someone familiar with other languages (I'm especially curious about Ruby, PHP, Python) comment on how popular the mini-language approach to the view is in these languages? I think in Java that JSP is the most popular approach to mixing code with the view-template.
  • Does the use of mini-languages strike you as a natural and productive step in MVC view programming?

Perl-related resources

Template
This module allows one to embed a mini-language in one's view with optional escapes to pure Perl. It has a number of possible output formats and a number of plugins available for accessing the model in a convenient fashion.
HTML::Mason
Even though this module allows one to mix Perl and HTML, it can be considered a mini-language of Perl because once one uses Mason to do programming, the object-oriented inheritance model available is more limited and rigid than Perl. Also, passing arguments to a component does not use standard Perl syntax.
Petal
This is Perl implementation of a Zope/PHP mini-language known as TAL There has been talk of merging Petal with the Template Toolkit since they offer a similar approach via a similar language.
HTML::Seamstress
This module, written by me, offers a non-embedded approach to HTML templating. It is inspired by XMLC, a Java framework which compiles an HTML document to a Java class accessible via the DOM API. Instead of XML::DOM, my module is based on HTML::TreeBuilder and the new version with similar compiler is in development. With the new API, you can take HTML like this:
<html> <head> <title>Hello World</title> </head> <body> <h1>Hello World</h1> <p>Hello, my name is <span klass=content id="name">ah, Clem</span>. + <p>Today's date is <span klass=content id="date">Oct 6, 2001</span> +. </body> </html>
And after compiling hello_world.html into a Perl module named html::hello_world process it like this:
use html::hello_world; my $tree = html::hello_world->new; $tree->name('terrence brannon')->date('5/11/1969')->as_HTML;
HTML::Template by samtregar
A popular, robust, powerful mini-language templating system which also does just fine on normal text files. It has burners for the Bricolage content management system. It offers unmatched efficiency features such as JIT compilation.
XML::LibXML
another non-embedded approach to X/HTML templating. It was written by Matts and is part of the XML delivery toolkit, cpan://AxKit].
Text::Template
was the recommendation of Andy Wardley for those who felt restricted by mini-languages. While I have tried to present a balanced approach to this issue, I am sure that it is clear that I have a viewpoint on this issue, I will close with a quote from the Text::Template docs because it echoes my personal sentiments 110 percent:
When people make a template module like this one, they almost always start by inventing a special syntax for substitutions. For example, they build it so that a string like %%VAR%% is replaced with the value of $VAR. Then they realize the need extra formatting, so they put in some special syntax for formatting. Then they need a loop, so they invent a loop syntax. Pretty soon they have a new little template language. This approach has two problems: First, their little language is crippled. If you need to do something the author hasn't thought of, you lose. Second: Who wants to learn another language? You already know Perl, so why not use it?

The "compilation" of the HTML file

Just in case you're curious here is the package that was generated via the file hello_world.html
package html::hello_world; use strict; use warnings; use base qw(HTML::Seamstress); my $tree; my ($name,$date); sub new { $tree = __PACKAGE__->new_from_file('/home/terry/perl/hax/HTML-Seamstre +ss-2.6/t/\ html/hello_world.html'); # content_accessors $name = $tree->look_down(id => q/name/); $date = $tree->look_down(id => q/date/); # highlander_accessors ; $tree; } # content subs sub name { my $self = shift; my $content = shift; if (defined($content)) { $name->content_handler(name => $content); return $tree } else { return $name } } sub date { my $self = shift; my $content = shift; if (defined($content)) { $date->content_handler(date => $content); return $tree } else { return $date } }

Related nodes

2004-12-27 Janitored by Arunbear - added readmore tags, as per Monastery guidelines

Replies are listed 'Best First'.
Re: mini-languages for MVC view/controller manipulation
by revdiablo (Prior) on Dec 26, 2004 at 20:21 UTC
    the use of mini-languages within view templates seems to occupy a very small and recent slice in the history of MVC frameworks

    Whether I agree with this or not depends on what you consider the definition of a mini-language. If you mean simply an API, as in modules = minilanguages?, then this probably isn't right. I very recently started working on a simple module to generate wx forms for me, and I doubt this is anything new or innovative. But if you mean a mini language as I generally define it -- that is, a language with its own semantics and syntax, rather than just an API on another language -- then you might be right. Either way, interesting Meditation. ++

Re: mini-languages for MVC view/controller manipulation
by dws (Chancellor) on Dec 27, 2004 at 03:47 UTC

    Which brings me to my point: the use of mini-languages within view templates seems to occupy a very small and recent slice in the history of MVC frameworks, motivated primarily by the need to dynamically generate HTML.

    In the pre-web epoch, several "mini languages" for describing views (and how to hook them up to models) came and went. VisualWorks had one, which served as the basis for reusable visual components. If I recall correctly, NeXT had one, too (on the back end of their visual UI design tool).

      Also don't forget that a lot of people rolled their own. I worked with one or two home grown templating languages in the mid-to-late 90's.

      I should've been clearer: did said mini-languages exist *in* the view... or did they manipulate the view from outside of the view?

        did said mini-languages exist *in* the view... or did they manipulate the view from outside of the view?

        They described the view and participated in the view's construction.

Re: mini-languages for MVC view/controller manipulation
by hardburn (Abbot) on Dec 27, 2004 at 15:18 UTC

    HTML::Template . . . A popular, robust, powerful mini-language templating system which also does just fine on normal text files.

    IMHO, it's not suitable for normal text files because of the way it handles whitespace:

    $ perl -MHTML::Template -e '$in = join "", <>; $tmpl = HTML::Template- +>new( scalarref => \$in ); print $tmpl->output;' Hi <TMPL_IF foo> <TMPL_INCLUDE foo.txt> </TMPL_IF> Hello

    Which will output:

    Hi Hello

    The extra lines just aren't acceptable for plaintext. It's fine for HTML since whitespace is almost always ignored there.

    "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

      This doesn't seem like much of a problem; either leave the extra whitespace out of your source files, or mark the extra lines in some way and remove them before processing.

      Version one looks like this:

      Hi <TMPL_IF foo><TMPL_INCLUDE foo.txt> </TMPL_IF>Hello

      Version two looks like this:

      Hi \ <TMPL_IF foo>\ <TMPL_INCLUDE foo.txt> </TMPL_IF>\ \ Hello
      ... $in =~ s/\\\n[\t ]*//g; ...

      Doesn't this same issue apply to most templating packages, or am I missing something about why this is more of an issue for HTML::Template than the others?

        Doesn't this same issue apply to most templating packages . . . ?

        Probably. If there is anything special about H::T, it's that its default tag syntax is a bit lengthy. Compare to Text::BasicTemplate:

        Hi %if foo%include%fi% Hello

        (Note that Text::BasicTemplate doesn't have an equivilent to TMPL_INCLUDE by default, though it can call out to Perl subroutines.)

        That's a much more condensed example that, IMHO, works better for plaintext.

        "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

Re: mini-languages for MVC view/controller manipulation
by jdporter (Paladin) on Dec 27, 2004 at 14:55 UTC
    I, for one, think your HTML::Seamstress module is very cool and elegant. (So what if the idea originated elsewhere.) But, a couple comments on the html compilation bit:
    1. In the line  $name->hello_world(name => $content); where does that hello_world method come from? Seems to me that you really want to be saying  $name->replace_with($content); (And you should probably then call  $name->delete_content(); first.)

    2. In your look_down call, don't you also want to include criteria to look for klass=content? I think that would be prudent.
    metaperl++ (and all your other egos too, btw ;-)
      I, for one, think your HTML::Seamstress module is very cool and elegant
      Thank you very much jdporter.

      In the line  $name->hello_world(name => $content);where does that hello_world method come from? Seems to me that you really want to be saying $name->replace_with($content);(And you should probably then call  $name->delete_content(); first.)
      You are right. I updated the code to what it actually was in the test suite. Actually the content_handler method does what you are talking about.

      There is a very nice extension of HTML::TreeBuilder by Matthew Sisk called HTML-Element-Extended. In both of our efforts, we have written a dozen or so convenience methods for common Treebuilder idioms. So, I am developing something called HTML::Element::Library which will have all of our methods in one place.

      In your look_down call, don't you also want to include criteria to look for klass=content? I think that would be prudent.
      Well, here I rely on the fact that an HTML document must have unique id tags... but your suggestion certainly wouldn't hurt and it would be more precise...

      Thanks for the comments.

Re: mini-languages for MVC view/controller manipulation
by metaperl (Curate) on Dec 27, 2004 at 22:32 UTC
    Also, passing arguments to a component does not use standard Perl syntax
    What I mean by this is shown here. Summarily, even though something is typed as an array or hash:
    <%args> @elements %labels </%args>
    you end up calling it with references like this:
    <& /display, elements => \@some_data, labels => \%data_labels &>
    a normal Perl subroutine would use $elements and $labels to receive both.

    Whether the Mason syntax is more articulate is not the issue at hand. The issue at hand is that knowing Perl is not enough to receive arguments. You must learn a new calling convention. And when things like this happen, I develop paranoia about what else might be a hair different from what I invested great amounts time and money learning: pure Perl.

      Pshaw.

      Your "shown here" link doesn't seem to work, but the example you give above is not very convincing.

      You are perfectly free to use standard Perl argument passing conventions with your Mason components:

      <& my_component, $foo, $bar, $baz &> ...
      my ( $foo, $bar, $baz ) = @_; ...

      The <%args> block is an optional extra mechanism for retrieving arguments, which you don't need to use if it makes you paranoid.

      The @elements line in an <%args> block is equivalent to something like my %ARGS = @_; my @elements = @{ $ARGS{elements} || croak("Missing required argument: elements" }. That's a useful shortcut, particularly after you factor in the support for default values, but again, it's layered on top of the normal mechanism, not a replacement for it.

      I think that in constrained contexts, mini-languages and format strings can be quite useful; the succinctness allows the developer to work at a higher level. I find them particularly non-threatening in cases like HTML::Mason, where all of the mini-language code is translated to pure Perl before execution -- just look at your var/obj directory to see exactly what Perl code was produced for an %args block or other HTML::Mason markup.

      If you've made up your mind that you only want to use "pure" Perl syntax, feel free to use heredocs and interpolation tricks to generate your page templates, but I think most developers would agree that this is a case in which an additional layer with a different syntax is justified.

        If you've made up your mind that you only want to use "pure" Perl syntax,
        Yes, I have: meta-level (Perl) manipulation of object-level (HTML) is my credo.
        feel free to use heredocs and interpolation tricks to generate your page templates,
        May I use HTML::Seamstress as part of my heresy? ;-)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (2)
As of 2024-04-20 05:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found