Press Releases with Mason

To learn more about building dynamic web sites, Mr. Lerner presents an application for reading the news using Mason and MySQL.

Last month, we took an initial look at
Mason, a template system that sits on top of
mod_perl and allows us to create
fast-executing dynamic web sites built out of small components.

This month, we will look at a simple application built in
Mason—a system to display the latest press releases on a corporate
site. Of course, such a system could be tailored in a number of
ways, including an on-line newspaper or other publication in which
information changes on a regular basis. In creating this small
site, we will see some of the steps involved in working with
Mason.

Creating the Database

The core element of our news system will be a relational
database. I will use MySQL in these examples, although any
relational database system should work fine.

I created a new MySQL database called “atfnews” on my MySQL
server and assigned privileges so that the user atfnews can connect
using the password “atfpass”. I then created the following two
tables:

As you can probably tell from their names, the Categories
table contains a list of category ID numbers and names. The
Articles table contains several more pieces of information,
including an article ID, the category ID into which an article
should be placed, the date and time at which the article was
posted, the article's headline and its body. We ensure no two
articles in a given category have the same headline with a UNIQUE
clause at the end of our CREATE TABLE statement.

The posting_date column takes advantage of MySQL's
TIMESTAMP data type. This type automatically
inserts the time and date of the latest
INSERT or
UPDATE to a given row. In this
way, we can easily determine when news stories were added to the
database, without having to enter or keep track of the information
ourselves.

In order for our news system to work, we will need to create
at least two different sets of components. One set will allow users
to enter news items into the database (i.e., perform INSERTs), and
the second will make it possible to retrieve items from the
database (i.e., perform SELECTs). In a production setting, we would
probably want to restrict posting access to a selected number of
users. This would be possible with a standard .htaccess file, which
allows users to restrict access to individual files or directories,
or with a more sophisticated system that stores user information in
a database.

Structuring the Components

One of Mason's strong points is its use of components.
Components are actually Perl subroutines, cleverly disguised in the
form of HTML files with some Perl thrown in. (Mason's parser
performs the underlying magic that turns components into
subroutines.) This structure means that repeated functionality can
be packaged into one component, then invoked from within other
components.

For example, Listing 1 contains a component called
“database-connect.comp”. This component returns a value, rather
than producing HTML output. Its purpose is to connect to a database
server and return a database handle, typically called
$dbh. By centralizing this connection code, we
can easily move our site from one server to another, changing only
the relevant $host, $user,
$password and $database
variables as necessary.

Once database-connect.comp has been configured, any component
on our system can receive a valid database handle with the
following code:

<%init>
my $dbh = $m->comp(database-connect.comp);
</%init>

The above code takes advantage of Mason's object-oriented
interface, using the predefined $m object to
invoke another component.

By placing the assignment inside of
<%init>, we ensure that the component will
connect to the database before anything else occurs within the
component. However, this also means we are creating a new lexical
variable ($dbh) with each invocation of the
component.

It would be slightly more elegant to perform the above
assignment within a <%once> section,
creating $dbh a single time and keeping the
value around. However, <%once> sections
are executed outside of the Mason component context, meaning they
cannot invoke methods on $m. Moreover,
<%once> sections are invoked before new
Apache child processes are created, which a $dbh
object might not like. Thus, it is common to define
$dbh in a <%once>
section, but to perform the assignment in
<%init>:

The plain-vanilla mason.pl (or “handler.pl”, as the Mason
documentation describes it) configuration file that comes with the
Mason distribution is almost good enough for this system to work.
We need to load only Apache::DBI,
a wrapper module that works with DBI within the mod_perl
environment, ensuring that database connections are created and
dropped only as necessary.

In order to load Apache::DBI, we need to put a
use Apache::DBI statement in mason.pl,
which is loaded with a PerlRequire statement in
httpd.conf. In order to save some memory, we insert a
PerlModule Apache::DBI line into
httpd.conf. This ensures the module is loaded into memory before
Apache splits into numerous child processes. The module might still
require a fair amount of memory, but at least that memory will be
shared among all Apache processes rather than requiring each one to
have its own copy.

Trending Topics

Webinar: 8 Signs You’re Beyond Cron

Scheduling Crontabs With an Enterprise Scheduler
11am CDT, April 29th

Join Linux Journal and Pat Cameron, Director of Automation Technology at HelpSystems, as they discuss the eight primary advantages of moving beyond cron job scheduling. In this webinar, you’ll learn about integrating cron with an enterprise scheduler.