Ну, сути проблемы уже сто лет в обед, а сама суть такая. В файле шаблона темы/ядра есть хук, внутри хука генерируется переменная и она же используется в подключении другого шаблона (в котором нет ни хуков, ни переопределить его нельзя целиком, так как он много где используется). Поэтому ни pre ни post использовать не получится. Использую override хука.
Вот только получается, что оверрайд переписывает не то, что внутри тэгов {hook …}…{/hook}, а ВКЛЮЧАЯ сами эти тэги, в результате все pre и post к этому хуку сразу отваливаются, так как подключаться больше не к чему.
Чтобы полностью заменить код внутри хука на свой: /design/themes/[название_темы]/templates/addons/[id_модуля]/hooks/[dir_name]/[file_name].override.tpl
Именно это я выкрикнул, когда наконец-то добрался в чтении кода до файла
/app/functions/smarty_plugins/block.hook.php
и на 114 строке наткнулся на комментарий
override hook should be call for opened tag to prevent pre/post hook execution
и
post hook should be called only if override hook was no executed
Господа, почему я трачу несколько дней на то, о чем вы не удосужились написать в доке? Ладно, возможности. Но ограничения???
Ну и собственно, вопрос “Как” - отпал. Остался вопрос - “Нахрена?”
if ($content === null) {
// reset override for current hook
$overrides[$params['name']] = false;
// override hook should be call for opened tag to prevent pre/post hook execution
if (!empty($hooks[$params['name']]['override']) && !isset($hooks[$params['name']]['override'][$smarty->template_resource])) {
foreach ($hooks[$params['name']]['override'] as $tpl) {
$_hook_content = $smarty->fetch($tpl);
if (trim($_hook_content)) {
$overrides[$params['name']] = true;
$hook_content = $_hook_content;
}
}
}
// prehook should be called for the opening {hook} tag to allow variables passed from hook to body
if (empty($overrides[$params['name']]) && !empty($hooks[$params['name']]['pre'])) {
foreach ($hooks[$params['name']]['pre'] as $tpl) {
$hook_content .= $smarty->fetch($tpl);
}
}
} elseif (empty($overrides[$params['name']])) {
// post hook should be called only if override hook was no executed
if (!empty($hooks[$params['name']]['post'])) {
foreach ($hooks[$params['name']]['post'] as $tpl) {
$hook_content .= $smarty->fetch($tpl);
}
}
$hook_content = $content . "\n" . $hook_content;
}
вношу изменения
if ($content === null) {
// reset override for current hook
$overrides[$params['name']] = false;
// override hook should be call for opened tag to prevent pre/post hook execution
if (!empty($hooks[$params['name']]['override']) && !isset($hooks[$params['name']]['override'][$smarty->template_resource])) {
foreach ($hooks[$params['name']]['override'] as $tpl) {
$_hook_content = $smarty->fetch($tpl);
if (trim($_hook_content)) {
// AVP: задаю false чтобы выполнялся post хук
$overrides[$params['name']] = false;
// AVP: задаю статическое значение, что уже был оверрайд хука
$overrides['is_yes'][$params['name']] = true;
$hook_content = $_hook_content;
}
}
}
// prehook should be called for the opening {hook} tag to allow variables passed from hook to body
if (empty($overrides[$params['name']]) && !empty($hooks[$params['name']]['pre'])) {
foreach ($hooks[$params['name']]['pre'] as $tpl) {
$hook_content .= $smarty->fetch($tpl);
}
}
} elseif (empty($overrides[$params['name']])) {
// post hook should be called only if override hook was no executed
if (!empty($hooks[$params['name']]['post'])) {
foreach ($hooks[$params['name']]['post'] as $tpl) {
$hook_content .= $smarty->fetch($tpl);
}
}
// AVP: ДОБАВЛЯЮ УСЛОВИЕ - приплюсовывать хук к контенту только если не было оверрайда(!)
if(!isset($overrides['is_yes'][$params['name']]))
$hook_content = $content . "\n" . $hook_content;
}
после этого и оверрайд и пост хук работают вместе
но надо еще поковырять, что будет с pre хуками и что может вылезти из неприятностей
@ikoshkin@Asya@avoronin@cs-cart_team
прошу объяснить заложенную логику в эту функцию и блок smarty hook, думаю много кому полезно будет, раз это один из основополагающих элементов
Глобальные изменения по работе хуков шаблонов были более 10 лет назад. Основные изменения:
Интегрировали хуки для шаблонов.
Переписали хуки.
Решили проблему с кешем.
Исправили проблему, что не срабатывала модификация capture и других параметров в прехуках. Из-за этого приходилось создавать отдельный хук для их модификации. Проблема проявлялась на витрине на странице товара рядом с кнопкой Добавить в корзину.
Откатили решение п. 4, т. к. это создавало баг для кнопок Добавить в корзину при включенном Catalog Mode. Сделали другое решение.
Спасибо большое, конечно, но я про логику а не про дорожную карту.
Правильно ли я понимаю из комментария и кода, что если есть оверрайд хука, то ни пре ни пост этого хука не сработают?
Правильно ли я понимаю, что если к хуку несколько оверрайдов, то сработает тот, priority аддона которого больший?
Приоритет точно есть, работает только один оверрайд.
Правильно ли я понимаю из комментария и кода, что если есть оверрайд хука, то ни пре ни пост этого хука не сработают?
Было бы идеально, если как то более строго указать логику оверрайда.
Но post и pre хуки нужно чтобы всегда работали, спасибо @alex_vp что покопался, так как тоже сталкивались с таким поведением, после чего просто корректировали ядро или переписанный файл с хуком.
и @Nail.Gafin
все-таки объясните сакральный смысл блокировки обработки pre если есть оверрайд, и блокировка post на закрывающем тэге, также если есть оверрайд
Очень нужен ваш ответ
Пока вышел из положения тем, что в модуле с оверрайдом прописал свой хук, а в модуле с пост - прицепился не к оригенальному, а к заявленному в файле оверрайда. Но в итоге пришлось сделать модули зависимыми, а это не есть гуд, причем очень-очень не есть