Tải bản đầy đủ (.pdf) (31 trang)

Tài liệu Embedding Perl in HTML with Mason Chapter 1: Introduction pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (77.73 KB, 31 trang )

Embedding Perl in HTML with Mason

Chapter 1: Introduction
At its heart, 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, 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 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. 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.
A First Example
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 code, called a 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 Chapter 2
, but two
basic elements in the preceding example deserve mention here. The first is
that any line that begins with a % 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.
The other element in the previous Mason component is the 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.
The Main Features of Mason
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.
Components: Modular Design Elements
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-2. footer.mas
<center><a href="/">Home</a></center>
</body></html>
Example 1-3
introduces the component 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.
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 $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() function.
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.
Example 1-5. footer.mas
<center><a href="/">Home</a></center>

</body></html>
In the mainpage.mas
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 &>
Mason will take the list of arguments passed to the header.mas
component
and assign the proper values to the variables specified in the <%args>
block.
Object-Style Component 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.
1
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.
Using component inheritance, we can rewrite Example 1-4
through Example
1-6 in a more common Mason idiom, as shown in Example 1-7 and Example
1-8.
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 tags like
<html> and <body> 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
.
Intelligent Caching Mechanisms
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 .
Integration with Apache and mod_perl
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 with 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 features.
Alternatives to Mason
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: 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 and 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.
Embperl
Of the systems presented in this chapter, 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 , but recent beta releases have switched the module
name to just Embperl. Its author, 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 can be
autogenerated by using the special Embperl variables $row , $col , and

$cnt :
[- @k = qw(zero one two) -]
<table>
<tr>
<td>[+ $row +]</td>
<td>[+ $k[$row] +]</td>
</tr>
</table>
This would output:

×