What's That Noise?! [Ian Kallen's Weblog]

All | LAMP | Music | Java | Ruby | The Agilist | Musings | Commute | Ball
Main | Next month (Sep 2004) »

20040803 Tuesday August 03, 2004

Parameterizable Web Components What do Struts w/tiles and HTML::Mason have in common? One is part of a Java MVC framework, the other a Perl component system. But they both provide parameterizable components. People I've spoke to who have never used a component system that use named parameters in component calls often just don't get it. But it's really very simple. So lets see if we can shed some light on this.

Let's say you have a page called "query_results.html" that internally calls a table widget "query_results_table.html". And let's say the table widget takes a parameter for which column to sort the rendered table on and a title for the table caption. So the calling component might invoke the widget like this (assuming .html are handled as JSP):

<!-- could also spec a symbolic name in the tiles definition xml -->
<tiles:insert page="query_results_table.html">             
  <tiles:put name="title" value="Widget Query Results"/>   <!-- some literal text -->
  <tiles:put name="sort_order" beanName="sortOrder" />     <!-- a java.lang.String -->
</tiles:insert>

The called component (query_results_table.html) then has this

<tiles:importAttribute name="title" ignore="true"/>          <!-- an optional parameter -->
<tiles:importAttribute name="sort_order" />                  <!-- a mandatory parameter -->

HTML::Mason provides a similar facility.

<& query_results_table.html, title=>'Widget QueryResults',sort_order=>$so &>

or equivalently, call out to Perl-land

% $m->comp('query_results_table.html',title=>'Widget QueryResults',sort_order=>$so);

The called component would have something like this

<%args>
$title => 'Default Title'
$sort_order                     # mandatory parameter
</%args>

So what does it look like without parameterizable components? Well, for instance every PHP project I've seen is rife with stuffing things into globals and then using an include like

$title = 'fubar';
$sort_order = 'cereal';
include('query_results_table.html');        

The component has magical variables in scope and it hopes that the caller set them (yech).

<?
echo "$title";
?>

This is unacceptably lame speghetti-bait. There very well may be some better ways to do it in PHP, too bad they're not prevalent. All of the PHP code I've seen has semi-random groupings of functions stuffed into include files like that. If you're lucky, there might actually be class definitions in there. But the UI components can't take a distinct set of parameters; you're either hoping that the caller stuffed the right variables into the current scope or you're going to write a lot validation code.

I didn't want to get into naming conventions for components or any of the other real life deltas you'd want to see in production code; I just to want keep it illustrative. Hopefully this example isn't too simple and contrived that it fails to illuminate the importance. OK, maybe not... so why is this important? Relying on the presence (or absence) of variables set externally is a problem plagued, buggy development practice. A component's instrumentation should be unambiguous. The Java and Perl examples illustrate clear, explicit parameterization. Which params are mandatory and which are optional is obvious from the the way they are declared in the component. Using named parameters leads to cleaner, less buggy code that's easy to reuse and change. Rapid development and agility, that's what I want.

Now I know there are perfectly reasonable people who are happy with PHP in every respect and will take umbrage at my dis. Well, it's nothing personal folks. Rapid prototyping is cool but structuring a language so it's easier to make a mess than to keep it clean is not.

( Aug 03 2004, 12:53:29 AM PDT ) Permalink
Comments [1]