After the initial idea on possibilities of PHP metaprogramming with templates, I pondered quite a bit on the subject. The thing is, I'm not too keen on template languages for a number of reasons - most of them being aptly disclosed in the comment thread by this guy (e):
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.
Generally, I agree with every single word. However, I wondered if being much less expressive is exactly the reason why the template languages can be useful in a particular context - more precisely, could a small, simple project (a couple of pages in size) benefit from such a solution?
Using a full- blown framework is an overkill for such a project. Apart from inevitable execution speed compromises, you don't gain much in speed and ease of development either - you still have to write all your controllers, models and views, which is 3 times the number of spaghetti scripts you'd do. On the flip side, this way you at least have a maintainable application - revisiting spaghetti code can be a real pain.
That's where code generation from a template might come into play. It could provide at least some much needed project structuring, alleviate the common tasks (e.g. setting up the database, fetching and looping through results, stuff like that) and shift the development focus towards the UI1. Also, you never, ever touch the generated spaghetti code.
Anyway, that was the theoretical reasoning I decided to inquire. After some trial and error, I made a parser for an XML - based language, slightly resembling the new Blogger template language. Specifically, there are
loop tags for iterating through arrays, function/method results or database results (which one is generated depending on the attributes provided),
data tags for echoing variables and/or function/method results,
fetch tags for fetching single database results,
set tags for setting variables,
else tags for... well, branching.
For generic tag case,
expr: attribute name prefix indicates echoing result of the expression in the attribute value. Also, there are
var: attribute value prefix that denotes a variable, and
data: attribute value prefix that denotes echoing a variable - either one can appear anywhere in the attribute value.
Anything that exceeds these simple commands should go in action files (auto-included if present) - a global
actions.php, plus a specific
*_actions.php for every template file. For an example, that is where all the function and class definitions go.
My primary goal was to come up with a language that's simple and restrictive enough to facilitate the common tasks and enforce some code separation, without loosing too much in expressiveness. I feel I'm still not there yet, though things look better with every iteration. I haven't give much thought to generated project infrastructure just yet, but that's the next thing on my list. For an example, generated scripts are the user entry points right now (the old scripting standard -
blah.php you request,
blah.php you're gonna get). However, it may be better to move them away from the webroot and have a single entry point (a single
index.php, dispatching the user requests to particular scripts). Among other things, that way it would be easier to set up "clean" URLs. On the other hand, that may seem a bit too much for the targeted scope.
While the last one might sound irrelevant to some, I learned that UI is one of most important aspects of a project, especially a small- scale one. Making an efficient UI is just as important as efficient backend processing, and easily becomes the most important part when there isn't much backend processing to begin with, as is often the case in small projects. ↩