Tuesday, February 05, 2008
Stone knives and bear skins
I'm endeavouring, Ma'am, to construct a mnemonic memory circuit using stone-knives and bear-skins.
Mr. Spock to Edith Keeler,“The City On the Edge of Forever.”
Progress is being made on the PHP project, which I'll call “Project Leaflet,” in the tradition of giving pseudoanonymous names to projects I'm working on that are related to the actual project name, but the current development tools I'm using feel very much like stone-knives and bear-skins.
The major problem is keeping a separation of logic, layout and language (hey! The Three-Ls of web programming!) in any web-centric programming language (or heck, any language that's used to write web-centric applications).
It's based on an abandoned PHP application which I'm currently cleaning
up, which right now involves removing the existing
<TABLE>
based layout and using simpler HTML (and using CSS to control the look-and-feel).
This is making the codebase easier to follow and giving me a chance to get a
feel for the code.
The language part has already been separated out, and while it's a solution, I don't feel it's a great (or even good) solution, but it works. There's one file with all the possible text to appear in a page, like:
<?php $lang = array(); $lang['yes'] = 'Yes'; $lang['no'] = 'No'; $lang['select_all'] = 'Select All & Copy to Clipboard'; $lang['error'] = 'Error'; $lang['error_reason'] = "I'm sorry Dave, I'm afraid I can't do that."; ?>
And then in the actual template (such as it is):
<h3><?php echo $lang['error'];?></h3> <p><?php echo $lang['error_reason'];?></p>
Annoying, yes, but at least it allows one to translate the text to another language like German, without having to change the layout:
<?php $lang = array(); $lang['yes'] = 'Ja'; $lang['no'] = 'Nein'; $lang['select_all'] = 'Wählen Sie alle und copy zum Klemmbrett vor'; $lang['error'] = 'Störung'; $lang['error_reason'] = "Ich bin traurig, Siegfried, ich Angst haben, daß ich nicht den tun kann.'; ?>
But the major problem I'm now encountering is a clean separation of logic and layout. In the cleanup, although I've managed to isolate large portions of logic and layout (usually within a single function) there are still times when it's not quite that clean, such as:
<form action="foo.php" method="post"> <fieldset> <legend><?php echo $lang['frobulator'];?></legend> <label for="models"><?php echo $lang['frobulator-models'];?></label> <select id="models" name="models"> <?php $query = "SELECT id,descr FROM frobulator_models ORDER BY descr ASC"; $result = mysql_query($query) or die_a_horrible_death(); while ($list = mysql_fetch_object($result)) { echo '<option value="' . $list->id . '">' . $list->descr . '</option>' . "\n"; // Yes, for some reason, you need } // to mark EOLN this way in PHP ?> </select> </fieldset> <!-- rest of form --> </form>
Frankly, it's quite ugly. But even worse, if this ever goes
open source, and we start taking patches from the greater open-source-using
community, it gets even worse. I'm keeping the HTML very simple right now, but that doesn't mean
that someone else might not very well want to use a
<TABLE>
based layout for forms and change the code
accordingly. So they change the HTML. They then find a bug in the actual logic portion
of the code, make a diff of the patch and … oh … I get not only the
patched logic code, but all the patched layout code as well, which I don't
want.
Or, they apply the patch to not only their version, but a clean copy of the distribution (twice the work on their part). And that's assuming I'm using the clean, distribution code and haven't modified it for local use for this site. And this site. And this other site. And …
That's why I dislike mixing the logic, layout and language. Ideally, I'd have a clean separation of the three.
But what really motivated me to write this today (I've been working on this for a few weeks now) was the tedium of cleaning up one of the files, which consists of about a thousand lines of PHP code that displays and processes about a dozen different “pages” in logic that goes like:
if ($_POST['action'] == 'edit) { // a dozen lines of PHP and HTML } elseif ($_GET['action'] == 'edit') { // four dozen lines of PHP and HTML } elseif ($_POST['action'] == 'search') { // a bazillion lines of PHP and HTML, all alike } elseif ($_GET['action'] == 'add') { // God, doesn't this file EVER end? } elseif ($_POST['action'] == 'remove') { // AAAAAAAAAAAAaaaaaaaaaaaaaaaah } elseif ...
With each block of code containing both logic and layout.
I know what I want, an intelligent IDE that works how I want it to work, not somebody else's idea of what they think I want. Something that knows the difference between the logic, layout and language for each function, and can track each separately and with very fine grained revision control—not only on a function-by-function basis, but on a logic/layout/language basis per each function.
Oh, and everybody who works on this project to use the same IDE, so I can manage the patches that come in, say, to accept any logic and language patches, but ignore all layout patches.
But currently, I'm stuck using stone-knives and bear-skins.