<?php
namespace Template;
// twig模板类
final class Twig {
private $filters = array();
private $data = array();
// 添加过滤
public function addFilter($key, $value) {
$this->filters[$key] = $value;
}
// 设置
public function set($key, $value) {
$this->data[$key] = $value;
}
// 分发
public function render($template, $cache = true) {
// 初始化Twig环境
$config = array(
'autoescape' => false,
'debug' => false
);
/*
* FYI all the Twig lovers out there!
* The Twig syntax is good, but the implementation and the available methods is a joke!
*
* All the Symfony developer has done is create a garbage frame work putting 3rd party scripts into DI containers.
* The Twig syntax he ripped off from Jinja and Django templates then did a garbage implementation!
*
* The fact that this system cache is just compiling php into more php code instead of html is a disgrace!
*/
// 1. 为用于生成输出的过滤器生成名称空间
$namespace = preg_replace('/[^0-9a-zA-Z_]/', '_', implode('_', array_keys($this->filters)));
$loader = new \Twig_Loader_Filesystem(DIR_TEMPLATE);
// 2. 启动Twig环境
$twig = new \Twig_Environment($loader, $config);
// 3. 创建一个匿名缓存类,因为twig不会让我们所有人都根据自定义键生成密钥
if ($cache) {
$cache = new class(DIR_CACHE, $options = 0, $namespace) extends \Twig_Cache_Filesystem {
private $directory;
private $options;
public function __construct($directory, $options = 0, $namespace) {
$this->directory = rtrim($directory, '\/') . '/';
$this->options = $options;
$this->namespace = $namespace;
}
public function generateKey($name, $className) {
$hash = hash('sha256', $name . $className . $this->namespace);
return $this->directory . $hash[0] . $hash[1] . '/' . $hash . '.php';
}
};
$twig->setCache($cache);
}
// 4. 获取模板类名称
$template_class_name = $twig->getTemplateClass($template . '.twig');
// 5. 获取缓存文件路径
$cache_file = $twig->getCache(false)->generateKey(DIR_TEMPLATE . $template . '.twig', $template_class_name);
try {
// 6. 如果我们没有创建缓存文件,请检查缓存文件是否存在
if (!is_file($cache_file)) {
// 7. 使用源获取源代码
$source = $twig->getLoader()->getSourceContext($template . '.twig');
$code = $source->getCode();
// 8. 通过过滤器运行代码
foreach ($this->filters as $key => $filter) {
$filter->callback($code);
}
// 9. 编译源代码
$output = $twig->compileSource(new \Twig_Source($code, $source->getName(), $source->getPath()));
// 10. 将输出写入缓存文件
$twig->getCache(false)->write($cache_file, $output);
}
// 11. 将缓存的文件加载到已加载模板的数组中
$twig->getCache(false)->load($cache_file);
return $twig->render($template . '.twig', $this->data);
} catch (Twig_Error_Syntax $e) {
trigger_error('Error: Could not load template ' . $template . '!');
exit();
}
}
}