CHP-1>
At its heart, Mason;overview> Mason is simply a mechanism for embedding Perl code into plain text. It is only one of many such mechanisms that all do more or less the same thing. However, Mason represents a particular set of choices about how this embedding should be done, and many people have found that the way Mason does things is very straightforward and extremely conducive to getting jobs done.
In this chapter we'll introduce you to some of Mason's key features and strengths, show you a couple of examples of how to use Mason> Mason, and talk about some alternatives to Mason. After reading this chapter, you should have a fairly good idea of how Mason relates to its peers and what kinds of tasks you can accomplish with Mason.
The most common application of Mason is in building large dynamic web sites, and this book focuses mostly on web site building. Mason is broadly applicable to any situation in which fine control over document content is required, however, such as generating mail-merged form letters, creating custom configuration file sets, and even building dynamic GIF images> GIF images based on varying input parameters. We intend to give you enough facility with Mason that after reading this book, you can imagine Mason-based solutions to problems we haven't ever thought of.
Before we get into the details of Mason and comparisons with its alternatives, we'll just briefly mention some of its guiding design principles. Mason was designed to help you build, organize, and maintain large web sites or other groups of dynamically generated documents. It cooperates fully with Perl, leveraging all the solutions and techniques that Perl developers have come to depend on and that have made Perl such a powerful and widespread tool. It encourages thinking about your site in structural terms rather than as a collection of procedural scripts or modules> modules. All of these things are conducive to getting your job done effectively, letting you concentrate on your goals while Mason takes care of the details.
CHP-1-SECT-1>
To help make this discussion a little more concrete (this thing is called Mason, after all), let's look at an example. We'll give more in-depth treatment to the details of Mason's syntax later in the book; these examples are just to put some Mason code in front of your eyes and show you what it looks like.
The following code is a complete chunk of Mason;sample codes> Mason code, called a components> component:
% my $planet = "World"; Hello, <% $planet %>!
When Mason runs this code, the output is:
Hello, World!
We'll talk more about the details of component
syntax in A<CHP-2>Chapter 2, but two basic elements in the
preceding example deserve mention here. The first is that any line
that begins with a %
% (percent
sign)>
percent sign
(%)>
character tells Mason that the line
contains Perl code. The
Perl
code>
Perl code can be any syntactically correct
Perl -- Mason doesn't care what it is or what it
does. In this case, it simply sets the value of a variable that will
be used later in the component.
The other element in the previous Mason component is
the
substitution tag (<%
%>)>
<% %>
(substitution tag)>
substitution tag, denoted by
the sequence <% %>
. Mason will evaluate the
contents of any such tag and insert the result into the surrounding
text. In this case, the variable $planet
evaluates
to World
, and the output of the entire component
is Hello, World!
Note that any text that isn't a special Mason
construct simply becomes part of the output of the component.
These two lines are relatively simple and not particularly exciting, but they should give you a taste for how Mason code looks in its simplest form.
CHP-1-SECT-2>
There are more templating systems written in Perl than you could possibly keep in your head all at once. To help you make sense of Mason;main features of> Mason's place in the world, this section presents Mason's most important and distinctive features. By the end of this section, you should see that Mason pushes the boundaries of the term ``templating system> templating system,'' with lots of features aimed at helping you manage the larger tasks of site design and maintenance.
CHP-1-SECT-2.1>
As we mentioned before, the basic unit of Mason code is called a component. It is a chunk of Mason code that can accept input parameters and generate output text. An important feature of Mason is that any component may call any other component at any point during its execution, much like a Perl subroutine calling another Perl subroutines> subroutine. Because of this feature, a component may represent a single web page, a part of a web page (like a side navigation bar), or even a shared utility function that generates no output of its own. This separation of design elements allows you to use Mason as a sort of glorified server-side include (SSI) mechanism> server-side include (SSI) mechanism, as in A<CHP-1-EX-1>Example 1-1, A<CHP-1-EX-2>Example 1-2, and A<CHP-1-EX-3>Example 1-3. Executing mainpage.mas will produce a full page of HTML with the header and footer inserted in place.
CHP-1-EX-1>
<html> <head><title>Welcome to Wally World!</title></head> <body bgcolor="#CCFFCC">
CHP-1-EX-2>
<center><a href="/">Home</a></center> </body></html>
A<CHP-1-EX-3>Example 1-3 introduces the component call
tag (<& &>)> <& &> (call tag)> call tag
syntax, <& &>
, which is used to call another component and
insert its output into the surrounding text. The component tag can
also accept arguments, which in this case can help unify site design
by moving the page header text into the
header.mas component> header.mas component.
listing mainpage.mas
CHP-1-EX-3>
<& header.mas &> <center><h1>Wally World Home</h1></center> Here at Wally World you'll find all the finest accoutrements. <& footer.mas &>
The header.mas component in A<CHP-1-EX-4>Example 1-4 now accepts an argument called
$head
that contains the text that should get
inserted into the
<h1>
tags:h1 tags>
<h1>
tags. A component's arguments are declared by using
an <%args>
block, which you'll see in more detail later in
the book. The $head
argument becomes an honest-to-goodness Perl
variable that can be used throughout the rest of the component. It's
lexically scoped in the header.mas component using Perl's
my()
my( ) function (Perl)>
function.
listing header.mas
CHP-1-EX-4>
<%args> $head </%args> <html> <head><title>Welcome to Wally World!</title></head> <body bgcolor="#CCFFCC"> <center><h1><% $head %></h1></center>
The footer.mas component in A<CHP-1-EX-5>Example 1-5 is fairly straightforward. It just provides a link to the document root.
listing footer.mas
CHP-1-EX-5>
<center><a href="/">Home</a></center> </body></html>
In the mainpage.mas mainpage.mas component> component
in A<CHP-1-EX-6>Example 1-6, the arguments are passed to the
header.mas component by using standard Perl syntax (i.e., commas,
quotes, and the =>
operator). In fact, any Perl syntax for
passing a list can be used, because the argument list is specified in
real Perl syntax.
listing mainpage.mas
CHP-1-EX-6>
<& header.mas, head => "Wally World Home" &> Here at Wally World you'll find all the latest accoutrements. <& footer.mas &>
Mason will take the list of arguments passed to the
header.mas__FOX_NLBF__>
component and assign the proper
values to the variables specified in the
<%args>
__FOX_NLBF__>
block.
CHP-1-SECT-2.2> inheritance> components;inheritance>
Aside from the fact that there's a little bit of Perl thrown into the mix for passing parameters, the examples we've seen don't really show anything that you couldn't do using standard server-side include (SSI) techniques. In fact, the usage demonstrated in these examples is relatively uncommon in building Mason sites, because there are better ways to get the job done. One of the greatest features of Mason is that components can inherit behavior from other components, much like classes and objects in an object-oriented hierarchy.N<A caveat is necessary when using the term ``object-oriented'' to describe Mason's content-wrapping and inheritance schemes, because Mason merely borrows some ideas from the object-oriented world rather than employing Perl's (or any other language's) built-in object-oriented inheritance.> Typically, each component will inherit from a single component called the autohandler autohandlers> . The autohandler implements general behavior for all components, such as the content of headers and footers. Individual components implement specific behavior, such as the body text of the individual pages.
Using component inheritance, we can rewrite A<CHP-1-EX-4>Example 1-4 through A<CHP-1-EX-6>Example 1-6 in a more common Mason idiom, as shown in A<CHP-1-EX-7>Example 1-7 and A<CHP-1-EX-8>Example 1-8.
listing autohandler
CHP-1-EX-7>
<html> <head><title>Welcome to Wally World!</title></head> <body bgcolor="#CCFFCC"> <center><h1><% $m->base_comp->attr('head') %></h1></center> % $m->call_next; <center><a href="/">Home</a></center> </body></html>
listing mainpage.mas
CHP-1-EX-8>
<%attr> head => "Wally World Home" </%attr> Here at Wally World you'll find all the finest accoutrements.
Notice that the header and footer are now both all in one file, the
autohandler. Visually, this helps unify the page content, because
tags like <html>
and
<body>
<body> tag:body tag>
that are opened in the
header are closed in the same file. The other important difference
here is that mainpage.mas no longer has to call
the header and footer components explicitly, but rather Mason calls
the parent component automatically and it wraps its header and footer
around the main content. The page header is now specified by an
attributes block, one of Mason's object-oriented
mechanisms. An attribute is a component property that inherits via
Mason's component
__FOX_NLBF__>
__FOX_NLBF__>
inheritance chain.
There are zillions of other uses for Mason's inheritance mechanism, which will be further explored in A<CHP-5>Chapter 5.
CHP-1-SECT-2.3> caching>
Anyone who has built any dynamically generated web sites knows that sometimes certain portions of a site can take longer to generate and serve than you want to make your users wait. Furthermore, portions of a site might be only ``semidynamic,'' meaning that their content changes periodically but stays static for a long time between changes. Alternatively, as might happen on a news site or for an online poll, content may change continually, but a lag time of a few minutes in updating the content would be acceptable if it improves site performance. For cases like these, Mason provides a very sophisticated caching mechanism that you can use to control how often the output of a component is rebuilt. You can base the expiration decision on time, on certain key parameters like username or content ID, or on an explicit agent that decides when specific data has expired.
The caching mechanism can be used for the output of a component, for an arbitrary block of text, or for any Perl data structure you might want to cache. The first-class support for caching is one of Mason's most endearing qualities, and you'll learn to appreciate it the first time it saves you from spending hours optimizing sluggish code.
To aid overall performance, Mason also has an intelligent internal caching> internal caching mechanism. During execution, Mason turns each component into Perl source code on disk, then compiles the Perl code into bytecode, then executes the bytecode to produce the component's output. It would be a waste of computing resources to repeat this cycle every time a component needs to be executed, so Mason caches at each stage. As an aid to rapid development, Mason will check your components' modification times and invalidate its cache when you make changes to your components, ensuring that any changes you make to your site take effect immediately. When your site moves from development to production, you probably won't be making frequent changes to your site, so you can disable the freshness checks in order to improve your site's responsiveness__FOX_NLBF__> .
CHP-1-SECT-2.4>
As mentioned before, the most common use of
Mason;integration with
Apache>
Mason;integration with
mod_perl>
Mason is in building large, dynamic,
data-driven web
sites>
data-driven web sites. The most popular
web server around is
Apache web
servers>
web
servers>
Apache, and one of
Apache's most powerful features is
mod_perl
, which lets you use the full power of
Perl within the Apache server process. Therefore, it should come as
no surprise that Mason is designed to cooperate fully
with
mod_perl>
mod_perl
. Mason comes with drop-in
mod_perl
handlers that let Apache serve your Mason
components directly. It lets you take advantage of the sophisticated
decision-making mechanisms that Apache has evolved to support, such
as custom authentication methods, content negotiation, and dynamic
URL rewriting. Mason's caching mechanism and other
performance considerations are designed specifically for the task of
serving dynamic content efficiently and with enough flexibility to
let you design creative solutions to your specific problems. Although
Mason lets you build a site without relying very much on assumptions
about the server environment, learning about
mod_perl
and Apache's request
cycle can help you use __FOX_NLBF__>
Mason to create slick and powerful
features.
CHP-1-SECT-3>
Much of this chapter so far may have sounded like a sales pitch, because we wanted you to know about Mason's biggest strengths so you could have some solid reasons for reading the rest of this book. However, you should also be aware that there are many alternatives to using Mason, and an awareness of these alternatives will help you form an accurate picture of the context for which each system was created. It will also help you decide which system to use for each individual project, because no single system was designed to be a solution to all the problems you might encounter. Just as importantly, different people find that different systems suit the way they think better than others do.
There are generally two kinds of systems that people consider to be
alternatives to
Mason;alternatives
to>
Mason: lightweight solutions and
heavyweight solutions. Lightweight solutions generally have the goal
of being small and fast and leave much of the major work up to you.
They are often simple templating modules like
Text::Template
or
HTML::Template
or even homegrown templating
schemes. Using templates is certainly a good idea, and it is one of
the core ideas in Mason itself. However, when designing an entire
site, you're usually going to need some more
sophisticated system that helps you manage your site-building
resources; if you choose a templating-only solution,
you'll probably end up writing this management code
yourself. You may have a good idea of what such a system would entail
only after writing and maintaining dozens of complicated web sites,
so you'd likely spend more time working on your
management code than on building your sites. This is the main
trade-off with lightweight solutions: you gain flexibility because
you can manage your site however you want, but since the burden rests
entirely on you, you might end up preferring to use a tool that
handles many of these management issues for you.
By contrast, heavyweight solutions implement several layers on top of their templating capabilities. Despite some disagreement on proper use of the term, ``application server'' is often used to describe such heavyweight systems. Each anticipates the typical needs of a large, sophisticated web site and provides methods for dealing with these situations cleanly. A heavyweight system will typically have support for integrating a site with a database, working with HTML (Hypertext Markup Language)> HTML and URLs (Uniform Resource Locators)> URLs, preserving state from one request to the next, caching often-used resources, and dealing with error conditions. Each heavyweight solution is tailored to different site requirements and makes different assumptions about the best ways to deal with them.
Good solutions, such as Mason, Embperl, and
Apache::ASP
, also help you organize your site code
in a way that lets you think about your site's
structure in an organized way, both on the small scale and the large
scale. They help you design a site that is easy to build and easy to
maintain.
Mason itself is sort of a unique offering. It sits somewhere in the middle between lightweight and heavyweight solutions, though it leans a bit toward the heavy. It doesn't directly provide support for database connections, HTML munging, or sessions, but it makes it so easy for you to use regular Perl tools for these purposes that you'll never miss the functionality. If you do decide that Mason is missing a feature you really need, it's easy to add functionalities to Mason and use them just as if they were built in. In a sense, Mason's main strengths lie in the ways it lets you interface various parts of your site with one another and with outside resources.
Consider these design goals as you read the following descriptions. When possible, we have worked with the authors of these systems to make sure the descriptions highlight each system's best features. Keep in mind, though, that our list of alternatives is by no means exhaustive. There are countless other solutions. We have tried to pick the most popular solutions, but for more information on any product you might want to use, read its documentation, find an appropriate mailing list in which to ask questions, and make your own decision.
CHP-1-SECT-3.1>
Of the systems presented in this chapter,
Embperl>
Embperl
may be the most similar one to Mason. Embperl is one of the oldest
heavyweight systems that is still in widespread use. It has been used
for several years under the name
HTML::Embperl
HTML::Embperl>
,
but recent beta releases have switched the module name to just
Embperl
. Its author,
Richter,
Gerald>
Gerald Richter, is generally very
responsive to bug reports and feature requests.
Embperl is targeted specifically toward generating HTML and has
several ``magical'' HTML-manipulation features. For instance,
HTML tables> HTML tables can be autogenerated by using
the special Embperl variables $row
$row variable
(Embperl):row variable>, $col
$col variable
(Embperl):col variable>, and $cnt
$cnt variable
(Embperl):cnt variable> :
[- @k = qw(zero one two) -] <table> <tr> <td>[+ $row +]</td> <td>[+ $k[$row] +]</td> </tr> </table>
This would output:
<table> <tr> <td>0</td> <td>zero</td> </tr> <tr> <td>1</td> <td>one</td> </tr> <tr> <td>2</td> <td>two</td> </tr> </table>
This means that Embperl does some scanning of your HTML and your Perl code to decide when you mean to use its magical generation. Some people find this assistance useful, and others would prefer to manage the generation themselves (the approach that Mason takes). The equivalent Mason code would require an explicit loop:
% my @k = qw(zero one two); <table> % foreach my $row (0..$#k) { <tr> <td><% $row %></td> <td><% $k[$row] %></td> </tr> % } </table>
Notice that the Embperl delimiters for embedded Perl code are based
on square brackets like [+ +]
. This is so that
Embperl code can be written by using a WYSIWYG
HTML editors>
HTML editor
that might get confused by angle brackets and treat them as HTML
code. Embperl takes this even further and lets you write Perl code
that is HTML-escaped by the editor, like so:
[- $i = 0; -] [$ while ($i < 5) $] Row: [+ $i++ +]<br> [$ endwhile $]
The text <
will be converted to
<
by Embperl before execution.
Notice also that Embperl uses its own custom loop control syntax (Embperl)> loop control syntax rather than Perl;loop control> Perl's built-in loop control. There is experimental support in Version 1.2b2 and higher for using native Perl loops, and it will be part of the stable feature set in Embperl Version 2.
Embperl has a feature called
EmbperlObjects>
EmbperlObjects,
which is an inheritance system similar to Mason's
autohandler functionality. It also offers integrated support for
preserving state between requests with
Apache::Session
via another special
variable,
%udat variable
(Embperl):udat variable>
%udat
. This can be
very handy; see A<CHP-12>Chapter 12 for how you can
accomplish a similar effect with Mason.
Variables you create in Embperl are usually dynamically scoped as
either local or global variables (not lexical my( )
variables),
which can sometimes be a bit unnerving in a persistent environment
like mod_perl
. Fortunately, after each request, Embperl will clean
up any variables you created during the request. Variables declared
with local()
or my()
in Embperl are usually scoped to the
substitution tag enclosing them. Contrast this to Mason, in which the
default scope of localized variables is the entire component. Because
of this, it is more common to see my()
in Mason code and global
variables in Embperl code.
Embperl Version 1.x also provides some support for using the
Safe.pm
module, which can provide some protection
against executing malicious Perl code. This strategy is somewhat
dubious, however, because the Safe
module is
fairly easily defeated and because we hope your page designers
aren't going to be trying to sabotage your servers
in the first place. Moreover, when using Safe
mode, you won't be able to access outside resources
like databases, so it might not even be an option in the first place.
Because of these problems, support for Safe
mode
has been removed in __FOX_NLBF__>
Embperl Version 2.
Embperl 2 will add several new features, including support for XML/XSLT processing, custom template syntax, and a highly customizable data caching and output filtering system.
CHP-1-SECT-3.2>
Apache::ASP
Apache::ASP
modules>
modules;Apache::ASP>
, by Joshua
Chamas, Joshua>
Chamas, is a package for writing
ASP (Active Server Pages)>
Active Server Pages under
mod_perl
. It is fairly mature (its initial release
was in 1998), and several years of development and active use by the
Perl community have created a feature set that includes several
useful extensions to the Microsoft standard.
With Apache::ASP
, instead of using
VBScript>
VBScript or
JScript>
JScript for the
dynamic portions of the pages, you use Perl.N<A
third-party PerlScript option is also available, but it is not as
widely used as VBScript or JScript.> The ASP
feature set has been neatly translated to Perl, so you have access to
all of ASP's built-in features such as session
management (using a custom session manager, not
Apache::Session
), email integration, and the ASP
object model.
The
Perl;embedding
syntax>
Perl embedding syntax is very simple:
<% %>
embedding tag
(<% %>)>
tags get wrapped around Perl
control structures or miscellaneous Perl instructions, and
<%= %>
tags are wrapped around Perl
expressions whose values you wish to insert into the surrounding
HTML. For example:
<h2>Font sizes:</h2> <% foreach my $i (1..5) { %> <font size="<%= $i %>">Size = <%= $i %></font><br> <% } %>
The Mason equivalent is very similar:
<h2>Font sizes:</h2> % foreach my $i (1..5) { <font size="<% $i %>">Size = <% $i %></font><br> % }
The output of both examples is:
<h2>Font sizes:</h2> <font size="1">Size = 1</font><br> <font size="2">Size = 2</font><br> <font size="3">Size = 3</font><br> <font size="4">Size = 4</font><br> <font size="5">Size = 5</font><br>
Because it is built on the ASP model, Apache::ASP
is a natural choice when porting an ASP/IIS application to the Apache
platform. You will need to translate the scripting language from
VBScript or JScript into Perl, but the overall structure of the site
should remain unchanged.
Besides the standard ASP feature set, Apache::ASP
supports several
additional features, including extra event handlers>
event handlers, XML/XSLT processing, and component output caching. It
also supports a cookieless mode for maintaining session data, which
can be very handy for end users unwilling or unable to store session
cookies> cookies. The XSLT (Extensible
Style Language Transformations)> XSLT support is particularly
interesting, since combining it with the output caching features means
that you can use dynamic XSLT transformations in web publishing, a
technique that might be computationally prohibitive without
__FOX_NLBF__>
__FOX_NLBF__> caching.
For more information on Apache::ASP
, please visit
U<http://www.apache-asp.org/>.
CHP-1-SECT-3.3>
Sam
Tregar,
Sam>
Tregar's
HTML::Template
HTML::Template
module>
modules;HTML::Template>
module falls into the lightweight category. Its chief goal is to
allow site builders to separate a site's HTML from
its Perl controlling code, and it enforces this division quite
strictly. No Perl code is ever embedded within templates, and control
structures like if
, include
,
and various loops are all implemented by custom
HTML::Template
tags. Any variables to be
interpolated into the HTML template are explicitly fed to the
template by the controlling Perl code.
Philosophically, the reason for this strict division of HTML and Perl is so that a division of labor can be enforced in an organization, with HTML designers and Perl coders working independently, not worrying about whether they're editing the same files. It is also possible to apply the same controlling code to several different templates, so that designers can create different look-and-feel templates without involving programmers.
HTML::Template
is generally very fast at filling
in HTML templates, especially if you use its just-in-time compiler
HTML::Template::JIT
. It also provides a caching
mechanism, somewhat similar to Mason's, that allows
for caching templates in private memory, on disk, in memory shared
between processes, or in combinations thereof. Unlike Mason,
HTML::Template
's caching handles
the caching only of templates themselves, not of their output or
arbitrary data.
Example syntax:
<h1>Employee listing:</h1> <TMPL_LOOP NAME=EMPLOYEE_INFO> Name: <TMPL_VAR NAME=NAME> <br> Job: <TMPL_VAR NAME=JOB> <br> </TMPL_LOOP>
To make this actually do something, you need to write Perl code to call the template. For this template, we might write something like this:
my $template = HTML::Template->new( filename => 'emp_list.tmpl' ); $template->param( EMPLOYEE_INFO => [ { NAME => 'Dave', JOB => 'Grouper of Bumpers' }, { NAME => 'Ken', JOB => 'Bumper of Groupers'} ] ); print "Content-Type: text/html\n\n"; print $template->output;
Note that the top layer for the system is a Perl script. Some people love this, some people hate it. You may know by now which category you __FOX_NLBF__> __FOX_NLBF__> fall into.
CHP-1-SECT-3.4>
Text::Template
Text::Template
module>
modules;Text::Template>
,
written by
Dominus,
Mark-Jason>
Mark-Jason Dominus, is a lightweight
solution similar to HTML::Template
, but has some
philosophical differences. First, it does not assume that the
template contains
HTML (Hypertext Markup
Language)>
HTML but is designed to work with any
kind of text in the template (in truth,
HTML::Template
can work with arbitrary text, too,
but it was designed specifically to work with HTML). Second, it uses
native Perl control structures instead of its own custom macros, so
Perl programmers have less to keep in their heads. This has the
effect of breaking down the barrier that
HTML::Template
maintains between code and HTML, so
in an environment in which designers and programmers need exclusive
control over their own work products,
HTML::Template
may be the better choice.
Like Embperl, Text::Template
also supports code
sequestering via the
Safe.pm
Safe.pm
module>
module, with the same caveats as
mentioned earlier. Template variables can be passed explicitly to the
template for substitution or drawn from Perl variables in a specified
Perl package. Text::Template
also allows the user
to customize what
delimiters>
delimiters are
used to indicate the special Perl code or variable substitution
sections. The default delimiters are curly braces:
my $string = q[ Dear {$recipient}, Congratulations! You have won {$amount} dollar{$plural}! ]; my $template = Text::Template->new(TYPE => 'STRING', SOURCE => $string ); $T::recipient = int(rand 2) ? 'Mary' : 'John'; $T::amount = int(rand 10) - 5; $T::plural = $T::amount == 1 ? '' : 's'; print $template->fill_in(PACKAGE => 'T');
Text::Template
was first released in 1995 and has
undergone many revisions in its life cycle. It is considered a mature
product, and its author is very responsive to comments and questions
about it. There is also a low-volume mailing list for users of
Text::Template
, the details of which can be found
in the module __FOX_NLBF__>
__FOX_NLBF__>
documentation.
CHP-1-SECT-3.5>
In order to combat the proliferation of zillions of templating
modules that all look and act similar but contain maddening and
meaningless differences, the
Template
Toolkit>
Template Toolkit package by Andy
Wardley, Andy>
Wardley aims
to be the only templating package you'll ever need
and offers an extremely full-featured
templating
system>
templating system. Like
HTML::Template
, it uses a large set of custom
control
macros>
macro tags
like IF
IF
tag>
SWITCH
tag>
FOREACH
tag>
FILTER
tag>
, SWITCH
,
FOREACH
, and so on, as
well as more advanced tags like
FILTER
FILTER
tag>
TRY
tag>
CATCH
tag>
MACRO
tag>
, TRY
and
CATCH
, and MACRO
. It can either
allow embedded Perl as Text::Template
does or
disallow it as HTML::Template does
. Like Mason, it
lets you build a site in terms of modular components. There is also
an
Apache::Template
Apache::Template
module>
module that facilitates building a
mod_perl
-based site out of Template Toolkit
components.
An example of Template Toolkit usage follows:
my $string = q( Dear [% recipient %], Congratulations! You have won [% amount %] dollar[% plural %]! ); my $template = new Template; my %vars = (recipient => (int(rand 2) ? 'Mary' : 'John'), amount => int(rand 10) - 5); $vars{plural} = $vars{amount} == 1 ? '' : 's'; $template->process(\$string, \%vars);
Because of its many features and its well-supported development, the Template Toolkit is becoming the modern standard for standalone templates. It is quite different in philosophy from Mason, though, so we do not consider it to be in direct competition as a tool for the same situations we'd use __FOX_NLBF__> Mason for.
CHP-1-SECT-3.6>
PHP (PHP: Hypertext Preprocessor)> PHP (U<http://www.php.net/>) is pretty far removed from Mason, but we mention it here because of its popularity. PHP is another mechanism for embedding functionality into web pages, but PHP does not use Perl as its scripting language. The name PHP can refer variously to the embedding system itself, the scripting language, or the interpreter that renders the HTML pages.
It is important to understand some of the properties of PHP before
deciding to use it. One of the design goals of PHP is to be as simple
as possible to install and start using, and in some cases this means
that features that experienced Perl programmers rely on are not
present. For instance, PHP lacks support for private namespaces,
there is no way to create three-tiered applications that separate
business logic and presentation code, and there is no mechanism for
creating reusable code modules. The Apache mod_php
module is only a content generation module, so it cannot cooperate
with other request phases in the same way Mason can cooperate with
mod_perl
's authentication or
filename translation phases.N<Although Mason is also
just a content generation module, it cooperates with the other
request phases by virtue of
mod_perl
's support for sharing
information among the request phases.>
Importantly, although there is a lot of user-contributed code in the
PHP world, it cannot match the breadth and depth of
Perl's CPAN. It has often been said that the
CPAN>
CPAN is
Perl's ``killer
app,'' and programmers most appreciate the CPAN when
they least expect it.
Finally, although you can theoretically use PHP for general-purpose programming, it wasn't designed for that. PHP is typically used only for embedding PHP code into templates, whereas Perl is a full-featured programming language used for more purposes than any single programmer could imagine. While this does make PHP well-suited for the common tasks of web scripting, it may be limiting. For instance, a certain Perl programming friend was recently contracted to write a ``simple shopping cart system'' that had one small addition: it had to do some horribly complex optics calculations. For situations like these, a general-purpose programming language like Perl can be quite __FOX_NLBF__> handy.
CHP-1-SECT-4>
The final criterion in evaluating an application platform is peace of mind: your peace of mind as a developer, your company's peace of mind as a provider of services and maintainer of site resources, and your users' peace of mind to enjoy (or suffer through) your final product.N<An excellent exposition on the importance of peace of mind when designing and maintaining systems is T<Zen and the Art of Motorcycle Maintenance> by Robert M. Pirsig.> If you are continually frustrated by your development tools and environment, you will almost certainly not be able to create a satisfactory product.
Mason was created to help you with tasks when you need help and get out of your way when you don't. It was designed to cooperate with Perl to the fullest extent possible. The Mason templating language is extremely simple but full featured and leverages Perl to do all the things that a programming language is good at. Mason is not explicitly tied to the HTML markup language, but it was designed to function well in an HTML environment. Mason's design choices were made to encourage a structural approach to site building rather than a procedural approach, and this often makes building large sites with a consistent feel very simple.
If you're interested in learning more about alternatives to Mason, you might be interested in another book from O'Reilly and Associates, Inc., T<CGI Programming with Perl>, written by Scott Guelich, Shishir Gundavaram, and Gunther Birznieks. It contains more extensive discussions of many of the modules mentioned here.
CHP-1-SECT-5>
To help you try out the various examples you'll see
throughout the book, we'll walk you through the
typical installation and configuration steps. First
we'll describe a fairly bare-bones standalone
installation that can be used without a web server, and then
we'll describe the more common situation, which is
to install Mason for use in conjunction with the Apache web server
and its mod_perl
-embedded Perl interpreter.
CHP-1-SECT-5.1>
Mason;installing;standalone> Mason can be installed just like any other typical Perl module and used as a toolset for templating. You'll need these ingredients:
Available from U<http://www.cpan.org/src/>. Perl;installing> Perl may already be installed on your system, especially if it's a variety of Unix. Mason requires at least Version 5.005 of Perl, though Version 5.6.1 is recommended. Instructions for installing Perl are contained in the INSTALL file, included with the distributions. If you're on some variety of Windows, you may find it much easier to install a version of Perl supplied by ActiveState, available at U<http://www.activestate.com/Products/ActivePerl/>.
To install Mason, download it from U<http://www.cpan.org/modules/by-module/HTML/>,
U<http://www.masonhq.com/code/download/>, or
your favorite CPAN mirror, and issue the standard commands for
installing Perl modules: perl
Makefile.PL
, then make
, then
make test
. If no errors are encountered, issue the
command make install
. This last step may need to
be done as the administrative user, so that Mason is made available
to all the users of the computer.
During some of these steps, you'll notice Mason
looking around for Apache and mod_perl
. You can
skip these parts of the installation process when asked, since you
won't be using them in this scenario.
You'll also need several other Perl modules that
Mason depends on, such as Exception::Class
,
Class::Container
, and
Params::Validate>
Params::Validate
.
Since it can get fairly tedious to follow all these dependencies
yourself, you may want to use the CPAN.pm
module
to help automate the process. In this case, you can start the
CPAN
shell with the command perl -MCPAN
-e shell
, and then type install
HTML::Mason
at the __FOX_NLBF__>
prompt.
CHP-1-SECT-5.2>
Most of the examples in this book will assume that Mason;installing;mod_perl>
mod_perl;installing>
Mason
is being used in a web context. Most people using Mason also use it
in conjunction with Apache and mod_perl
. The main
ingredients involved in setting up this paradigm are:
You can follow the same procedure as in the standalone scenario. Perl itself doesn't care how you're going to use Mason.
You can get Apache from U<http://httpd.apache.org/dist/httpd/>. Mason
has no direct dependencies on any specific version of Apache, but
you'll probably want the latest version in the 1.3.x
sequence, which is 1.3.26 at the time of this writing. Mason has not
yet been tested extensively with Apache 2.x, though it probably will
be by the time this book hits the shelves. Instructions for
installing Apache are included in its INSTALL
file -- or, if you're building
mod_perl
too, you can just let
mod_perl
build and install Apache for you.
You can get mod_perl
from
U<http://perl.apache.org/dist/>.
mod_perl
follows the standard installation
procedure for a perl module (even though it is actually much more
than that), so you can issue the same perl
Makefile.PL
, make
,
make
test
, and
make
install
commands mentioned
previously. Several configuration options are available in the first
step -- for full Mason compatibility, build
mod_perl
with the command perl
Makefile.PL EVERYTHING=1
. We do not
recommend building mod_perl
as a Dynamic Shared
Object (DSO), because that configuration has been associated with
instability on several platforms.
After you've installed mod_perl
,
you can install Mason. The process is exactly the same as we
described previously in the standalone configuration, but if
mod_perl
is installed, the make
test
step will test Mason with a live
mod_perl
-enabled Apache server. Make sure all the
tests succeed before issuing the make install
command.
Apache web servers;configuration files>
In order to enable Mason for certain sections of your web site, you'll need to configure Apache so that it hands off requests for Mason components to Mason. A simple configuration that will suffice for many users is the following, put in the httpd.conf for the site:
PerlModule HTML::Mason::ApacheHandler <FilesMatch "\.html$"> SetHandler perl-script PerlHandler HTML::Mason::ApacheHandler </FilesMatch>
This tells Apache that all files ending in .html
are Mason components and should be handled by the
HTML::Mason
module via
mod_perl
. Of course, you can use standard Apache
configuration directives to specify different criteria for passing
requests to Mason. For instance, if you'd rather
restrict Mason's influence to a certain directory,
you can use something like this:
PerlModule HTML::Mason::ApacheHandler <Directory /path/to/subdirectory> <FilesMatch "\.html$"> SetHandler perl-script PerlHandler HTML::Mason::ApacheHandler </FilesMatch> </Directory>
Lots of configurations are possible. If you have more complex needs for your site, you'll need to be familiar with Apache's configuration directives. The relevant documentation on general Apache configuration are available at U<http://httpd.apache.org/docs/>, and more advanced __FOX_NLBF__> __FOX_NLBF__> Mason configuration is discussed in A<CHP-7>Chapter 7.
CHP-1-SECT-5.3>
Once Mason;test program for> Mason is installed, you can write a simple test program like the one in A<CHP-1-EX-9>Example 1-9 to show that it's actually working.
listing handshake.pl
CHP-1-EX-9>
#!/usr/bin/perl use strict; use HTML::Mason; my $interp = HTML::Mason::Interp->new( ); my $comp = $interp->make_component(comp_source => <<'END'); Greetings, <% ("Earthlings", "Martians")[rand 2] %> END $interp->exec($comp);
When you run this program, you should see either Greetings,
Earthlings
or Greetings, Martians
. The
code between the <% %>
tags is just regular
Perl code, not anything to do specifically with Mason. It randomly
selects an element from the two-element list ("Earthlings",
"Martians")
. Of course, we'll explain the
details of how the rest of the program works later in this book.
If you've installed mod_perl
and
configured Apache as we described earlier, then you should test out
your setup now. Assuming the first configuration option we showed
you, you can place the same component at the top level of your web
server's documents directory, as shown in A<CHP-1-EX-10>Example 1-10.
listing handshake.html
CHP-1-EX-10>
Greetings, <% ("Earthlings", "Martians")[rand 2] %>
When you request the URL http://www.example.com/handshake.html from
your server, you should again see a random selection of either
Greetings, Earthlings
or Greetings,
Martians
.N<Throughout this book,
we'll use the fictional domain
example.com for many of our examples. Unless you
own this domain (and you don't, since
it's reserved for examples in books like this one),
you should replace it with the real name of your web server.>
Assuming you've gotten
Mason;online
resources>
Mason installed properly and
everything's working right, congratulations. If
you've run into a problem that you
can't figure out, several sources of help are
available. First check out the Frequently Asked Questions file at
U<http://www.masonhq.com/docs/faq/>,
as it contains answers to the most commonly encountered problems. If
you don't get any satisfaction there, try searching
the archives of the Mason mailing list, available at U<http://www.masonhq.com/resources/mailing_lists.html>,
or post a message to
U
Finally, a word of advice as you read this book -- try out all the examples! You'll have a lot more fun and you'll retain the techniques better if you take a hands-on approach. And of course, if you find any errors in the examples, be sure to let us __FOX_NLBF__> know.