Chapter 2: Components- P1
As mentioned in Chapter 1, the basic building block of Mason is called a
component. A component consists of text of any sort as well as Mason-
specific markup syntax. This chapter briefly introduces some core Mason
concepts and then goes into the nitty-gritty of component syntax.
In this chapter we'll introduce you to the syntax of Mason components, but
we won't spend much time on semantics. In most of the sections, we refer to
other parts of the book where you can find out more about each concept.
Mason from 10,000 Feet
In order to put Mason into perspective, a basic understanding of how Mason
processes a request is helpful. Each request is defined by an initial
component path and a set of arguments to be passed to that component.
Requests are handled by the Interpreter object. You can use it directly or its
API can be called by the ApacheHandler or CGIHandler modules provided
with Mason.
The Interpreter asks the Resolver to fetch the requested component from the
filesystem. Then the Interpreter asks the Compiler to create a "compiled"
representation of the component. Mason's compilation process consists of
turning Mason source code into Perl code, which is then executed in order to
create an object representing the component. Mason stores this generated
Perl code on disk, so that it doesn't need to go through the parsing and
compilation process for every request, and stores the compiled code in an
LRU (least recently used) cache in memory.
Once Mason has an object representing the initial component, it creates a
request object and tells it to execute that component. The initial component
might call several other components during the request. Any output a
component generates is sent to STDOUT, which is a reasonable default for
most environments in which Mason might be used. Of course, it is possible
to change this default and send output elsewhere.
Several parameters can change how elements of this process happen, and
you can replace the core Mason classes with your own customized
bit more complex than that, because you may actually specify multiple
directories in which to search for components or use another storage
mechanism altogether. We'll leave those complexities aside for now.
1
When
running under Apache, either via 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.
It is very important to understand that component paths, like URL paths,
always use the forward slash (/) as their directory separator, no matter what
operating system Mason is running on. In other words, a component path
can be thought of as a unique identifier for a particular component, in much
the same way that a URL is a unique identifier for a particular resource. Also
much like a URL, a component path usually corresponds to a file on disk
with a related path, but it needn't necessarily.
Basic Component Syntax
Mason parses components by taking the text of a component and translating
it into actual Perl code. This Perl code, when executed, creates a new
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.
The markup language Mason uses can give certain parts of the component
special semantics, just like any other markup language such as XML or
HTML. In this case, the syntax is used to tell Mason that certain parts of the
component's text represent either Perl code, special instructions for Mason,
results of a Perl expression into your text. This tag is quite similar to those
found in other templating systems. A simple example might look like this:
% $cd_count = 207; # this is embedded Perl
You have <% $cd_count %> CDs.
The output of this example would be:
You have 207 CDs.
The contents of the tag are evaluated in a list context and joined together just
as if they had been passed as arguments to Perl's built-in print() function.
It is possible, and often desirable, to put more complicated Perl expressions
into your substitution tags. For example, to handle plurals properly, the
second line in the previous example could be rewritten as:
You have <% $cd_count %> CD<% $cd_count != 1 ?
's': '' %>
This could output any of the following, depending on the value of the
$cd_count variable:
You have 207 CDs.
You have 1 CD.
You have 0 CDs.
The contents of the substitution tag are evaluated as Perl code, so whitespace
is ignored, meaning <%$cd_count%> would be perfectly valid, though
perhaps a bit difficult to read. Our style is to always include whitespace in a
substitution tag.
Escaping substitutions
One very useful feature provided by Mason is the ability to escape the
contents of a tag before it is sent as output. Escaping is the process of
making unsafe characters safe. In a web context, safe means that we do not
generate output that could be mistaken for HTML. In addition, we may need
to do URL-style escaping as well.
Substitution escaping is indicated with a pipe (|) followed by one or more
escape flags placed before the close of the tag. Currently, there are three