PHP Template Engine Intro
[email protected] (Andrei Zmievski)
| Newsgroups | php.template |
|---|---|
| Message-ID | <[email protected]> |
PHP Template Engine ------------------- It is undoubtedly one of the mosted asked questions on the PHP mailing lists: how do I make my PHP scripts independent of the layout? While PHP is billed as "HTML embedded scripting language", after writing a couple of projects that mixed PHP and HTML freely one comes up with the idea that separation of form and content is a Good Thing [TM]. In addition, in some companies the roles of layout designer and programmer are Consequently, the search for a templating solution ensues. Most of the time these souls are pointed to the FastTemplate. It provides a way to substitute variables into the template and do a limited form of dynamic block functionality. Unsatisfied with this, I wrote a class called SmartTemplate which, aside from regular variable substitution, supported including other templates, integration with config files, embedding PHP code, limited 'if' statement functionality and much more robust dynamic blocks which could be multiply nested. It did all this with regular expressions and the code turned out to be rather, shall we say, impenetrable. Ever since I've wanted to build a template engine directly into PHP. The desire for this is twofold. Firstly, having it in PHP itself means that we can make it very fast without relying on regular expressions. Secondly, it would provide immediate support for include statement, embedded PHP code evaluation, possible support for compiled and cached templates in the future, and other benefits. In our company, for example, the development of an application goes on as follows. After the requirements docs are done, the interface designer makes mockups of the interface and gives them to the programmer. The programmer implements business logic in PHP and uses interface mockups to create skeleton templates. The project is then handed off to the HTML designer/web page layout person who brings the templates up to their full glory. The project may go back and forth between programming/HTML a couple of times. Thus, it's important to have good template support because programmers don't want anything to do with HTML and don't want HTML designers mucking around with PHP code, and designers need support for config files, dynamic blocks and other stuff, but they don't want to touch the PHP code. With all this in mind, I am at a point where I can start the development of the PHP templating solution, but I need your help. I have a fairly good idea of how it will function and what the template syntax would be, but perhaps there are better ideas floating out there that have never been discussed in public. I've created a mailing list that you can subscribe to by sending e-mail to [email protected]. Please read the following short design document and let's start talking about how to make PHP templates rock. --------------------------------------------- Template Language ----------------- The templates would consist of straight HTML interspersed with template language commands. The commands are enclosed between { and } characters. {<variable>} - prints out the value of the variable {%<variable>} - prints out the value of the configuration variable {# ... #} - comment, does not show up in PHP, does not show up in HTML {%xx} - prints out ASCII character specified by xx (mostly to support putting { and } in the HTML directly. {config: <file> [: <section>]} - loads globals settins from config file, optionally loading values from specified section {dynamic: <name>} ... {/dynamic} - defines a dynamic block that can be optionally parsed or looped PHP Template interface ---------------------- resource tpl_load(string tpl_name [, path_to_templates [, string path_to_configs]]) - loads a template and performs initial parsing which includes replacing the config variables with their values, stripping comments, and printing out {%..} constructs. void tpl_assign(resource tpl, string varname, mixed value) - assigns the value to the specified template variable void tpl_assign(resource tpl, array vars) - assigns key/values of array as template variable names and values void tpl_parse_dynamic(resource tpl, string block [, bool append]) - parses a dynamic block optionally appending the result to the previous parsed result void tpl_clear_dynamic(resource tpl, string block) - clears the previously parsed contents of the dynamic block void tpl_parse(resource tpl) - parse the template, substituting the variables string tpl_fetch(resource tpl) - returns the parsed contents of the template which should be straight HTML Some other possible ones that come to mind: tpl_unset_var(resource tpl, string varname) - unset template variable tpl_unset_conf_var(resource tpl, string confvarname) - unset template config variable If there are nested dynamic blocks, then the parsing should proceed from the innermost block to the outermost. If the parent block is parsed before the child one, then the contents of the child block within the parent one would be empty. If the top template file loads config var TITLE, for example, and the included template loads TITLE from another section of config file, then it will be valid only in the scope of the included template. Basically, the config vars in the included templates override the config vars inherited from the parent template, but only within their scope. Another sticky issue is whether the parsed contents of the child block should be automatically cleared once the parent block is parsed. Maybe path_to_templats, path_to_configs should be .ini settings. Sometimes there are also situations where you want to show either one or the other dynamic block, for example, when doing search they may or may not be search results. With the proposed interface you'd have to define two dynamic blocks on the same level and then parse either one or the other. The unparsed one simply wouldn't show. I will probably also write an extension for dealing with config files in PHP. Something like config_load() which can be used to load global config vars or a section. I know this interface mostly resembles FastTemplates, but that's why I'd like to have a good discussion on how templates should work in PHP. Maybe there's a better way to do dynamic blocks. Maybe config file integration can be different. Let's brainstorm, but keep in mind that HTML designers will need to use this as well, not just the programmers. With this in mind, I'm going to invite one of our HTML designers to be on the list and if you want to bring more, go ahead. Cheers, -Andrei