I’m on vacation this week and next week. Since I rarely have time to learn anything technical (or blog for that matter anymore), I thought I would take some time during my time off to learn something new around development.
We have a system at work that is essentially a small portal. The core of it was written by me to learn PHP about 8 years ago and has been augmented by me and one other guy at workKeith and I over the years. Over that time, as we added new functionality to it, I used it to experiment with other languages as I was learning it. Other pieces were written in Java out of convenience. In total, we have pieces written in PHP, Java, Python, and PERL.
As I usually use this system to learn new things, I figured it would be a good candidate to use to learn how to use the Smarty templating system for PHP. I became interested in this templating system after working with Eventum over the last few weeks and figured that if I am going to do further work with Eventum, it would be helpful to understand the templating framework it uses.
So I’ve started using the system to take our 8 year old PHP code base and separate some of the presentation logic out. Smarty is pretty flexible and easy to use at a high level (I haven’t gotten into any of the really advanced stuff yet).
Here’s an example of how nicely the use of a templating system simplifies your code. Take this example, which enumerated entries from our internal wiki via an RSS feed into a section on the home page:
function getWikiEntries($url) {
$theHTML = "";
$rss = fetch_rss($url);
$theHTML .= "
"; $theHTML .= "";# foreach over each item in the array.
# displaying simple links$rowCount = 0;
$className = "modifications-evenrow";foreach ($rss->items as $item ) {if (($rowCount % 2) == 0) {
$theHTML .= " "; } $theHTML .= "# truncate item title to 28 characters
$myTitle = $item['title'];if (strlen($myTitle) > 28 ) {
$myTitle = substr($myTitle, 0, 28) . " ...";
}$theHTML .= $myTitle;
if (($rowCount % 2) == 0) {
$theHTML .= " ";
} else {
$theHTML .= "";
}
$rowCount++;if ($rowCount == 20):
break;
endif;
}$theHTML .= "
<table cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<th class="header-title" colspan="2">"; # get the channel title and link properties off of the rss object # $title = "Recent Wiki Entries"; $link = $rss->channel['link']; #$theHTML .= "$title"; $theHTML .= "$title <a href="$url"><img alt="" border="0" />"; $theHTML .= "</th>
</tr>
</tbody>
</table>
<table cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<td class="modifications-sectionheader" colspan="2"></td>
<td class="modifications-data">"; $theHTML .= "<a title="" href="$item[link]">";</a></td>
</tr>
</tbody>
</table>
"; return($theHTML); }
I’m sure you can appreciate how hard this would be to maintain, and all of the cruft that has accumulated over the years …
Now take the simplified version (sans error checking), written today in about 10 minutes:
function getWikiEntries($url) {
$rss = fetch_rss($url);
$template = new TemplateEngine();
$firstColumn = array_slice($rss->items, 0, 10);
$secondColumn= array_slice($rss->items, 10);
$template->assign("firstColumn", $firstColumn);
$template->assign("secondColumn", $secondColumn);
$template->assign("link", $rss->channel['link']);
return($template->renderString("wikiEntries.tpl"));
}
… along with its corresponding Smarty template:
{section name="entries" loop="$firstColumn"}{/section}
<a title="{$secondColumn[entries].title}" href="{$secondColumn[entries].link}">{$secondColumn[entries].title}</a>
<table width="80%" cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<th class="header-title" colspan="2">Recent Wiki Entries <a href="{$link}"><img src="{$applicationURL}/images/rss.png" alt="" border="0" />
</tr>
<tr>
<td class="modifications-sectionheader" colspan="2"></td>
<td class="modifications-data"><a title="{$firstColumn[entries].title}" href="{$firstColumn[entries].link}">{$firstColumn[entries].title|truncate:28:" ..."}</a></td>
</tr>
</tbody>
</table>
I don’t know about you, but I think thats quite a difference in maintainability. I’d much rather modify the html in the template than in the original function. Not only that, but the code is actually code, not a bunch of code with a lot of simply horrid markup stuck in the middle of everything.
I’m pretty impressed with how much I’ve been able to use in a short amount of time this week. The libraries are obviously thought out and ramp up time for me was really minimal. I like libraries like that. It also addresses something that has annoyed me for a long time. Embedded HTML is a pain to maintain and I’ve dreaded going into this over the years just because of that.
At some point, I’ll investigate what it takes to write custom plugins, a functionality that the libraries also support.
I think I’ve been able to get a really good start at getting something maintainable. My goal over the next few of weeks is to templatize the whole system, then start taking the non-PHP pieces of the system and rewrite them in PHP. I’ll also add the ability to change configuration in one place, so that we can cut some of the pain that we have in keeping things maintained down – and perhaps be able to install the application in other places.
Should be fun. I’m definitely feeling productive over the past few days. I’ve always liked working in PHP over other languages. I definitely have to do work like this more often.
As the other person who maintained this software I must, however, disagree that Java was used as a convenience. It may have seemed so to you (you’ve always maintained the language takes too many lines of code to get things done), but for me, it was also a learning experience into parts of the Java world of which I had little first hand knowledge.
That being said, this is really, really cool! It cleans up the ‘bad’ code that’s in place and make it much cleaner and easier to maintain. I look forward to the changes coming in the future, even if it means having my code contributions getting thrown to the curb, er, I mean replaced! ;-P
See, you learn something new every day. I thought you already knew everything about Java, and that Java was used to get things up quickly.
Go figure, Keith needs to learn too! 😉
As far as things being “kicked to the side”, you are MORE than welcome to participate and contribute your ass off, as you always do.