Continuing from the thread on the modperl mailing list:

On Sun, Jun 02, 2002 at 05:04:01PM -0400, Sam Tregar wrote:
> > I don't think the standard HTML::Template has support for formatting
> > numbers, dates, etc.
> 
> And thank the sweet lord it doesn't!  HTML::Template is a "do one thing
> and do it well" module.  If you want routines for formatting "numbers,
> dates, etc." then CPAN has just what you need.

I (mostly) consider formatting of numbers, etc., to be a presentation 
issue, not a programming one.  That's why TT supports this kind of 
thing in the templates (or in the code if you prefer).  

Of course, the fact that it's a module/object is entirely hidden.  TT 
abstracts the front end templates from the backend implementation, so
that the HTML designers don't have to know if a data structure is 
implemented as a hash, object, or subroutine, it just does the right 
thing.

This allows the developers to worry about implementing a back-end system
in the best way possible and the front-end designers to just use it.

> HTML::Template::Expr may present a solution to this particular desire,
> although it isn't one I've come across.  How often are HTML designers
> fiddling with numeric formats?  Are they really HTML designers if they can
> deal with, say, a printf-style format string?

In TT, you would usually pre-declare a particular format in a config
file, pre-processed templates, or some other "global" style document.
e.g.

  [% USE money = format('%.02f') %]

In your main page templates you would do something like this:

  [% money(order.total) %]

Then you can change the money format in one place and your designers
don't have to worry about sprintf formats.  

If you prefer to write your own formatting subroutine you can do it 
like so:

  my $vars = {
     money => sub { return sprintf("%.02f", shift) };
     order => {
         total => 22.95,
     }
  };

  $template->process($file, $vars) || die $template->error();

Guess what?  You don't have to change any of the templates.  They still 
use the same syntax:

  [% money(order.total) %]

This is abstraction.  Not to be confused with MVC which is one particular
architecture well suited to GUI applications.  Blindly applying MVC without
understanding the real issues (abstraction of front/back ends, separation of 
concerns, don't repeat yourself, etc.) is likely to build a system which is 
highly fragmented.  Maintenance becomes harder because everything is split 
up into many different pieces and it becomes difficult to see the wood for 
the trees.  

Aspect oriented programming teaches us that as soon as you decompose a 
system into a particular structure you inevitably fragments aspects which
cut across the system.  I have seen this in close and painful detail over the 
past few months while helping to build a very strictly partitioned MVC 
architecture system for Fotango(.com).  We're using TT for presentation, 
Openframe for the application pipeline/dispatch and a custom data backend 
called Vx.

Despite our best intentions, this web site doesn't neatly fall into 
clearly defined chunks of model, application and view.  Well, actually,
those parts do split down quite nicely.  But then you look at localisation,
for example, and we find there is localisation required in the data backend, 
localisation required in the applications and localisation required in the 
templates.  Thus, localisation is an aspect which cuts across the system.
By building a strict MVC we've fragmented localisation and have to trawl
through hundreds of different files to localise the site.  

Another example is that different countries running their localised versions
of this web site will want to change the URLs.  Where the english version
uses /product/shirt/red.html, the french version should instead be 
/produit/chemise/rouge.html, for example.  Again, these URLs are (currently)
embedded throughout the system and making any changes to them is a painful 
process involved many files spread across the M, the V and the C.  In an 
ideal world, English and French would just be different views of the same
model.  Alas, it's never that easy because the chances are that parts of
the model and parts of the controllers will also need changing.  

See, the problem is that MVC is just one particular decomposition.  It's 
generally a good one because application, data and presentation are typically
the three biggest aspects that you want to separate.  However, it doesn't
take into account any of the other dozen or so aspects that you might want
to model in your system.  Nowhere in MVC or any other Design Pattern does
it tell you to define all your URLs in one place in case you ever need to 
change them en masse.  You have to think of that all by yourself.  MVC is 
no substitute for thinking and it often encourages the opposite, lulling 
you into a false sense of security by the fact that you think you're doing 
the Right Thing.

I've seen far too many example of people who didn't pass objects into their
templates, didn't embed Perl code, or didn't do this or that because they 
thought that it might violate the MVC principal.  The end result was that
they jumped through hoops and made the system more complex than it needed 
to be for the sake of "purity".  Sometimes it really is a good idea to embed 
Perl code in templates.  Not often, no, but if the Perl code is performing a 
*presentation* function and not an *application* function, and as long as 
it's defined in one convenient place so that you can get your hands on it, 
then it can be the Right Thing to do.

Now I'm not suggesting that embedding Perl is a good idea, per se, but I'm 
saying that the smart people know when and how to break the rules.  
Separation of concerns is the goal, and MVC is one particular approach that
can help you to acheive that.  

To address the problem in the fotango site, I'm borrowing a technique
from AOP called aspect weaving.  I currently define 12, yes 12 separate
models (either as Perl code or XML files) each of which defines one aspect
of the site.  One defines the abstract site/section/page structure, another 
defines the URL -> page mapping, another defines page titles, short names, 
descriptions and anything other information about a page (e.g. not content)
that might need to be localised.  Another aspect defines pure style elements
(e.g. colours, fonts, CSS styles, etc), another defines flags and other
data for building the site interface, another defines database connection
and other backend data values.  And so on.

Each of these elements can be "subclassed" to change one particular 
aspect of the site.  A simple bit of code weaves the 12 different aspects
together into one coherent data model which is the definitive reference
model for everything in the site.  

This is all still in development as I type (or rather it's not in development
because I stopped to type this :-).  Assuming that it matures well and 
proves that it does what it says on the tin, I'll be releasing it as some 
kind of general tool for the modelling and building of web sites.  It will
be entirely generic so you will be able to use it equally well with TT as
with HTML::Template.

So to summarise a long, rambling post, MVC often isn't the answer by itself
and sometimes it's not the answer at all.  AOP might help, but only until we
reach the next problem horizon.

Five years ago I was saying "Object Oriented Programming isn't the answer
by itself and sometimes it's not the answer at all".  Any idiot can write
an object, but we all know that it takes a great deal more to design a 
coherent OO application.

In five years time, I'll probably be saying "Aspect Oriented Programming 
isn't the answer by itself..."  :-)

Or, more generally:

  [% silver.bullet %] isn't the answer by itself...


A

Reply via email to