Last Updated: March 21, 2019
·
2.47K
· tjuice

Simple Template Renderer in php

There are many powerfull templating systems in php like smarty, twig etc. but sometimes you just wanna fill some string with placeholders without introducing a big library onto your project.

This class will provide a method TemplateRenderer::renderTemplate($template, $placeholderArray); to fill some template string with the Values given in an associative array.

e.g. you can have some template

$templateString = 'Hi {$who}, welcome to {$where}.';

and fill it with your data.

$data = array(
    "who" => "Thomas",
    "where" => "munich",
);

the TemplateRenderer will do the following output:

echo TemplateRenderer::renderTemplate($templateString, $data);
// => Hi Thomas, welcome to munich.

Here is the implementation:

class TemplateRenderer {

    public static function renderTemplate($template, $placeholderArray) {

        $placeholderKeys = array_keys($placeholderArray);
        $subject = $template;
        foreach ($placeholderKeys as $placeholderKey) {
                $placeholderValue = $placeholderArray[$placeholderKey];
                $pattern = '/\{\$'.$placeholderKey.'\}/';
                $replace = $placeholderValue;
                $subject = preg_replace($pattern, 
                TemplateRenderer::preg_escape_back($replace), $subject);
        }
        return $subject;
    }

    public static function preg_escape_back($string) {
      // Replace $ with \$ and \ with \\
      $string = preg_replace('#(?<!\\\\)(\\$|\\\\)#', '\\\\$1', $string);
      return $string;
    } 
}

4 Responses
Add your response

If you don't mind standardizing the template variables to either upper or lower case; then you could use PHP's string translate function (strtr) which would probably be considerably faster than regex.

over 1 year ago ·

Cool! Thanks for the tipp!

over 1 year ago ·

strtr is a good choice but remember to put a prefix and postfix:
foreach($a as $key=>$value) { $b['{$' . $key . '}'] = $value }
return strtr($subject, $b) ;

If you think is better to use regexp then I recommend you to use pregmatchall and preg_split. In that way the source of keys won't be your array, the list of required keys are based on the template. Avoiding the problem of a tiny template with a fat array of options making unnecesary comparisons

over 1 year ago ·

This is really cool. Just curious, how would you go about dealing with arrays that would require looping through and displaying lists? If that was including this would be a pretty powerful, yet simple templating class.

over 1 year ago ·