-
-
Save daggerhart/730e8a9d79f37a461d985b158d0108ab to your computer and use it in GitHub Desktop.
| <?php | |
| /** | |
| * Class Template - a very simple PHP class for rendering PHP templates | |
| */ | |
| class Template { | |
| /** | |
| * Location of expected template | |
| * | |
| * @var string | |
| */ | |
| public $folder; | |
| /** | |
| * Template constructor. | |
| * | |
| * @param $folder | |
| */ | |
| function __construct( $folder = null ){ | |
| if ( $folder ) { | |
| $this->set_folder( $folder ); | |
| } | |
| } | |
| /** | |
| * Simple method for updating the base folder where templates are located. | |
| * | |
| * @param $folder | |
| */ | |
| function set_folder( $folder ){ | |
| // normalize the internal folder value by removing any final slashes | |
| $this->folder = rtrim( $folder, '/' ); | |
| } | |
| /** | |
| * Find and attempt to render a template with variables | |
| * | |
| * @param $suggestions | |
| * @param $variables | |
| * | |
| * @return string | |
| */ | |
| function render( $suggestions, $variables = array() ){ | |
| $template = $this->find_template( $suggestions ); | |
| $output = ''; | |
| if ( $template ){ | |
| $output = $this->render_template( $template, $variables ); | |
| } | |
| return $output; | |
| } | |
| /** | |
| * Look for the first template suggestion | |
| * | |
| * @param $suggestions | |
| * | |
| * @return bool|string | |
| */ | |
| function find_template( $suggestions ){ | |
| if ( !is_array( $suggestions ) ) { | |
| $suggestions = array( $suggestions ); | |
| } | |
| $suggestions = array_reverse( $suggestions ); | |
| $found = false; | |
| foreach( $suggestions as $suggestion ){ | |
| $file = "{$this->folder}/{$suggestion}.php"; | |
| if ( file_exists( $file ) ){ | |
| $found = $file; | |
| break; | |
| } | |
| } | |
| return $found; | |
| } | |
| /** | |
| * Execute the template by extracting the variables into scope, and including | |
| * the template file. | |
| * | |
| * @internal param $template | |
| * @internal param $variables | |
| * | |
| * @return string | |
| */ | |
| function render_template( /*$template, $variables*/ ){ | |
| ob_start(); | |
| foreach ( func_get_args()[1] as $key => $value) { | |
| ${$key} = $value; | |
| } | |
| include func_get_args()[0]; | |
| return ob_get_clean(); | |
| } | |
| } |
| <?php | |
| $suggestions = array( 'user-profile-example-template' ); | |
| // provide more-specific template suggestions for logged in users | |
| if ( user_is_logged_in() ) { | |
| // provide a generic template suggestion for all users of a given type | |
| if ( user_is_of_special_type() ) { | |
| $suggestions[] = 'user-profile-' . $user->type; | |
| } | |
| // provide the most-specific template suggestion possible for this user. | |
| $suggestions[] = 'user-profile-' . $user->id; | |
| } | |
| $tpl = new Template( 'path/to/templates/folder' ); | |
| $tpl->render( $suggestions, array( | |
| 'user_name' => $user->name, | |
| 'user_bio' => $user->bio | |
| ) ); |
| <div class="user-profile"> | |
| <h3 class="title"><?php echo $user_name; ?></h3> | |
| <div class="content"><?php echo $user_bio; ?></div> | |
| </div> |
@Cyclonecode, good catch on the doulbe $this->folder = $this->folder = ..., that was a typo I had obviously missed for years.
The $folder constructor parameter is optional. You shouldn't have to provide a folder path during construction of the object.
Ah, but if you don't supply a folder path the following will never work right:
https://gist.github.com/daggerhart/730e8a9d79f37a461d985b158d0108ab#file-simple-template-class-php-L72
@Cyclonecode, that's true. I made it optional in the constructor, but when not provided a user would need to make use of the set_folder() method themselves. What would you recommend as an improvement to the class? I'm open to any ideas that make it more reliable and easy to use.
First of all I think I would set visibility for the different methods,. For instance I guess the render_template(), find_template() and so on really should not be used by a user directly? If this is the case I really think they should be declared as private or protected. Of course the folder property also should be set to private or protected in this case. After that I think changing the render() method to something like this might be a good idea:
public function render( $suggestions, $variables = array() ){
// Make sure we have a folder path, perhaps we should also check so the folder is readable?
if ( !$this->folder || !is_dir($this->folder)) {
throw new Exception('You need to set the base folder for all templates using set_folder().');
}
$template = $this->find_template( $suggestions );
$output = '';
if ( $template ){
$output = $this->render_template( $template, $variables );
}
return $output;
}
Hm what's up with this:
https://gist.github.com/daggerhart/730e8a9d79f37a461d985b158d0108ab#file-simple-template-class-php-L33
Also, should not this be mandatory:
https://gist.github.com/daggerhart/730e8a9d79f37a461d985b158d0108ab#file-simple-template-class-php-L22