我用50行代码写了树枝
#php #twig #symfony

成分

每当我需要渲染一个“树枝”模板引擎页面时,我都需要这些组件。 $页面:我要渲染的模板的名称。 $模板层次结构:从$ Page One,...到te root模板。是的,因为在类似树枝的模板引擎中,模板可以扩展另一个。 $ CACH:因为存储缓存文件并将内容保存在缓存中很重要,而不是随时重新打开文件。最后但并非最不重要的$块:因为每个模板都可以覆盖父模板的块。

$page = 'page';
$hierarchy = [];
$cache = [];
$blocks = [];

等级制度

构建模板的层次结构非常简单。只需打开所需的页面,并检查extends零件是否存在。查找父模板,直到模板不包含父。

同时,我构建了层次结构,我还存储所有需要的模板。我将在下一步中再次需要构建最终的渲染模板。缓存可以帮助我建立更好的表演。

do {
    $hierarchy[] = $page;
    $filename = __DIR__ . '/../templates/'.$page.'.engine';
    $cache[$page] = file_get_contents($filename);
    $re = '/extends \'([\w]{0,})\'/m';
    preg_match_all($re, $cache[$page], $matches, PREG_SET_ORDER, 0);
    if ($matches != []) {
        $page = $matches[0][1];
    }
} while ($matches != []);

现在我们有了模板的层次结构。我将模板的$层次结构从根模板开始。从这里返回到所需的模板,我可以检查是否必须重写某个块。

foreach(array_reverse($hierarchy) as $template) {
    $re = '/ block ([\w<>\/ \n\s]{0,}) /m';
    $content = $cache[$template];
    preg_match_all($re, $content, $matches, PREG_SET_ORDER, 0);
    $blockList = array_column($matches, 1);
    foreach ($blockList as $block) {
        $re = '/{% block '.$block.' %}([\{\}\[\]\w=\"\<\/\> \n\.]{0,}){% endblock '.$block.' %}/m';
        preg_match_all($re, $content, $matches, PREG_SET_ORDER, 0);
        if ($matches != []) {
            $blocks[$block] = $matches[0][1];
        }
    }
}

现在我已经有一系列块。每个块包含每个块的最终版本。

渲染块

现在我将获得缓存的最后一项内容。记住?是根模板。现在,...我将使用“ Ultimate”块的数组呈现所有块。

$content = end($cache);
foreach($blocks as $name => $block) {
    $re = '/{% block '.$name.' %}([\{\}\[\]\w=\"\<\/\> \n\.]{0,}){% endblock '.$name.' %}/m';
    $content = preg_replace($re, $blocks[$name], $content);
}

变量

最后实现的功能是模型的渲染。像在树枝中一样,... {{foo}}呈现foo变量。

$model = [ 'title' => 'titolo dal modello', ];

$re = '/{{([\w]{0,})}}/m';
preg_match_all($re, $content, $matches, PREG_SET_ORDER, 0);
foreach(array_unique(array_column($matches, 1)) as $var) {
    $content = str_replace('{{'.$var.'}}', $model[$var], $content);
}

使成为, ...

现在,$content包含渲染模板。只需打印

echo $content;

结论

好的,这是未经测试的代码。只是我可以使用RegexP进行的练习,并检查我是否能够构建这样的模板引擎。我相信我永远不会在生产中使用它。是练习。

关联

我制作的视频的链接在这里:I wrote twig in 50 lines of code。我以意大利语讲话的这段视频,但代码在php中。