0

Hi I'm trying to perform a very easy templating system in PHP.

I wold to do this:

  • Reading some .md file
  • Change all {{ variables }} with a corrispondent variable in an array like

    $data( array('variable1' => 'value', 
                 'variable2' => 'value2'));
    
  • Manage the case when a variable doesn't exist, in order to prevent errors like "key not found in array".

Currently I've done this (not in regular expression and also it doens't work)

class Markdown{
    private static $folder = 'markdowns/';

    public static function fill_template($template, $array){

        $text = file_get_contents(self::$folder . $template . '.md'); 
        foreach($array as $key => $value){
            $text = str_replace('{{'.$key.'}}', $value, $text);
        }

        return $text;
    }
}

Any ideas?

Thanks

Steve
  • 406
  • 3
  • 11

2 Answers2

2

You can use preg_replace_callback() to transform the pattern {{variable}} to its corresponding value:

public static function fill_template($template, $array){
    $text = file_get_contents(self::$folder . $template . '.md');
    $text = preg_replace_callback('~\{\{([^}]+)\}\}~', function($matches) use ($array) {
        $key = trim($matches[1]); // remove unwanted spaces
        if (isset($array[$key])) return $array[$key]; // return the value if found
        // If not found, return the key:
        return $key;
    }, $text);
    return $text;
}

If the match is not found in the array, the content is returned without {{}}.

Regular expression:

~       # delimiter
\{\{    # two literal { - need to be escaped
(       # start capture group
 [^}]+  # all character until }
)       # end capture group
\}\}    # two literal } - need to be escaped
~       # end delimiter
Syscall
  • 19,327
  • 10
  • 37
  • 52
0

You can use preg_replace_callback to get simple renderer

function render($template, $vars) {
    return \preg_replace_callback("!{{\s*(?P<key>[a-zA-Z0-9_-]+?)\s*}}!", function($match) use($vars){
        return isset($vars[$match["key"]]) ? $vars[$match["key"]] : $match[0];
    }, $template);
}

Example

echo render(
    "Hello {{ name  }}, how are you today? Date: {{time   }} and it's {{weather}} in {{location}}\n", 
    ["name"=>"World!!", "time"=>date("c")]
);

will render to

Hello World!!, how are you today? Date: 2018-04-05T06:40:34+00:00 and it's {{weather}} in {{location}}

mleko
  • 11,650
  • 6
  • 50
  • 71