Welcome to infinite expanse, the web site of Jim Benton.

Two at a time: Two column body text in Textpattern

May 10, 14:12

Update

There is now a newer version of the plugin available. Details. Download.

As I was saying…

I’ve been trying to figure out how to utilize a two-column layout for body text on the web for longer than I can remember. It’s a simple thing to do, really, just make two divs, put half the text in each one, and float both to the left. Sounds rather easyemdash; mostly because it is. All one needs to know is how much text he has to deal with so he can divide it equally between the two layout divs.

We need flexibility

But what if the site in question is to run on top of some sort of backend software, such as a blog engine or other CMS. Then the article length is variable, and as such, dividing the content manually is no longer an option.

This poses quite a problem, one that I had so far been unable to overcome.

Today I found some needed inspiration at Daniel Mall’s site through a link at Mr. Maria’s. He had sucessfully employed a two column layout, and I was jealous. This lasted only for a minute, though, and I soon went to work figuring out how the heck he did what he did. I wanted to be able to do it too.

I hacked away at the CSS using the requisite Firefox Web Developer extension to no avail. I found definitions for ‘leftcolumn’, but it was nowhere to be found in the html! What was going on here? I had to look deeper.

After a little more poking (I apologize for my nosiness Mr. Mall), I discovered that he had utilized a rather clever JavaScript to create his columns. His function counted the number of paragraph tags in the ‘content’ div and then divided them between two separate divs. These new containers had CSS definitions ready and waiting for them, floating the first beautifully to the left. All in all, a rather elegant solution.

To Script, or not to Script

My only qualm was that client-side scripting is needed to preserve a layout. And while ‘most’ people are browsing with scripting turned on in their browser (I saw a somewhat recent study that listed 90%, but such numbers are highly subjective), it still bothered me that the work had to be done by the web browser. Wasn’t there a way to have the columnizing done on the server, so that scripting availability became a non-issue?

I noticed that Mr. Mall uses TextPattern, which means that his site runs on PHP. Which means that it would be fairly trivial to write some simple PHP to perform the same task as his JavaScript.

Here it is, in zygote form:


<?php
function columnize($article) {

    // find length of article and halves
    $halfway = strlen($article)/2;

    // find next paragraph tag starting after halfway point
    // we always want the left column to be the bigger of the two
    // adding 3 compensates for the length of the string we are looking for: '</p>'
    $nextP = strpos($article, '</p>', $halfway) + 3;

    // build left column
    $leftCol = '<div id="leftCol">';
    $leftCol .= substr($article, 0, $nextP);
    $leftCol .= '</div><!-<del>leftCol</del>->' . "n";

    // build right column
    $rightCol = '<div id="rightCol">';
    $rightCol .= substr($article, $nextP+1);
    $rightCol .= '</div><!-<del>rightCol</del>->' . "n";

    // return assembled html
    return $leftCol . $rightCol;
}
?>

This function takes any string of formatted HTML and splits it between two divs, aptly called ‘leftCol’ and ‘rightCol’. The division occurs just following the next closing paragraph tag following the calculated halfway point. This was easy— the harder part was getting this function into TextPattern, and having it run only on certain articles. This called for a plug-in.

So I made one. Enter jcb_columnize_body, which is a drop in replacement for <txp:body />. The plug in simply runs the body html through the function shown above. The first version only allows for two columns, but I will add the ability to use a user-configurable number in the next release if there is a need for it, along with any other features that I come up with. I’d also like to make the halving engine smarter; right now it chokes on really short articles, producing a page that seems uneven.

The choice is Yours

So now that it is possible to easily add multiple column body text to a webpage, the issue of its effect on usability remains. I’m not convinced that the traditional multiple-column layout, which was a solution to the problem of reading large amounts of text on paper, translates so well to the screen. Particularly if one must scroll back up to the top of a page to begin the next column when reading. But it is something I’ve wanted to do for a while, and thanks to Mr. Mall’s site I have figured out one way to accomplish it. At least one that works for me.