Recently in Web design/development Category

I’ve had an analogy on my mind for several days, churning, and I think I’d better blog it or else it’s going to devour me. Here it is:

“PHP application development is like bologna as Perl application development is like a good marinated London Broil.”

So, there you go. Now, let me explain. There are upsides and downsides to this.

Balogna requires nearly nothing to start eating. It’s as simple as opening the package, removing a slice of the processed meat product, and eating it. It’s just that easy. My five-year old does it all the time. Sometimes, he puts it on a plate and, using a butter knife, cuts the slice of balogna into little wedge-shaped pieces.

And, as a consumer, you don’t have to do much to get balogna to a point where you can consume it. It’s ready in its edible form at the supermarket. You go, buy it, take it home, (cut a slice into little wedge-shaped pieces), and eat it.

London Broil, on the other hand, isn’t available at the supermarket in sealed ready-to-eat packaging. You have to find a cut of top round beef, preferably one that has a nice amount of thickness (over 1-inch thick is ideal). In addition to the beef, you’re going to need to get some other ingredients for the marinade. When I was in college and wanted to impress a girl on a date, my sister suggested preparing a dinner that included London Broil. I don’t remember the exact recipe for the marinade now, but I remember there was worchestershire sauce, red cooking wine and series of different spices and salts. Looking online, there are many different recipes for such a marinade that include honey, garlic, chopped parsley, pepper, soy sauce, and more.

Once you get your ingredients home, mix the marinade and put it in a large plastic bag that zips shut. Place the raw beef into the bag with the marinade and put it in the refrigerator for up to 24 hours, turning it over once.

Cooking the marinated London Broil is a tricky p;ocess. You definitely broil or grill the meat, but this isn’t a hamburger. You need to heat it carefully, about six to eight inches over the flames. Some recipes actually call for broiling the meat to “rare” before you place it in the marinade. After the meat is cooked to the desired wellness, take it off the grill and begin cutting it in slices with your knife at a 45-degree angle to the meat.

Mmmmm mmmm. This is making my mouth water, just blogging about it!

London Broil, a magnificent meal that is sure to impress a date (or scare her away, as was my case.).

To bring this back to the programming languages, let me regurgitate a story of a recent experience I had.

A couple of weeks ago, a handful of systems I used to manage were compromised. These servers were running Fedora Core 6 and Fedora Core 5 which, of course, haven’t been supported by the Fedora community in at least a couple of years. The obvious response to a compromise was to install a actively supported Linux distribution on the hardware, make sure security issues are addressed, and then re-deploy the applications.

I was asked to assist in the process because of my knowledge of the systems.

Backing up critical data, installing a new OS, restoring data was pretty straightforward and easy. Next came the harder part: Getting all the applications configured and working again, just as they were supposed to.

Most of these applications were written in Perl. I went through each, one by one, taking note of the errors that occured when I first tried to run them. These errors invariably complained of missing CPAN modules — most of which were not available as packages available to install from a software repository affiliated with the Linux distribution.

This meant I had to go through, one by one, and build packages for each CPAN module that was a dependency for the applications. Many of these had their own sets of dependencies. The result: a couple of hours building packages to satisfy an interconnecting web of dependencies. In the end, everything worked.

It was then I decided to check on the one application that wasn’t written in Perl. This last application was written in PHP by some no-name programming team that the client paid to develop and host the software but when they didn’t have the chops to host and manage the application, the client took the application to someone who did have the necessary skills.

Guess what. The PHP application ran, out of the box. no unmet dependencies; No package installations neededl No fuss; Nothing.

At a recent PLUG meeting, I shared my experience with a friend who nodded in agreement. He too had his share of trouble navigating the waters of “dependency hell” trying to get a Perl application working.

Some Perl developers don’t understand this experience because they don’t use their OS’s packaging infrastructure to manage their Perl installation. Instead, they let Perl run loose, so to speak, and install necessary packages outside of a package management system. The upside: It’s fast. The downside: It’s risky and unmanagable.

My friend said, “Perl developers are just too smart.” I have to agree. Damian Conway, a Perl guru that travelled to Utah and spoke to a group of us about four years ago, likes to quote the late Arthur C. Clarke: “Any sufficiently advanced technology is indistinguishable from magic.” Conway prides himself on being the author of several CPAN modules that work “like magic.”

Conway’s not the only one. Many in the Perl community have developed extremely useful but complicated pieces of code and have graciously shared it with the open source community. Like any good open source community, others have built on what has been done and the result is software that has a deep root system of module dependencies.

Meanwhile, Perl has fallen out of favor as a language of choice for web application development, despite all the “magic” that exists within the Perl community. Why? If it’s so technologically superior, why aren’t the hordes of web developers using it?

The answer: Precisely because it is so technologically superior.

Newcomers to web development are drawn to the simplicity, straightforwardness, and relatively painless entry of developing applications using PHP. I can’t tell you how many PHP-based web applications I’ve looked at that are quite useful and powerful on the outside, but the code is... well, it’s boring. That’s not to say the programmers didn’t know what they were doing, they just didn’t really seem to know of any optimal ways of doing it. In the end, that’s okay, because the software works as it’s supposed to. A computer scientist will tell you, however, that this type of programming runs the risk of becoming unmanagable as it grows. The PHP community doesn’t seem to mind, though. They’ve had no problem “brute-forcing“ their way through most obstacles like this.

As a advocate of Perl, I’m left with a problem. My language of choice is failing at popularity contests and now I think I know why: It’s a pain in the ass to grasp in order to wield the magic.

What is it going to take to rectify this problem?! A Linux distribution that includes a great portion of the CPAN modules a programmer would ever need? That would certainly make things a lot easier.

What if the great minds of Perl put their current challenges aside for a few moments and tackled this challenge instead? Make the magic easier to obtain. Make using Perl much less frustrating for the uninitiated.

There are some that would say selling London Broil in a ready-to-eat package would be too hard or that it would be too expensive. I don’t know. I know you can get some very tasty prepared, marinated meats ready to slap on a plate. Sure, you pay more than you would for a slice of balogna, but isn’ it worth it?

It doesn't matter what language you do your server-side web development in, presentation templates just make so much sense. Here are some reasons why:

  • Templates (usually) let you re-use commonly used blocks of code.
  • Templates (usually) make it easy (or easier) for a web designer (e.g. not a developer) to work on the presentation layout of your application.
  • Templates allow you to separate presentation from business logic and will help you separate them in how you think of your application as well.

By templates, I mean files that contain HTML data along with some special coded method of interpolating dynamic data into the HTML.

By this definition, PHP and ASP code are template languages themselves. That's one of the more substantial reasons I've come to dislike these languages! You'll come to understand as you read more below.

Here's a very simple template example:


<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <title>$TITLE</title>
    </head>
    <body>
        <h1>Welcome to the $SITE_NAME website!</h1>
    </body>
</html>

The above example uses the syntax defined by the CGI::FastTemplate Perl module. I used this module for a couple of projects in 2000 or so and while it does make it easy to design a page's look and feel around the dynamic content your web application is going to drop into the page, it works best when your content doesn't need to be nested inside HTML. For example, dynamics data in a table does not work well with CGI::FastTemplate. Neither do lists of data.

Some templating systems, like CGI::FastTemplate to some extent, can handicap you too much. Others, like HTML::Embperl or ePerl, in my opinion, provide too much capability at the template level.

You don't want to be able to write your entire application in a template. You might as well be writing your application in PHP, JSP, or ASP (or Apache::ASP).

I think a templating system should provide you with just enough logic so that you can affect how data is presented and not much more logic than that. I'm not alone in thinking these things. See Wikipedia topics: Web template system, Model-view-controller, and Separation of concerns.

So, as a result of study of templating systems for Perl, I recommend Template (Template Toolkit for Perl).

Note: Template Toolkit does allow some things I don't think have any place in templates, but it doesn't do so by default. You have to make a conscious choice to do those things, read the documentation, etc. and that should (hopefully) discourage you from doing so.

How to use Template Toolkit

Let's take a look at how Template Toolkit would be used to mimic the CGI::FastTemplate example above.


<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <title>[% title %]</title>
    </head>
    <body>
        <h1>Welcome to the [% site_name %] website!</h1>
    </body>
</html>

It's not a whole lot different, is it? And, actually, it's a little more typing to key in those beginning and ending brackets instead of just a preceding dollar sign.

Now, here's an example of how this template file (we'll call it page1.tt) would be used in Perl code, say, in a CGI script.


#!/usr/bin/perl

use CGI qw/:standard/;
use Template;

my $q = CGI;
my $tt = Template->new({
    INCLUDE_PATH    =>  '/var/www/templates/'});

my $vars = {};

$vars->{'title'} = 'Joe Schmoe Shoe Repair - Home';
$vars->{'site_name'} = 'Joe Schmoe Shoe Repair';

print $q->header('text/html');
print $tt->process('page1.tt', $vars) || 
    die $tt->error();

Great! Now we know Template is just as good as CGI::FastTemplate! What else can it do?!

Wrapping an application

One thing I often do with Template Toolkit is use it to wrap applications so that every page has the same look and feel. You do this by defining a wrapper template in the hash reference you pass to the Template constructor:


my $tt = Template->new({
    INCLUDE_PATH    =>  '/var/www/templates/',
    WRAPPER         =>  'sitewrapper.tt', });

Now every page generated by the process() function will include the contents of sitewrapper.tt around it.

The wrapper template needs to contain a special template directive in it: [% content %]. This is where the contents of your specified templates are placed.

Here is an example of a wrapper template:


<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <title>[% template.title %]</title>
        <link rel="stylesheet" type="text/css" href="style.css" />
    </head>
    <body>
        <div class="sidebar">[% INCLUDE sidebar.tt %]</div>
        <div class="body">[% content %]</div>
        <div class="footer">[% INCLUDE footer.tt %]</div>
    </body>
</html>

Notice the use of the [% content %] directive in the wrapper template.

There are a couple other interesting uses of Template Toolkit directives in this example, notably the INCLUDE directive (for inserting the parsed output of other templates) and a special directive within the HTML title tags.

The [% template.title %] directive should make sense once we see how a normal template might look when using a wrapper:


    [% META title = "Contact us" %]
    <h1>Contacting Joe Schmoe Shoe Repair!</h1>
    <p>See the list below for our telephone numbers:</p>
    <ul>
    [% FOREACH phone = phone_numbers %]
        <li>[% phone.name %]: [% phone.number %]</li>
    [% END %]
    

The META directive let's us pass data into the wrapper template.

Flow control

The above template example also introduces to one of the reasons I love Template Toolkit: flow control. In this case, a for-each loop. The variable phone_numbers could be a list of hashes we get from a database and pass to the template. Each hash contains a name-value pair named name and one named number. The FOREACH directive allows us to iterate through the phone_numbers list and assign a reference the current hash to a variable we've named phone. Inside the loop, we can reference the individual name-value pairs by name.

This is only one of the flow control structures Template Toolkit offers. There are also IF-THEN-ELSIF-ELSE structures, CASE/SWITCH structures, and WHILE loops.

These should give you just a taste of what Template Toolkit can do. With the Template Perl module installed on your system, you get all the documentation you could hope for as POD and man files. The Template Toolkit website also has all this documentation online as well.

Below is a bit of a more complex template I created years ago for the utahisps.com website.


      <h3>[% company.name %]</h3>
      <table cellpadding="6">
        <tr>
          <td>Services</td>
          <td>
                [% has_services = 0 %]
                [% FOREACH service_name = services.keys %]
                  [% IF services.$service_name %]
                    <a href="/isp/[% company.company_id %]/[% service_name %]">
                    [ % service_name %]</a><br/>
                    [% has_services = 1 %]
                  [% END %]
                [% END %]
                [% IF has_services == 0 %]
                  N/A
                [% END %]
                  <!-- None listed -->

              </td>
            </tr>
        <tr>
          <td>Address</td>
          <td>
            [% company.addr1 %]<br/>
        [% IF company.addr2.length %]
        [% company.addr2 %]<br/>
        [% END %]
        [% company.city %], [% company.state %] [% company.zip %]
          </td>
        </tr>
        <tr>
          <td>Phones</td>
          <td>
            [% IF company.phone1.length %]
                [% company.phone1 %] ([% company.phone1_desc %])
        [% END %]
            [% IF company.phone2.length %]
        <br/>
                [% company.phone2 %] ([% company.phone2_desc %])
        [% END %]
          </td>
        </tr>
        [% IF company.fax.length %]
        <tr>
          <td>Fax</td>
          <td>[% company.fax %]</td>
            </tr>
            [% END %]
            <tr>
              <td>Website</td>
          <td>< <a href="[% company.www_url %]" 
          target="_new">[% company.www_url %]
          </a> ></td>
            </tr>
        [% IF company.info_email.length %]
        <tr>
          <td>Info E-mail</td>
              <td>< <a href="mailto:[% company.info_email %]"
              target="_new">
              [% company.info_email %]</a> ></td>
            </tr>
            [% END %]
        <tr>
          <td>Payment</td>
              <td>
                [% IF company.credit_cards.length %]
                  [% company.credit_cards %]
                [% ELSE %]
                  Cash/check only
                [% END %]
            </tr>
        [% IF company.oper_since %]
        <tr>
          <td>Oper since</td>
              <td>[% company.oper_since %]</td>
            </tr>
            [% END %]

        <tr>
              <td><a href="http://www.angio.net/rep/" 
              target="_new">Utah
              REP</a><br/>member</td>  
              <td>[% IF company.ut_rep %]Yes[% ELSE %]No[% END %]</td>
            </tr>
            
        [% IF company.os.length %]
        <tr>
          <td>Primary OS</td>
              <td>[% company.os %]</td>
            </tr>
            [% END %]

        [% IF company.upstreams %]
        <tr>
          <td>Upstream feeds</td>
              <td>[% company.upstreams %]</td>
            </tr>
            [% END %]


        [% IF company.notes.length %]
        <tr>
          <td>Notes</td> 
              <td><tt>[% company.notes %]</tt></td>
            </tr>
            [% END %]
     </table>

Perl is over twenty years old, but it continues to evolve as a programming language. When Perl 6 is released to the world, we're going to see an incredibly modern language that is adaptable to tackle many of the challenges faced by programmers today including internationalization/localization, Internet networking, object orientation, and more.

But this blog post isn't about Perl 6. This is the first in a series of posts designed to help people ease into Perl as a web development language and is influenced largely by tutorials and seminars I've given in person and online about using Perl as a web development tool.

Perl was embraced for web development in the early and mid 1990s because it had already become a powerful language for text-processing and system administration. As such, it was a natural first choice for developing web applications.

Perl programmers at the time adapted public domain algorithms into Perl code to process HTML forms, but the results were not pretty.


my $hashRef = {};
my $buffer = "";

if ($ENV{'REQUEST_METHOD'} eq 'GET') {
    $buffer = $ENV{'QUERY_STRING'};
}
else {
    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
}

foreach (split(/&/, $buffer)) {
    my($key, $value) = split(/=/, $_);
    $key   = decodeURL($key);
    $value = decodeURL($value);
    %{$hashRef}->{$key} = $value;
}

sub decodeURL {
    $_ = shift;
    tr/+/ /;
    s/%(..)/pack('c', hex($1))/eg;
    return($_);
}

No wonder Perl is often labeled as "unreadable!"

Thankfully, Lincoln Stein came along and gave us CGI.pm-- a Perl 5 module that makes several tasks the Perl web developer is commonly faced with, easier:

  • Generating good HTTP headers
  • Parsing form data
  • Generating HTML
  • Handling file uploads
  • Debugging HTML form processes
  • ...and more

Web developers often fail to realize they take on a greater level of responsibility when they leave the realm of static HTML pages, images, MP3 files, etc. served up by a HTTP server like Apache and enter the world of dynamic content generation, interactive web applications, and forms and form processors.

Web developers must write code to generate headers for the client that would otherwise be handled by the web server. This includes, at a minimum, a Content-type header, but may also include Content-length, Content-disposition, or Location. Developers must also provide the client with an HTTP status code (e.g. 200, 404, 302, etc.).

You may use CGI.pm using object-oriented syntax or not. I prefer to use the object-oriented syntax because it means I'm in step with other Perl modules I employ in my code.


use CGI;

my $q = new CGI;
print   $q->header('text/html'),
        $start_html(    -title =>   'React' );

my $answer = $q->param('foo');
if($answer eq 'bar') {
    print $q->p("You answered correctly!");
}
else {
    print $q->p("That is incorrect.");
}

print $q->end_html;

This example generates different content based on the value of a form variable (foo) passed in. If this script were named react.cgi then it might be called with a URL like react.cgi?foo=bar.

Notice the code above uses the header() function to generate a valid HTTP header. There are many options you may pass to this function but if you pass one scalar string as in this example, it will use that data to generate a Content-type header.

The above above demonstrates some of CGI.pm's HTML-generation capabilities (the use of the p() function to generate paragraph tags around content and the use of the start_html() and end_html() functions to properly form the beginning and end of an HTML document and generate the necessary title tags in the header.)

The above example also shows how you may use CGI.pm to access form variables (the param() function).

For a couple years, I used CGI.pm quite heavily in my web development tasks. I grew very attached to its HTML-generation capabilities and the fact that if your HTML is generated from CGI.pm code, it will always be valid, start tags will always have matching end tags, and so forth. For example, here is a snippet of code I wrote circa 1999-2000:


print   $q->start_form(
           -method=> 'POST',
            -action => 'add_event.cgi'),
         $q->hidden({-name=>'r'}),
         $q->table(
            $q->Tr(
                $q->td(
                    _event_form($q)),
                $q->td({
                    -valign=>'top',
                    -align=>'left'}),
                    $q->submit({
                        -name=>'c',
                        -value=>'Save Event Info'}),
                    $q->br,
                        $q->submit({
                            -name=>'c',
                            -value=>'Cancel'}))),
         $q->end_form;

There are definite advantages to writing code this way, but the disadvantages are numerous, especially if you intend for your application to be maintained by someone other than yourself. If you intend to have a web designer who has no Perl competence work on the layout, this type of code will have them running away, screaming, and flailing their arms wildly.

That being said, if you need to throw together a simple, self-encapsulated interactive web page, doing everything with CGI.pm isn't a bad way to go.

In most cases, CGI.pm is already installed on your Linux system. To read all about it, type perldoc CGI at your shell command prompt, or go to http://search.cpan.org/perldoc?CGI with your favorite web browser.

What's next?

Well, what's next partly depends on the type of feedback I get from this post, if any. Generally, I plan to talk about templating, database interaction, and more. But, if people have some specific things they would like to see my spin on, I'd be more than happy to oblige.

Our good friend Jesse recently posted an article on his blog saying, "NOW is the time [for Perl] to step up!!!" Jesse mentioned a discussion going on inside the Ruby on Rails community in which at least one significant member expressed frustration with the lack of intelligent software architecture methodology put into Rails. I think he called other RoR contibutors "a bunch of half-trained PHP morons," which goes a long way -- in my book, anyway -- toward describing something akin to building an automobile out of toothpicks and rubber cement.

Jesse suggests this is the perfect time for Catalyst to make a entrance. I couldn't agree more.

Catalyst is a Perl web application development framework that compares, in some ways, to Ruby on Rails. Catalyst does a fine job of providing developers with a solid MVC framework for developing web applications, but I think what makes Catalyst so formidable is that it also leverages much of the excellent Perl code available from CPAN, the global distributed repository of reusable Perl component code.

Yeah, Catalyst is awesome. I'm thrilled to be using it for a project at work right now. That may come as a surprise to people who have heard me describe KnowledgeBlue as purely-Java shop, but the company is adapting to better exploit the skills available just as I am taking steps to learn more about Java development.

Catalyst needs a lot more (well-written) documentation. There is an excellent tutorial -- Catalyst::Manual::Tutorial -- that is distributed in POD format as part of the Catalyst::Manual package, but even after going through this tutorial, a Catalyst newbie is likely to still be doing some head scratching.

The tutorial is great, really. It walks through setting up a connection to a database backend with DBIx::Class, creating templates using the all-powerful Perl Template Toolkit, and using the Catalyst tools to magically provide authentication and program flow.

The problem, however, is that Catalyst, can do so much, it can be difficult to grasp how to do simple things. The complexity of deploying a simple application approaches what a JSP developer must do. The difference is that after a JSP developer edits several configuration, source, and HTML files, he or she has a simple web application that says "Hello World." The Catalyst developer might spend the same amount of time and end up with a "Hello World" application in a very extensible MVC framework. From there, it requires a minimal amount of work to extend the application, for example, to send its output in PDF format or to get its "Hello World" message from a web service.

In addition to wrapping your mind around all that Catalyst can do and how to do it is the large number of Perl packages you must install. This is less of a burden than it used to be because a lot of Linux distributions provide the fundamental packages necessary for Catalyst development like Catalyst::Runtime, Catalyst::Devel, and Catalyst::Manual, but to really develop kick-ass applications, you've still got to install other packages like HTML::FormFu, Template::Alloy, DBIx::Class, and others in addition to their corresponding Catalyst glue modules.

I think this blog posting may be the first in a long series of brain dumps on Catalyst. I hope I can make it easier for others to transition into Catalyst development.

Great news for Catalyst developers using Fedora 7 or Fedora Core 6 Linux distributions: Core Catalyst modules are NOW available in FC6 extras and F7 repositories!

Yes, it's true! Just do a yum install perl-Catalyst-Devel and BAM! You'll be taking web development to a new level while staying in the comfortable world of managable packages.

(Note: Thanks to redbeard2 for pointing out my stupid typo: "are not available.")



Dojo mojo

| No Comments | No TrackBacks

A couple evenings ago, I had to move some data around for a client. One of their Samba servers was overutilized and was running out of space while another was underutilized and had plenty of space -- more than enough to contain what was on the overutilized server and future growth. The plan was to swap the shares between the servers. The total data I needed to move around was about 300G. I knew, even with a gigabit network, that was going to take a while.

So, while I waited for the rsync process to proceed, I decided to walk myself through an open source JavaScript framework called Dojo.

Now, I should back up here. I've always been sort of anti-JavaScript. I've been witness too many times to what happens when someone designs security for an application using JavaScript and that security goes out the window when you simply turn off JavaScript in your web browser. I've always been a big proponent of "graceful degradation" and my use of JavaScript in web applications has been mostly cosmetic. If I ever developed anything using client-side scripting to add functionality to the application, I made sure there was some server-side logic to back it up in case script interpretation was not available on the client side.

Plus, I would always cite the mobile phone as my example of the user agent that could not process a web application that was JavaScript-heavy.

With all that said, I've started to see the light, so to speak, with regards to JavaScript. With so much of What's Cool on the Web being built using AJAX-type code and with mobile devices like smartphones coming out which support JavaScript, it is starting to make sense to me to get my feet wet and at least get in up to my knees.

A few weeks back, there was a thread posted on a Catalyst mailing list I subscribe to which posed the question of which JavaScript/AJAX framework was preferred by Catalyst developers.

(You can see the archived thread here.)

The answers list members gave included Dojo, jQuery, and the Yahoo! User Interface library.

When Matt Trout -- DBIx::Class and Catalyst guru -- indicated that Dojo was his preference, I made a mental note then and there to check it out.

In summary, it's very cool. I like that it seems to almost agree with the philosophy of graceful degradation. With the Dojo libraries loaded, you can decorate your forms with enhanced widgets simply by adding parameters to the HTML tags. For example, if you have a text field that asks for a date: <input type="text" name="date" />. Dojo lets you turn that into a fancy "select your date from this pop-up calendar" widget simply by adding a few parameters: <input type="text" name="date" dojoType="dijit.form.DateTextbox" />.

Now that's pretty dang cool.

I've been playing with the 0.9(beta) and 0.43 versions of Dojo. The documentation for 0.9 is pretty sparse at this point, but I'm impressed with what it can do.

The one thing I'm a bit disappointed that it can't do is visual effects many other frameworks support like drag and drop, element opacity tricks, etc. Maybe I just haven't run across it yet.

There does seem to be good support for abstracted AJAX functionality including interactive file uploads -- something many of the people I've done work for in the past have asked for.

Fozzout.

Installing Catalyst on a Fedora/RedHat system can be a challenge - especially if you insist on keeping all installed software manageable via RPM. This is because many of the packages required to run Catalyst are not available from any common repositories and therefore must be built as RPM packages.

Eventually, I believe these packages will either show up in fedora-extras or a new third-party repository will be created for Perl modules required by Catalyst that are provided neither by fedora-core or fedora-extras.

In the meantime, I've created a straightfoward shell script called catalystinstaller.sh that drives yum and cpan2rpm to install everything you need to get a good start developing Catalyst apps on a Fedora Core 6 system.

I'm aware of one problem with this script, so far. When building Catalyst::Runtime. the module's configuration routines complain that the optional package Catalyst::Engine::Apache is not installed. It appears to want version 1.05 which is an older version than what is currently available. The currently available version is installed by this point in the process. So, just hit ENTER when it asks if you want to install it (the default is No).

This is a first release (v0.01). Run at your own risk. Please report any issues you run across and, of course, any suggestions you come up with.

I would love to set up a yum repository for these packages that are not available yet in the standard repositories, so, if someone wants to help with that project, please let me know. The hard part won't be setting up the repository, but keeping packages up to date.

Interested parties can download the catalystinstaller.sh script here.

I thought I'd share a short demonstration of some very cool Perl technology.

About a week ago, I got back from taking my family on a short vacation to beautiful southern Utah. I documented our trip and posted copies of a few photos we took in the Events section of my website. You can read the Sept. Mini-Vacation page yourself.

In the past, when preparing images for publication on the web, I've either hand-coded the HTML -- usually a mess of table elements -- or I've used a homegrown shell script called buildgallery.sh that generates the HTML table code around a set of images. After generating the scaffolding of tabl code for the image organization, I'd go in and populate various cells with image captions, descriptions, and links to different sizes.

This works, but tables are ugly. CSS-only presentation is so much more elegant. Plus, it'd be better if I didn't have to jump around the HTML to populate the caption and description text for all the images.

Perl to the rescue!

I'm already using the Perl Template Toolkit to generate static pages for each page on my website. I use the ttree command at the command line on my staging server to generate the pages by "wrapping" the main content.

Since the page about our southern Utah vacation was just being fed to a template processing engine to generate a resulting HTML file, it made sense to use the power of the Perl Template Toolkit to generate the HTML around my gallery of images.

By the time I've gotten to this point, I've already run a shell script that uses ImageMagick's, uhm, magic, to create sensibly-sized thumbnail and web-friendly sized versions of each image. Those images are stored in files with .med and .thumb in the names before the filename extension.

For each group of images, I declared a data structure called images which is essentially an anonymous list of anonymous hashes. Each anonymous hash contains information about an image such as the base filename, image dimensions, title, and description text.

[% images = [
    {   basename    => "fiesta_fun-all_3-2",
        width       => 156,
        height      => 117,
        title       => "Our kids driving the kiddie-carts",
        description => "Maya, Lucy, and Eli on the kiddie-carts course."},
    {   basename    => "fiesta_fun-lucy_eli-4",
        width       => 156,
        height      => 117,
        title       => "Lucy and Eli",
        description => "Lucy and Eli on the kiddie-carts course."} ] %]

For those unfamiliar with the Perl Template Toolkit syntax, it is similar (but not too similar ;-)) to PHP or ASP in that template code can be embedded with HTML as long as each piece of template code begins with [% and ends with %]. This is, of course, overrideable -- You can change those start/end sequences to anything you want.

Next, I declared a block called doimage which takes one set of information about an image -- one hash from our list of hashes -- and generates HTML for it.

This BLOCK section only needs to be declared once in the file and could be placed in its own file for re-use later, if I chose to do so.

[% BLOCK doimage %]
    [% DEFAULT img_path = "images" %]
        <div class="picture">
            <div class="imagecontainer">
                <a href="[% img_path %]/[% img.basename %].med.jpg" target="_new">
                    <img width="[% img.width %]" height="[% img.height %]" 
                    src="[% img_path %]/[% img.basename %].thumb.jpg"
                    alt="[% img.title %]" 
                    title="[% img.title %]"/></a>
            </div>
            <div class="textcontainer">
                <div class="picture_caption">[% img.title %]</div>
                [% IF img.description %]
                <div class="picture_description">[% img.description %]</div>
                [% END %]
            </div>
            <div class="floatbreak"></div>
        </div>
[% END %]

It should be pretty obvious by looking at the code (unless you're reading from an RSS feed of this document, in which case, the above example will be all messed up) how the values of the individual hash elements are interpolated into the HTML.

Next, I need to loop through all the images by iterating through the list of hashes I declared earlier. For each one of these hashes, I want to process the information in the hash using the block I declared.

[% FOREACH img = images %]
     [% PROCESS doimage img_path = "images" %]
[% END %]

Finally, I dressed up the HTML by adding some properties to the stylesheet:

.picture {
margin: 5px;
margin-left: 20px;
border: solid #aaa 1px;
}
.imagecontainer {
text-align: center;
float: left;
width: 170px;
}
.picture img {
margin: 5px;
}
.textcontainer {
margin-left: 200px;
}
.textcontainer .picture_caption {
font-family: sans-serif;
font-size: large;
font-weight: bold;
}
.textcontainer .picture_description {
font-family: sans-serif;
font-size: medium;
font-weight: medium;
}
.floatbreak {
clear: both;
height: 0;
}

(A big shout-out of kudos to Tene for helping me with that CSS.)

In summary, I don't think I'll be using any shell scripts to build HTML table scaffolding around my simple image galleries anymore.

I've already thought of some ways to improve upon this. For example, I could use the Perl Template Toolkit's Image plugin to examine each image file and automagically extract information such as image dimensions, EXIF data, etc. as it iterates over the list of image information.

I've been so busy lately, but tonight I took some time to get caught up on the Utah Open Source Planet and, I must say, there was lots of good stuff to read. Thanks to y'all sharing your knowledge. You rock.

I thought I'd pick on one of my favorite UOSSP bloggers, Aaron Toponce, but not in a negative way. I read his semi-recent entry about using HTML entities to obfuscate web site data in an attempt to foil robots -- particularly robots intent on harvesting e-mail addresses and other information.

Some years ago, I implemented this technique on several sites, personal and professional. It seemed to make sense the average spammer/data-harvester, was not going to implement the code necessary to de-entity-ize the content in search of e-mail addresses. In retrospect, however, I think that's a poor assumption.

See, spammers have money and they give their money to poor souls who will write code for money and, in many cases, have the smarts to pull it off. So, semi-smart coders tasked with maximizing the pool of e-mail addresses gleamed from a vast array of websites will very quickly implement techniques to foil the simplest of data obfuscation techniques. Converting text to HTML entities has got to be one of the first obfuscation techniques they are faced with circumventing.

After that, they probably implement simple OCR techniques to gleam data from sites that convert all their e-mail addresses into text rendered as image files.

That said, this HTML entity-based obfuscation technique is better than nothing, right? Because spammers like their pools of e-mail addresses to be fresh, it usually only takes a couple of weeks to see if any anti-spam technique results in a significant reduction of incoming spam, so it's easy to verify your technique is working. When we implemented the HTML-entity based obfuscation technique, there was a decrease in the amount of spam, but there was still plenty of spam.

If you're interested in playing with ways of automating the process of converting text data to a string of HTML entities, check out the HTML::Entities Perl module -- part of the comprehensive HTML::Parser distribution of modules.

Once you have this installed, you can do something like this:

perl -MHTML::Entities -ne 'print encode_entities($_, "\32-\255")'

For the Perl head-scratchers, this is a one-liner that loads the HTML::Entities module, wraps a loop around reading from STDIN or a filename parameter, and prints the result of the encode_entities() function call for each line of input read. Hit Control+D to get out of it.

[foo] /home/fozz 19 % perl -MHTML::Entities \
-ne 'print encode_entities($_, "\32-\255")'
Aaron Toponce
&#65;&#97;&#114;&#111;&#110;&#32;&#84;&#111;&#112;&#111;&#110;&#99;&#101;

When it was clear the HTML entity-based obfuscation simply did not have what it takes to win against increasingly smart harvesting bots, we deployed a CAPTCHA solution using the Authen::Captcha Perl module for our clients that really needed/wanted to publish e-mail addresses on their websites. This solution has worked out much better and, paired with educating users about the risks of leaving your e-mail address on websites, we've seen more significant decreases of incoming spam.

I've got brand new blogging software up on my site now. I guess we'll call it Fozzolog 1.99. It seems to be working pretty well. The only issue that has arisen is that the change in RSS propogation has caused the Utah Open Source Planet to include all of the most recent 25 entries in their aggregation. Fun.

I've also put up a new site design and this one is completely table-free. All the layout is done with positional CSS and seems to be pretty cross-browser friendly.

I'm using the original content from my old site throughout, so there are still some tables littered about, but the general layout -- the "wrapping", if you will -- is all CSS. The design is based on one I saw on the openwebdesign.org site called A20. I changed the color scheme and tweaked some of the components, but it's still largely intact.

It takes a lot of work to produce a truly functional table-free design and I applaud the folks who put forth the effort to do it.

About this Archive

This page is an archive of recent entries in the Web design/development category.

Video is the previous category.

Work is the next category.

Find recent content on the main index or look in the archives to find all content.