Cover | Table of Contents | Online Book | Colophon
% my $planet = "World"; Hello, <% $planet %>!
Hello, World!
%
character tells Mason that the line
contains Perl code. The 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.
<% %>. 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!
<html> <head><title>Welcome to Wally World!</title></head> <body bgcolor="#CCFFCC">
<center><a href="/">Home</a></center> </body></html>
<& &>, 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 &> <center><h1>Wally World Home</h1></center> Here at Wally World you'll find all the finest accoutrements. <& footer.mas &>
$head that contains the text that should get
inserted into the
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.
mod_perl-embedded Perl interpreter.
http://www.cpan.org/src/.
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 http://www.activestate.com/Products/ActivePerl/.
http://www.cpan.org/modules/by-module/HTML/,
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.
mod_perl. You can
skip these parts of the installation process when asked, since you
won't be using them in this scenario.
Exception::Class,
Class::Container, and
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
CPANdie(
)
function. In a
mod_perl or CGI environment, Mason will make sure
that this exception is handled in a reasonable way, by showing the
error in the browser and/or recording the error in the
server's error log. You can also catch exceptions in
your own code and handle them as you
please.
mod_perl or
CGI, Mason will default to using the
web
server's document root as the component root. Mason
may also be used in ways that don't require a
component root at all, such as from a standalone perl script. Since
the focus of this book is on building sites, we will generally assume
that there is a component root unless we mention otherwise.
HTML::Mason::Component
object. This object, in turn, can be
used to generate the text originally found in the component. In a
sense, this inverts the component, turning it from text with embedded
Perl into Perl with embedded text.
|
Tag
|
Name
|
Contains
|
|---|---|---|
|
<% ... %>
|
Substitution
|
Perl that is evaluated and sent as output
|
|
% ...
|
Perl line
|
A single line of Perl code
|
|
<%perl> ... </%perl>
|
Perl block
|
Perl code
|
|
<& ... &>
|
Component call
|
A call to another component, possibly with arguments |
<%args>
block discussed previously. This block is used to declare the
arguments that a component expects. In addition, it can also be used
to specify a default value if none is given when the component is
called.
<%args> $color $size => 20 @items => ( 1, 2, 'something else' ) %pairs => ( key1 => 1, key2 => 'value' ) </%args>
color , which is mandatory,
and one named size , which is not
mandatory and defaults to 20. It also expects an array named
items , which defaults to
(1, 2, '
something
else'
) and a hash named
pairs, which defaults to
(
key1 => 1, key2 =>
'value' ). Neither of these latter two arguments is
mandatory.
$color variable available. You do not need
to declare it anywhere but in the
<%args> block.
undef is a valid value for an argument. It is the
absence of an argument that causes the
exception.
<%args> block, each
component body also has a lexically scoped hash called
<& &>), by using
the $m->comp( )
method, or via a URL. When using a
component call tag, the called component's output is
placed exactly where the tag was. When a component is called via a
URL, its output is sent to the client. The $m->comp(
) tag offers an additional channel of component output: the
return value. By default, Mason components return
undef. If you want to return something else, you
can add an explicit return( ) statement inside
that component, such as this:
<%init> my $size = 20; return $size; </%init>
return(
)
function will end processing of the
component, and any values specified will be the return value of
$m->comp( ). Since Perl's
normal rules of scalar/list context apply, a component may return
either a scalar or a list.
%ARGS, which is
lexically scoped for each component. Mason also has a few special
global
variables available.
HTML::Mason::Request object,
which has a number of methods that allow you to do things such as
retrieve information on the current request, call other components,
or affect the flow of execution. This object is discussed in detail
in Chapter 4.
mod_perl (as is the case
in most Mason setups), all components also have access to the Apache
request object via the global variable $r.
Mason's special hooks into
mod_perl are covered in Chapter 7.
<%init> block does some very simple work to
figure out the time that the file was last altered, and then it turns
that time into a human-readable string.
<table width="100%" cellspacing="0" cellpadding="5">
<tr>
<td class="heading"><h2 class="headline">What's New?</h2></td>
</tr>
<tr>
<td>
<p>
The whole site, at this point.
</p>
<p>
<em>Last modified: <% $last_mod %></em>
</p>
</td>
</tr>
</table>
<%init>
my $comp_time = (stat $m->current_comp->source_file)[9];
my $last_mod =
Time::Piece->strptime( $comp_time, '%s' )->strftime( '%B %e, %Y %H:%M' );
</%init>dhandler
and serve that instead of the requested component. Mason looks for
dhandlers in the apparent requested directory and all parent
directories. For instance, if your web server receives a request for
/archives/2001/March/21 and passes that request
to Mason, but no such Mason component exists, Mason will sequentially
look for /archives/2001/March/dhandler,
/archives/2001/dhandler,
/archives/dhandler, and
/dhandler. If any of these components exist, the
search will terminate and Mason will serve the first dhandler it
finds, making the remainder of the requested component path available
to the dhandler via $m->dhandler_arg. For
instance, if the first dhandler found is
/archives/dhandler, then inside this component
(and any components it calls), $m->dhandler_arg
will return 2001/March/21. The dhandler can use
this information to decide how to process the request.
dhandler
and serve that instead of the requested component. Mason looks for
dhandlers in the apparent requested directory and all parent
directories. For instance, if your web server receives a request for
/archives/2001/March/21 and passes that request
to Mason, but no such Mason component exists, Mason will sequentially
look for /archives/2001/March/dhandler,
/archives/2001/dhandler,
/archives/dhandler, and
/dhandler. If any of these components exist, the
search will terminate and Mason will serve the first dhandler it
finds, making the remainder of the requested component path available
to the dhandler via $m->dhandler_arg. For
instance, if the first dhandler found is
/archives/dhandler, then inside this component
(and any components it calls), $m->dhandler_arg
will return 2001/March/21. The dhandler can use
this information to decide how to process the request.
inherit flag, or it may inherit from
/trains/autohandler or
/autohandler by default.
$m.
HTML::Mason::Request->new(
)
,
is intended for use by other Mason objects and is not documented for
external use. If you want to make a new request object, use the
make_subrequest(
)
method provided by the request object,
which is covered as part of the discussion of
Mason's subrequest mechanism in Chapter 5.
HTML::Mason::Request->instance(
)
, returns the current Mason request
object. This is useful if you have code outside of a Mason component
that needs to access the request object. Inside components, you
can just use $m.
$m.
HTML::Mason::Request->new(
)
,
is intended for use by other Mason objects and is not documented for
external use. If you want to make a new request object, use the
make_subrequest(
)
method provided by the request object,
which is covered as part of the discussion of
Mason's subrequest mechanism in Chapter 5.
HTML::Mason::Request->instance(
)
, returns the current Mason request
object. This is useful if you have code outside of a Mason component
that needs to access the request object. Inside components, you
can just use $m.
HTML::Mason::Component::FileBased
class, which is used for components
generated from component source files. The next most common will be
HTML::Mason::Component::Subcomponent
objects, which represent subcomponents
and methods. Finally, anonymous components created via the
HTML::Mason::Interp->make_component( ) method
(covered in Chapter 5 and Chapter 6) will simply be of the
HTML::Mason::Component
class.
make_component( ) method.
<%attr> blocks, as covered in
"<%flags> and <%attr>
blocks" in Chapter 2.
attr( ) method except that it
simply returns undef if the specified attribute
does not exist.
undef as its value and an attribute
that is not found. To make that distinction, use the attr(
) method and wrap it in an eval {}
block, or use this method in conjunction with the
attr_exists( ) method.
scomp( ) method for the
Request object. This method calls the named method with the given
arguments and returns the output as a string. If the method is not
present in the component or any of its parents, an exception is
thrown.
<%def></%def> block, a special Mason
directive that defines one component from within another. The
component embedded within the
<%def>
block is called a
subcomponent
,
and it is visible only to the component within which it resides:
component A may not access component B's
subcomponents directly.
<%args>,
<%init>, %-lines, and so
on. The only exceptions are that you may not use
<%def> or <%method>
blocks within subcomponents nor may you use
"global" blocks like
<%once> or
<%shared>.
<%def> tag (the name often starts with a
period, purely by convention) and that you use the regular
component-calling mechanisms ($m->comp() or a
<& &> tag) to invoke it.
<h2>Information about certain Minnesota cities:</h2>
% my @cities = ("Young America", "Sleepy Eye", "Nisswa", "Embarrass",
% "Saint Cloud", "Little Canada", "Burnsville", "Luverne");
% foreach my $name (@cities) {
<hr>
<& .city_info, city => $name, state => 'MN' &>
% }
<%def .city_info>
<%args>
$city
$state
</%args>
<table border="2">
<tr> <th colspan="2"><% $city %></th> </tr>
<tr> <td>Population:</td> <td><% $population %></td> </tr>
<tr> <td>Coordinates:</td> <td><% "$latitude, $longitude" %></td> </tr>
<tr> <td>Mayor:</td> <td><% $mayor %></td> </tr>
</table>
<%init>
my ($population, $latitude, $longitude, $mayor) =
$dbh->selectrow_array("SELECT population, latitude, longitude, mayor
FROM cities
WHERE city=? and state=?",
undef, $city, $state);
</%init>
</%def><%def></%def> block, a special Mason
directive that defines one component from within another. The
component embedded within the
<%def>
block is called a
subcomponent
,
and it is visible only to the component within which it resides:
component A may not access component B's
subcomponents directly.
<%args>,
<%init>, %-lines, and so
on. The only exceptions are that you may not use
<%def> or <%method>
blocks within subcomponents nor may you use
"global" blocks like
<%once> or
<%shared>.
<%def> tag (the name often starts with a
period, purely by convention) and that you use the regular
component-calling mechanisms ($m->comp() or a
<& &> tag) to invoke it.
<h2>Information about certain Minnesota cities:</h2>
% my @cities = ("Young America", "Sleepy Eye", "Nisswa", "Embarrass",
% "Saint Cloud", "Little Canada", "Burnsville", "Luverne");
% foreach my $name (@cities) {
<hr>
<& .city_info, city => $name, state => 'MN' &>
% }
<%def .city_info>
<%args>
$city
$state
</%args>
<table border="2">
<tr> <th colspan="2"><% $city %></th> </tr>
<tr> <td>Population:</td> <td><% $population %></td> </tr>
<tr> <td>Coordinates:</td> <td><% "$latitude, $longitude" %></td> </tr>
<tr> <td>Mayor:</td> <td><% $mayor %></td> </tr>
</table>
<%init>
my ($population, $latitude, $longitude, $mayor) =
$dbh->selectrow_array("SELECT population, latitude, longitude, mayor
FROM cities
WHERE city=? and state=?",
undef, $city, $state);
</%init>
</%def>make_component( )
method. It accepts a
comp_file or comp_source
parameter (letting you create a component from a file or a string,
respectively) and returns a Component object.
# Creating a component from scratch #!/usr/bin/perl -w use strict; use HTML::Mason; my $source = <<'EOF'; <%args> $planet </%args> Hello, <% $planet %>! EOF my $interp = HTML::Mason::Interp->new( ); my $comp = $interp->make_component(comp_source => $source); $interp->exec($comp, planet => 'Neptune');
<& $comp &> <%init> my $comp = $m->interp->make_component( comp_file => '/home/slappy/my_comps/foo', ); </%init>
make_component( ) method. If you
want to trap these errors, you may wrap the make_component(
)
method in Perl's
eval
{} block, and check
$@ after the method call.