What everyone knows
For those, who himself even had never dealt with Perl the very words HTML::Mason are hardly unfamiliar; and CPAN might be a source for either admiration or envy. Among the tremendous number of library modules, HTML::Mason could survive a row of releases of his own and got qualified as entirely professional web-development environment. Though one can narrate a lot on what exactly it is, but if in the course of conversation they utter ‘HTML::Mason’ occasionally, the sharp rejoinders like “well, it’s a mod_perl’s only” aren’t rare. It’s well-known that the module was designed and developed with this Apache web-server extension in mind, however, far not all modules presented at CPAN can (at least in their pods) make a brilliant display of flexible features. In here we’re going to talk how to ‘cut the coat according to the cloth’, that is how to use available things at hand and produce good enough and practical applications.
Perhaps, there are not so many brave heads can claim they used HTML::Mason in full and without mod_perl+Apache out there; much as well as this, and what the reader might know, is possible with the module. But in our case we’re going to solve a bit different problem and that is how to put in use all HTML::Mason power when one has got an ordinary web-hosting, offering the old good CGI.pm.
What Mr. Rolsky is silent about
Despite HTML::Mason possesses an excellent set of docs and examples for virtually any option possible, the real life shows that by intent or not (and there are numerous graphic evidences of that on the Internet) it lacks for CGI use a lot. No secret that anybody, who ever tried to dive into the problem made their first stop at HTML::Mason, HTML::Mason::Admin, HTML::Mason::CGIHandler and the rest. Well, more often than not they skipped to something else or ... whatever, as those guys once faced this wall obviously never ever got back again. And pitiful are they! The lines authors do not reproach HTML::Mason’s developers with this notice, but still it could be better to shed more light in this respect for the uninitiated.
Thus, what does the standard documents of HTML::Mason offer, when there is no way to use mod_perl? First, all the options are cut to two as a matter of fact.
The option using HTML::Mason within a stand-alone (and baked) cgi-script from the very beginning, if even to omit the scape and scope and scalability and usability, will bring to naught all the mighty of Mason in its components interoperability and interchangeability, and, say, for system administrators templates are excessive as the standard Perl’s features are more than enough. To be short, this variant makes a developer to say good-bye to any template system and the most unfortunate is to the Mason’s ability ‘to bind’ components dynamically.
The next option is pointing to incomplete emulation mode, where HTML::Mason is working in CGI environment via HTML::Mason::CGIHandler. As the Mason developers say it’s a poor man’s option that can re-produce just a few features of what Mason can in mod_perl mode. And that is true. The question ‘does anyone need this?’ is out of place here; on the other hand, is it good to start anything what is of no interest to finish is open yet.
How much and what for
The invention history is redundant in examples born right in between two or more technologies or techniques or just notions. Fortunately, HTML::Mason is not an exception. Those, who knows something on the Internet history, the history of CGI might be a good example. The protocol could meet almost all existing earlier needs for client-server communication. But the time passes by and the people are acquiring more sophisticated toys.
The old story on how hard for a web-designer to understand problems of a web-developer seems getting shabby since the world saw various CMS and the like. Nevertheless, as usual in the first place (but may be not so usual) the choice of platform arises. If one tries to compile the list of hosting providers offering mod_perl feature, he might be disappointed to learn how much that costs and how few are those who can offer the feature indeed. They state many reasons to excuse the price and the main of their own is support; which we cannot accept though. That is why we are turning back to what is offered here and there, to CGI.pm plus a set of standard features and for free, almost. In case they don’t have HTML::Mason installed they can do that easily, that’s not a problem, all the problems are just one step ahead, namely, when a happy developer with his home-grown project will try to deploy it at the hosting.
For the languished readers it is worthy to say that the starting point is the creation of cgi-handler, that is the script which is channeling all ins and outs, coming form CGI environment and going back, to HTML::Mason for processing. Till now everything is more or less clear; this is the turn of auto- and dhandler. Technically, these are common in shape and contents, but due to the difference between %ENV of CGI and %ARGS of Mason (and these two are really different, not only in names, but also in what they can be containers for) it is strongly recommended to inform HTML::Mason where to obtain the environment variables.
The theory smelling
In theory, or to be more precise in the documentation, they say that autohandler is triggered and executed right before everything else and this is true always; on the other hand, dhandler does … well, everyone knows how it works. But this makes a big difference when transferred into CGI environment. Dlhandler under such conditions, if one follows the Mason docs, is not working as needed; well, autohandler is still there! What’s wrong?
The question is how to turn on dhandler forcibly, that is how to make it CGI-aware. The example we placed below might be far from perfect, however, if the service has no heavy load of simultaneous and/or concurrent requests it performs well. Here is the recipe:
#!/usr/bin/perl
# File: mason_handler.cgi ( cgi handler to process, auto-, dhandler )
use HTML::Mason::CGIHandler;
use lib '/path/to/lib '; # absolute path to your lib
use YourModule1;
use YourModule2;
use utf8;
# we DO call dhandler explicitly
$ENV{PATH_INFO} = '/path/to/DocumentRoot/dhandler';
my $h = HTML::Mason::CGIHandler->new(
data_dir => '/path/to/mason data dir',
comp_root => '/path/to/component/root',
allow_globals => [qw($globalscalar)],
);
$h->handle_request;
What else should be said about HTML::Mason
This section is a sort of obligation, or, may be, just a compulsory piece of a development inventory, especially needed for those dealing with non-English web-resources and aware about consequences of ‘use utf8’ usage within HTML::Mason.
All-known UTF-8 is getting more and more common on the Web. The standard Perl documentation says about built-in classes like “\p{InBasinLatin}”, “\p{InCyrillic}” and so on; those when used together, for example, with ‘qr()’ may, and really are, the powerful tools. Also let’s bring forward the old ‘quotemeta()’ that also may be of a good help yet; nonetheless, when it comes to use the like from inside HTML::Mason, not everything goes smoothly. Suppose, you’ve got a mysql table, which is queried exclusively with ‘SET NAMES utf8’ (so that mixed data make no noise) and which itself has ‘CHARSET=utf8 COLLATE=utf8_unicode_ci’ collation tags placed properly; next, somewhere in the UI form you must sift the user’s input with fascinating ‘s///go’ (needless to say all your pages are containing the valid XHTML with meta-tag ‘charset=utf-8’ or generated with HTML::Mason ‘headers_out()’), but the problem is still there as your regexp isn’t working properly! Again, as it is said in perldoc – ‘use utf8’ to rescue and place it right into the component… now, regular expression is alright, but the generated page content is odd a bit. Finally, you found Encode.pm with its “decode(), encode()” and feverishly started to “normalize” the utf8 input… it’s the same and not entirely what’s expected.
Sure, your own story may be a bit different, but the conventional morality is following:
all the data, corresponding UTF8, in the internal Perl representation almost always looks differently (and for Perl as well); the use of data presented in the way, well, they are looking correct in the browser, as well, to be fed to regular expressions; the latter, if they are well-formed, will process the data happily and supply the correct (read – expected) result. As to the rest of your precious resource, none of the beasts should be let out, otherwise, you’re in troubles: the explicit turning on UTF8 by any means and in any of the Mason processed components will result to the correct data display from this one and incorrect within the others.
The problem got the shape, but what’s the solution? It’s time to get back to the sources: they strongly advise to follow ‘divide-and-conquer strategy’; for the case it sounds like: all the routines requiring to process Unicode (utf8) data with Perl should reside in modules only, and none of those must be put inside a component; the same is true about the tools like Encode::encoded/decoded(“utf8”, $datum). This is one of the few limitations one should keep in mind while designing his/her HTML::Mason applications.
All the said above was ‘inside’, now we’re going to make a set of notes what’s ‘outside’. HTML::Mason, as the dear reader probably knows already, has some *escape* hooks; it is out of place to repeat the pods and instead we just recall few things like ‘|h’.
In fact if one has, say, an English site, then no worries; in case of otherwise, and if the developer has to use UTF8, the following bit of code may help to escape the user’s data properly. It happens, for instance, when there’s a UI html form; suppose a user has input the data mixed with markup, to avoid his own data to be treated as markup afterwards we do recommend to append to your code something like:
File name: autohandler …… % $m->interp->set_escape( h => \&HTML::Mason::Escapes::basic_html_escape ); % $m->call_next(); …… file:…… <% $htmlstring | h %> ……
The whole thing sample
Finally, we’d like to illustrate what’s said with a plain example.
The example we’re creating a small site, containing the following:
- perl module with DB interface;
- autohandler and dhandler;
- a set of components to construct the simple UI;
You can download the example here (~ 10 Kb).

0 коммент.:
Отправить комментарий