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 для рендеринга самого себя?