Getting PHP to make the HTML for me
by Derek Sivers
Now that I'm making my own HTML template system, I realize what I need are functions, as if built into PHP, that will do some basic HTML markup of strings.
h1, h2, h3, h4, h5
p div span
dl dd dt
table tr td
code address pre blockquote
form input select option label
All of those tags can (and will often) have one or more these attributes:
Also, image and a href have their own special targets. And forms have their own special attributes.
OH NO! IT'S NOT AN OBJECT!:
Somewhere in Ruby-love I got it in my head that everything should be an object.
But what I want here are functions that returns a result:
div('hello') = <div>hello</div>
div('hello', 'id', 'greeting') = <div id="greeting">hello</div>
PHP already has a bunch of these under "String Functions". Some great ones are:
htmlentities('"you & me"') = "you & me"
strip_tags('<a href="me.html">me</a>') = me
strtoupper('hello') = HELLO
So there we go. If I could alter the language itself to add these functions, I would. (Yes OK I know I could write modules in C to expand PHP, but I'd hate for someone else to have to maintain or debug that.)
So I think the best thing is to write a library of string-altering functions.
HOW TO DO ATTRIBUTES, THOUGH?
How to do the attributes, though? The best way I've ever seen is PHP's XML DOM class:
$track = $tracks->new_child('amount', 10) = <amount>10</amount>
$track = $tracks->new_child('amount', 10);
$track->set_attribute('currency', 'USD') = <amount currency="USD">10</amount>
If I were to do that with HTML-markup objects, it'd have to look like this, though:
$x = $html->div('hello');
= <div id="greeting" title="welcome">hello</div>
Hmmmmmmmmm......... That's not very elegant for use in a hundred places on an HTML page.
What if attribute() was also a string-altering function that uses a little regex to add an attribute to the first HTML tag it sees?
$plaindiv = div('hello') = <div>hello</div>
$div_plus_class = attribute($plaindiv, 'class', 'greeting') = <div class="greeting">hello</div>
attribute($div_plus_class, 'title', 'welcome') = <div title="welcome" class="greeting">hello</div>
Ooh! The nice thing about this is that I could use, say, a table-making function, to get me back a table:
$mytable = table($bigarray);
... then add an id to the table afterwards like this:
attribute($mytable, 'id', 'sales') = <table id="sales"><tr><td>etc...</td></tr></table>
Yeah I'm diggin' this.
Holy shit I just went to go test this idea and it took only 30 seconds, and seems to work!
# regex to add an attribute to an HTML opening tag
function attribute($html, $key, $value)
$pattern = '/^<(\w+)/ ';
$replace = '<$1 ' . $key . '="' . $value . '"';
return preg_replace($pattern, $replace, trim($html));
useful prior art
Your system sounds similar to Donovan Preston's Nevow.Stan HTML generator (part of his Nevow templating system for Python). Here's a link if you want to compare for ideas:
derek your driven
don't forget validation
I've been thinking about the same path, although a more limited tool for making forms for me. Something to not forget is client and server side validation, the form making script may as well make that stuff too. Coldfusion has had some of this stuff for a while now with its cfform tags.
As a musician/programmer, let me suggest the deceptively simple yet wonderfully effective PHP template class found in the PHPLIB package (file: template.inc). Goto: http://phplib.sourceforge.net/
Thanks for the comments - please see next post first, though.
Thanks for your comments, everyone. They made me realize that I wasn't explaining myself well.