2007-05-31

PHP spaghetti

Last couple of days I've been toying with the idea of XML template-based metaprogramming. Essentially, the idea is to create a simple HTML page with some namespaced XML template elements (similar to Blogger new layout tags) that would compile down to plain old PHP spaghetti before deploying. In other words, to have something like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:tpl='http://malatestapunk-stuff.blogspot.com'  
      xml:lang="en" 
      lang="en">
    <tpl:set data="a_variable" value="a value" />
    <tpl:set data="another_variable" action="FunctionName('arg1', 'arg2')" />

    <tpl:if cond="data:a_variable == data:another_variable">
        <tpl:data source="YetAnotherVarFromIncludedFile" />
    </tpl:if>

    <head>
        <title><tpl:fetch source="TableArticles" data="Title" cond="id=1" /></title>
    </head>
    <body>
        <tpl:loop source="TableArticles" cond="author='anyone'" as="Article">
            <li>
                <strong><tpl:data source="Article/Title" /></strong>
                <em><tpl:data source="Article/Author" /></em>

                <p> <tpl:data source="Article/Body" action="ClassName::methodName('arg2', 'arg3')" /> </p>

                <p> <tpl:data action="Solo" /> </p>
            </li>
        </tpl:loop>
    </body>
</html>

turned into something like this:

<?php
include ('config.php');
include ('actions.php');
$link = mysql_connect(DATABASE_HOST, DATABASE_USERNAME, DATABASE_PASSWORD);
mysql_select_db(DATABASE_NAME);
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:tpl="http://malatestapunk-stuff.blogspot.com" xml:lang="en" lang="en">
    <?php $a_variable = 'a value';  $another_variable = FunctionName('arg1', 'arg2');  if ($a_variable == $another_variable) {  echo $YetAnotherVarFromIncludedFile;  } ?>

    <head>
        <title><?php 
$_db_result = mysql_query("SELECT Title FROM " . TABLE_PREFIX . "TableArticles WHERE id=1");
$Title = mysql_fetch_array($_db_result, MYSQL_NUM);
echo $Title [0];
?></title>

    </head>

    <body>
        <?php 
$_db_result = mysql_query("SELECT * FROM " . TABLE_PREFIX . "TableArticles WHERE author='anyone'");
while ($Article = mysql_fetch_array($_db_result, MYSQL_ASSOC)) {
?>
            <li>
                <strong><?php echo $Article['Title']; ?></strong>, by
                <em><?php echo $Article['Author']; ?></em> said:
                <p><?php echo ClassName::methodName($Article['Body'], 'arg2', 'arg3'); ?></p>
                <p><?php echo Solo(); ?></p>
            </li>
        <?php } ?>
    </body>
</html>

before deploying it on the server.

Reasoning

While this approach may not be good enough for any serious stuff, if all you need is to get some data from the database and massage it into some XHTML (which is very often the case), it can be a fast and easy way out. By altering only templates, you keep your code/logic separate from your presentation, which is, of course, very important. However, when compiled to a script (which could easily be done either locally - say with make or a similar tool - or server-side) and deployed to a server, it most likely will outperform a more robust solution because of it's specific scope and thus, a smaller footprint.

Another advantage would be simplified RDBMS switching by extending the main parser class and rebuilding the page scripts, without the added overhead of introducing a database abstraction layer to the script itself. And, compared to working with a full-blown framework, this approach allows for a much shorter development cycle, which is kinda cool for rapid prototyping.

2 comments:

  1. It looks like you're falling down the template-language rabbit hole. Template languages are nice, but they are never as expressive as the language that are implemented in. Perhaps more importantly, they're harder to learn, and have much less documentation, meaning that any poor sap that has to maintain your templated solution is in for a world of hurt.

    ReplyDelete
  2. Thanks for your thoughts. I totally agree with you about template languages being less expressive then the language they're implemented in, as well as being much less documented. Usually, I'm not too big on template languages myself.

    However, I was wondering if, when used in a specific scope (say, to produce a simple one- or two- page script - a task that won't really benefit from using a full-blown framework, ready-made or home-grown), this approach may have offered some structuring and improved code readability, compared to the "old school style" of PHP scripting.

    I emphasize the "may" part. I just implemented the most basic version (the working mock), and I've yet to try it on a couple of times before I draw any further conclusions.

    ReplyDelete