mplate syntax
There are two kinds of mplate operations, functions and expressions. By default, both are enclosed by curly braces.
Expressions and variables
An expression can be any PHP expression that doesn’t look like a function. As such, {$var} is roughly equivalent to <?php echo $var; ?>. So, the following are all valid expressions:
{$var}{count($var)}{((time()%31337 > $var) ? "yes" : "peach")}
There are, however, two differences between PHP expressions and mplate expressions: First of all, everywhere in mplate functions or expressions, the dot can be used for array element lookup, just like in Smarty. This means that if $actor is an associative array with a key called name, we can write {$actor.name} or {$actor['name']} and get the same result.
Secondly, mplate expressions escape special HTML characters by default. This means that {"<"} (which works, because "<" is a valid PHP expression) gets transformed into < in the HTML output. This is done because very often, views display user-submitted content. This content makes a site vulnerable to nasty hacks by users if they can, for instance, get arbitrary HTML code to be included in a page. The philosophy here is that the coder should do extra work when they do not want a variable to be escaped, instead of the other way around. This way, it is less easily forgotten. If you want to circumvent this feature, you can use the raw function:
{raw $var}{raw ">"}{raw nl2br($var)}
Both of these features can also be completely turned off in the settings.
Functions and taglibs
Other than showing expressions, mplate has many handy built-in functions. mplate functions are bundled together in nice packages called taglibs, short for “tag libraries”. The taglib concept was shamelessly stolen from Java Server Pages (JSP), but of course without all the typical java-suck.
For now, all you need to know is that a taglib is a collection of functions which are all prefixed by the same word and a colon. Examples of mplate functions are c:foreach, c:include and c:strip. There, c is the name of the taglib and what comes behind that is the name of the function. The c taglib (the core taglib for friends) is the taglib that contains all the common and often-used mplate functions. These are all you need for simple mplate templates, but there are will be (hopefully) many more taglibs out there for all kinds of hip and trendy stuff! Check out the section about extending mplate if you want to make your own taglib.
You call a taglib function simply by wrapping it in curly braces (by default, at least):
{c:capture assign=$subpage_content}
{c:include file="star_wars_chapter.tpl"}
{/c:capture}
{str_replace("saber", "pudding", $subpage_content)}
The above piece of code tries to include a template file which, we hope, will display a chapter from Star Wars. The block function c:capture captures all its output, however, so that we can replace all occurences of “saber” by “pudding” in an attempt to improve the story. Please note that the last operation (the str_replace one) is not a mplate function, but a mplate expression performing a plain PHP function call, which means that the result is displayed. Finally, notice how the arguments to mplate functions look a lot like HTML attributes - in fact, mplate functions aren’t all that different from XML or HTML tags! Hence the name tag library. Please note that most functions work like this, but not all - c:foreach and c:if are common exceptions.
Because the core taglib is so commonly used, you may leave out the c: part entirely; if mplate sees a core taglib function without c: in front of it, it will assume that that’s what you meant. As such, the following piece of code is equivalent to the previous example:
{capture assign=$subpage_content}
{include file="star_wars_chapter.tpl"}
{/capture}
{str_replace("saber", "pudding", $subpage_content)}
Core functions
There should be a more decent function reference later, but for now, these functions are supported:
-
{c:if expr}...{c:else}...{/c:if}
Like PHPif. The{c:else}...part is optional. -
{c:foreach($arr as $key => $value}...{c:foreachelse}...{/c:foreach}
Like PHPforeach. The optional{c:foreachelse}...gets executed if$arrevaluates tofalse. -
{c:capture assign=$var}...{/c:capture}
Captures the output of the enclosed code, and assigns it to $var. -
{c:strip}...{/c:strip}
Removes all whitespace at the start and end of every line in the enclosed code. This is useful, for instance, when unwanted whitespace causes unwanted behaviour in bad browsers. -
{c:include file="file.tpl"}
Compiles thefile.tplmplate template, and uses PHPincludeto include it.file.tplhas to be somewhere in the template directory. -
{c:inline file="file.tpl"}
Like include, but puts the compiled code of file.tpl directly into the current template. Useful to avoid the overhead of including many small files. -
{c:raw expr}
echoes the PHP expressionexpr. Use this instead of{expr}to prevent HTML-like characters inexprfrom being escaped.
Template syntax
It is possible to customise the shape of mplate operations to your wishes, by choosing your own start en end delimiter character, and specifying under which circumstances they should work. Two “factory default” delimiter settings have been shipped with mplate, which I hope is enough for nearly all users.
The default setting, mplate, is what is used in nearly all examples on this site. With it, the start delimiter is {, and the end delimiter is }. However, within <script>…</script> or <style>…</style> tags, the start delimiter is #{ instead. This way, curly braces that are part of Javascript or CSS expressions are not by accident parsed as mplate expressions.
The other factory default is called jspish because it looks more like how JSP works. With jspish delimiters, all mplate functions are delimited by angular brackets, for example <c:if $rob=="jarig">feest</c:if>. Expressions still have curly braces, but always start with a #, as in #{$number * 3}. JSP uses ${..} instead of #{..} for expressions, but ${$foo} just looks silly. With jspish, you cannot omit the c: prefix for core functions. Also, make sure you wrap expressions containing “>” in parentheses, or mplate will think it found the end of the expression! (e.g. <c:if ($i>4)>..</c:if>)
The big advantage of jspish over mplate is that plain template files will look pretty decent in a web browser, while still clearly showing the places where data is shown. This is because the browser will parse <functions> as unknown HTML tags which it will ignore, while #{expressions} are shown like normal text. This is very nice in situations where the guy doing (or improving) the layout does not have easy access to the whole PHP-shebang - he can just plainly test the template in a browser and things will often be pretty close to the end result.
You can add comments to a template file with {* this is a comment *} (or <* ... *> in jspish). Additionally, use {literal}...{/literal} (<literal> in jspish) to make mplate not evaluate a piece of code at all. Comments and literal are not mplate functions or expressions, but “language constructs”. Or something like that.
Finally, you can simply insert blocks of PHP code into a mplate template and use mplate variables in them, just like you would in a normal PHP file:
{foreach $wookies as $wookie}
<?php toss_wookie($wookie); ?>
{$wookie} tossed!<br/>
{/foreach}
In fact, nearly every PHP file will correctly parse and run as a mplate template! However, it is in general bad practise to put plain PHP file into an mplate template; if you’re computing something complicated, better do it before displaying the view (google for “model view controller” for more info), and if you’re doing something obvious and common, better make it an mplate function!
Extending mplate
I’ll write this later. Look at Mplate/Taglib/Core.php and what’s in Mplate/Taglib/Core and see if you get it. There’s some magic involved, but it should be pretty straight forward. mplate finds all taglibs automatically, if they’re in the right directory (Mplate/Taglib) and if the filenames and classes match in a sensible way. As you can see, you can spread the functions of a taglib over multiple files (each must either contain a correctly named class or one correctly named global function), so that no extra luggage has to be loaded every time an mplate template runs.
Oh, and you can also change a setting (see below) to make mplate search multiple directories for taglibs. This way, you can keep application-specific template functions separate from the rest.
Settings
Will elaborate. These are the currently available settings and their defaults:
"compileDir" => $here.DS.'compiled',
"templateDir" => $here.DS.'templates',
"forceCompile" => false,
"mplateVariableName" => '__mplate',
"compiledFilePermissions" => 0644,
"dirPermissions" => 0771,
"smartyVarNotation" => true,
"escapeTarget" => Mplate::escapeXHTML,
"charset" => 'ISO8859-1',
"delims" => 'mplate',
"taglibDirs" => array(
dirname(__FILE__)."/Taglib" => "Mplate_Taglib",
)
And the “factory defaults” for syntax are defined as follows:
//mplate
array(
"scripts" => array(
"funcLDelim" => "#{",
"funcRDelim" => "}",
"exprLDelim" => "#{",
"exprRDelim" => "}",
"topNamespace" => "c",
"regex" => "<script.*?>.*?</script>|<style.*?>.*?</style>",
),
"default" => array(
"funcLDelim" => "{",
"funcRDelim" => "}",
"exprLDelim" => "{",
"exprRDelim" => "}",
"topNamespace" => "c",
),
),
//jspish
array(
"default" => array(
"funcLDelim" => "<",
"funcRDelim" => ">",
"exprLDelim" => "#{",
"exprRDelim" => "}",
),
)
$mplate->settings['delims'] accepts either the strings "mplate" or "jspish" or an array just like the ones up here.
The Mplate object
Public methods available:
void $mplate->display(string $filename)string $mplate->fetch(string $filename)string $mplate->viewfile(string $filename)string $mplate->fetchPHP(string $filename)void $mplate->setContext(Mplate_ContextInterface $context)Mplate::__construct(Mplate_ContextInterface $context = null)
The first four methods all search for $filename in $mplate->settings[’templateDir’] and compile it to a PHP file (if necessary). Then, display runs it and displays the result, fetch runs it and returns the result in a string, viewfile returns the filename of the compiled PHP script and fetchPHP returns the produced PHP source code.
Public variables:
array $mplate->settings-
array $mplate->vars
Use as associative array to send data to the view, i.e.$mplate->vars['apple'] = 'tree'sets the template variable$appleto the string “tree” inside a template whendisplayorfetchis called.
Check out the bottom of Mplate/Mplate.php to find out how the context thing works. In short, you can run a (compiled) mplate template in any scope you like, so that, for instance, $this points to some object or all kinds of variables have values.
Will run doxygen on this one for decent docs at some point. I promise.
End of docs! Sorry!