【发布时间】:2009-10-13 13:24:44
【问题描述】:
Smarty FAQ 提出了一种处理可缓存片段的方法,但它需要每个页面控制器预先完成大量工作,而不是正确封装。
我们希望达到一个可以做以下事情的阶段:
<div id="header">
{our_categories}
{our_subcategories category=$current_category}
</div>
our_ 前缀函数的输出应该是完全可缓存的,只依赖于命名参数(如果有的话)。如果我们在多个模板中引用 {our_categories},它们应该都引用相同的缓存内容.
(可能值得一提的是,我们尝试使用{insert name="..."} 并编写我们自己的函数,但结果无法缓存,我们最终手动调整了 HTML,而不是从 Smarty 的模板处理中受益。)
我们的第一次破解使用了自定义函数smarty_function_our_categories,但缓存出现了严重错误。这是我们的函数的样子:
function smarty_function_our_categories($params, &$smarty) {
$smarty->caching = 2;
$smarty->cache_lifetime = 3600; # 1 hour
if (!$smarty->is_cached(...)) {
// ... do db access to fetch data for template...
$smarty->assign(....);
}
return $smarty->fetch(...);
}
问题是:在函数中调用$smarty->fetch() 会使 smarty 混淆,使其无法跟踪哪些模板有插入标签,哪些没有。最终结果是 Smarty 在提供缓存内容时忘记替换某些标记(它放在那里的标记说:“用一些非缓存 {insert ...} 调用的结果替换它。)在我们的例子中,这体现在我们的站点显示了几个 md5 校验和和一个 php 序列化的纪念品,我们的主菜单应该是 - 这不好。
我们假设我们在构建组件的方式上犯了一个错误,所以问题最终变成了:
如何使用 Smarty 安全地创建缓存组件来呈现自身?
【问题讨论】: