Creating a simple but flexible templating engine

时光总嘲笑我的痴心妄想 提交于 2019-12-01 11:14:47

The regular expression you're looking for is {_(\w+)_}, if your template tags are only ever a single word. You'd use it a bit like this:

<?php

$replacements = array(
    "firstname" => "John",
    "lastname" => "Smith"
);

$template_markup = "Hello {_firstname_} {_lastname_}";
if(preg_match_all('/{_(\w+)_}/', $template_markup, $matches)) {
    foreach($matches[1] as $m) {
        $template_markup = str_replace("{_".$m."_}", $replacements[$m], $template_markup);
    }
}
echo $template_markup;

?>

You'll see the preg_match_all has forward slashes surrounding the regular expression, these are delimiters.

Update: If you want to expand the regular expression beyond single words, then be careful when using . to match any character. It's better to use something like this to specify that you want to include other characters: {_([\w-_]+)_}. The [\w-_] means it will match either alphanumeric characters, hyphens or underscores.

(Perhaps someone can explain why using . might be a bad idea? I'm not 100% sure).

James C

Unless you're trying to restrict down what people can do within a template and want to control what markup they can put in it I'd recommend PHP as a pretty kick-ass templating language!

If you want to stick with your solution you could do something like this to manage replacements.

$template = "foo={_FOO_},bar={_BAR_},title={_TITLE_}\n";

$replacements = array(
    'title' => 'This is the title',
    'foo' => 'Footastic!',
    'bar' => 'Barbaric!'
);

function map($a) { return '{_'. strtoupper($a) .'_}';}

$keys = array_map("map", array_keys($replacements));
$rendered = str_replace($keys, array_values($replacements), $template);

echo $rendered;

I have combined the solutions provided by both Sam and James to create a new solution.

  • Thanks to Sam for the regex part
  • Thanks to James for the array mode str_replace() part.

Here is the solution:

$replacements = array(
    "firstname" => "John",
    "lastname" => "Smith"
);

function getVal($val) {
    global $replacements;
    return $replacements[$val];
}

$template_markup = "Hello {_firstname_} {_lastname_}";
preg_match_all('/{_(\w+)_}/', $template_markup, $matches);
$rendered = str_replace($matches[0], array_map("getVal",array_values($matches[1])), $template_markup);
echo $rendered;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!