Press Releases with Mason
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.
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:
CREATE TABLE Categories ( category_id SMALLINT UNSIGNED AUTO_INCREMENT, category_name VARCHAR(25) NOT NULL, PRIMARY KEY(category_id), UNIQUE(category_name) ); CREATE TABLE Articles ( article_id MEDIUMINT UNSIGNED AUTO_INCREMENT, category_id SMALLINT UNSIGNED NOT NULL, posting_date TIMESTAMP NOT NULL, headline VARCHAR(30) NOT NULL, body TEXT NOT NULL, PRIMARY KEY(article_id), UNIQUE(category_id, headline) );
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.
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>:
<%once> my $dbh; </%once> <%init> $dbh = $m->comp(database-connect.comp); </%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.
Fast/Flexible Linux OS Recovery
On Demand Now
In this live one-hour webinar, learn how to enhance your existing backup strategies for complete disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible full-system recovery solution for UNIX and Linux systems.
Join Linux Journal's Shawn Powers and David Huffman, President/CEO, Storix, Inc.
Free to Linux Journal readers.Register Now!
- Sony Settles in Linux Battle
- Download "Linux Management with Red Hat Satellite: Measuring Business Impact and ROI"
- Libarchive Security Flaw Discovered
- Profiles and RC Files
- Maru OS Brings Debian to Your Phone
- Understanding Ceph and Its Place in the Market
- Snappy Moves to New Platforms
- The Giant Zero, Part 0.x
- Git 2.9 Released
- Astronomy for KDE
With all the industry talk about the benefits of Linux on Power and all the performance advantages offered by its open architecture, you may be considering a move in that direction. If you are thinking about analytics, big data and cloud computing, you would be right to evaluate Power. The idea of using commodity x86 hardware and replacing it every three years is an outdated cost model. It doesn’t consider the total cost of ownership, and it doesn’t consider the advantage of real processing power, high-availability and multithreading like a demon.
This ebook takes a look at some of the practical applications of the Linux on Power platform and ways you might bring all the performance power of this open architecture to bear for your organization. There are no smoke and mirrors here—just hard, cold, empirical evidence provided by independent sources. I also consider some innovative ways Linux on Power will be used in the future.Get the Guide