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’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,” with lots of features aimed at helping you manage the larger tasks of site design and maintenance.
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 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, as in Example 1-1, Example 1-2, and Example 1-3. Executing mainpage.mas will produce a full page of HTML with the header and footer inserted in place.
Example 1-1. header.mas
<html> <head><title>Welcome to Wally World!</title></head> <body bgcolor="#CCFFCC">
Example 1-3 introduces the
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
Example 1-3. mainpage.mas
<& 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 Example 1-4 now accepts an argument called
$head that contains the text that should get
inserted into the
<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
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
Example 1-4. header.mas
<%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 Example 1-5 is fairly straightforward. It just provides a link to the document root.
component in 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.
Example 1-6. mainpage.mas
<& header.mas, head => "Wally World Home" &> Here at Wally World you'll find all the latest accoutrements. <& footer.mas &>
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. Typically, each component will inherit from a single component called the autohandler . 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.
Example 1-7. autohandler
<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>
Example 1-8. mainpage.mas
<%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
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 inheritance chain.
There are zillions of other uses for Mason’s inheritance mechanism, which will be further explored in Chapter 5.
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 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.
As mentioned before, the most common use of
Mason is in building large, dynamic,
data-driven web sites. The most popular
web server around is
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
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 Mason to create slick and powerful
 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.