I was reading this question over on stackoverflow:
https://stackoverflow.com/questions/104516/calling-php-functions-within-heredoc-strings
and the accepted answer says to do plain PHP templates like this:
template.php:
<html> <head> <title><?=$title?></title> </head> <body> <?=getContent()?> </body> </html>
index.php:
<?php $title = 'Demo Title'; function getContent() { return '<p>Hello World!</p>'; } include('template.php'); ?>
To me the above isn't well structured in the sense that template.php depends on variables that are defined in other scripts. And you're using an include() to execute code when you do include('template.php')
(as opposed to using include() to include a class or a function which isn't immediately executed).
I feel like a better approach is to wrap your template inside a function:
template.php:
<?php function template($title, $content) { ob_start(); ?> <html> <head> <title><?=$title?></title> </head> <body> <?=$content?> </body> </html> <?php return ob_get_clean(); } ?>
index.php:
<?php require_once('template.php'); print template('Demo Title', '<p>Hello World!</p>'); ?>
Is the second approach better? Is there an even better way to do it?
Best Answer
I wouldn't do the second approach as the parameters aren't named.
A well-written essay on describing how a template system should work is coming from Parr, it's often quoted by people writing template systems and/or web-mvc frameworks.
Personally, what I usually prefer is to implement an ArrayObject class with a properties array, and the template would refer to
$this->propertyName
, which in fact would be the template object's$this->property['name']
. This could be also achieved simply by using__set
and__get
, so:and a template would look like:
and invoking it would look like:
As far as I remember, this is how the old Symfony 1.x and the Zend_View template engines look like, and for me it's fine.