Есть theme_preprocess_views_view_unformatted и theme_preprocess_page
В theme_preprocess_views_view_unformatted я получаю некое значение, которое мне нужно затем использовать в theme_preprocess_page. Соответственно мне надо передать переменную. Это возможно?
Drupal 7
Комментарии
Возможно: https://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/drup...
UPD - но важно, чтоб на момент когда переменная будет нужна, она уже была заполнена. Т.е. фактически, чтоб на момент выполнения theme_preprocess_page уже был выполнен theme_preprocess_views_view_unformatted.
ИМХО, вы что-то делаете не так. Опишите саму задачу, а не что сделать нужно.
Вообще я пока эксперементирую, как правильно сделать, и может быть не туда копаю, но пока я ещё только ищу варианты решения. Но задача примерно следующая:
На всех страницах сайта в подвал выводятся данные, генерируемые собственным модулем: массив со списком ID. Причем каждый раз в случайном порядке: shuffle(&array). Т.е. функция модуля генерит список id, а затем в page.tpl.php на основе этого списка выводятся блоки, по одному блоку на id из массива. В модуле я устанавливал переменную variable_set, а затем в page.tpl.php брал значения через variable_get.
Теперь понадобилось, чтобы на страницах views часть блоков (4) выводилась не в подвале, а посреди результатов вьюхи, между 5 и 6 рядом, а в подвал выводились только все оставшиеся, например ещё 7 блоков.
Итого например если у меня 11 id, и соответственно 11 блоков, то надо чтобы на всех страницах, кроме вьюх, в подвале выводилось 11 блоков, а на страницах вьюх 4 блока в результатах вьюхи в середине списка, и ещё 7 оставшихся в подвале.
При этом важно, чтобы блоки при каждом заходе на страницу, перемешивались между собой в случайном порядке.
views-view-unformatted.tpl.php у меня переопределен и просто 4 блока из 11 я могу вывести. Но настроить связь между views-view-unformatted.tpl.php и page.tpl.php у меня пока не получается
Как минимум, это уже неправильно.
Вы если делаете variable_set(), то у вас кеш сбрасывается, если делаете это на каждой странице, то дико теряете в производительности.
Вам скорее подойдёт static-кеширование в helper-функции или синглтон
1 - preprocess_page выполняется после preprocess_views_view_unformatted, хотя могло бы быть и наоборот.
2 - preprocess_views_view_unformatted выполняется сколько угодно раз. В какой из исполнения функции static переменная запишет нужное значение? Правильно - при последнем вызове. Продолжать костылить и проверять для какой вьюхи и для какого дисплея был вызван препроцесс?
3 - вообще идея передавать переменную в виде static между функциями является костылем, так как нельзя надеяться на порядок вызова функций и количество их вызовов.
4 - если в preprocess_page нужно получить какую то переменную, то нужно в теле функции определить нужное значение и записать его в переменную (опишите подробней, что нужно получить в переменную).
Это из серии когда не друпал разработчик почему то предлагает более здравую мысль, чем друпал разработчик.
Я не советовал так делать, а только отвечал на вопрос "как это можно сделать", и объяснил как с этим работать.
Определить, что открыта страница вьюхи можно функцией views_get_page_view . Эта же функция и возвращает объект вьюхи. Далее пишите свою логику отталкиваясь от результатов $view->result
<?php
/*
* Implements hook_preprocess_page
*/
function THEMENAME_preprocess_page(&$variables){
$view = views_get_page_view();
if(isset($view) && $view->name == 'YOUR_VIEWS_MACHINE_NAME') {
// результаты вьюхи в массиве $view->result
}
}?>
Спасибо. Да, конечно. Это само собой. Моя ошибка была в том, что я зачем-то решил логику раскидать на несколько preprocess функций. Частично задуманное заработало при использовании variable_set и variable_get, но это, во-первых, как написали выше, неверно с точки зрения производительности, а во-вторых все равно не работало так как задумано, из-за изначально неправильной логики.
В итоге я весь расчет условий поместил в hook_preprocess(), после чего обмен переменными между препроцессами стал не нужен и все стало на свои места.
<?php
/**
* Implements hook_preprocess().
*/
function mytheme_preprocess(&$variables, $hook) {
...
}
?>
https://api.drupal.org/api/drupal/includes%21theme.inc/function/template...
Сильный ход вынести всю логику в hook_preprocess, который вызывается перед каждым препроцессом. hook_preprocess может быть вызван сотни раз для одной страницы и вы в каждом из них будете производить свои вычисления? Это фиаско, братан.
Ну я сделал вот так:
<?php
function mytheme_preprocess(&$variables, $hook) {
if ($hook == 'node' || $hook == 'page' || $hook == 'views_view_unformatted') {
логика тут
}
}
?>Вот так у меня к примеру в шаблоне вьюхи не видит переменную $my_var
<?php
function mytheme_preprocess_page(&$variables, $hook) {
$variables['my_var'] = 'value';
}
?>
Вот из документации друпала: https://www.drupal.org/docs/7/theming/overriding-themable-output/setting...
<?php
// Shared between the 'foo' and 'bar' theming hooks.
// Specific to 'foo'.
function drop_preprocess(&$variables, $hook) {
if ($hook == 'foo' || $hook == 'bar') {
$variables['foobar_item'] = 'foobar item';
}
if ($hook == 'foo') {
$variables['foo_item'] = 'foo item';
}
// Specific to 'bar'.
elseif ($hook == 'bar') {
$variables['bar_items'] = 'bar item';
}
}
?>
Так а сколько раз в конечном итоге будут вызваны preprocess_node/preprocess_views_view_unformatted и hook_preprocess?
Хорошо, признаю, я не прав. Как мне заставить views-view-unformatted--myview--page.tpl.php увидеть мой $my_var из
<?php
function THEMENAME_preprocess_page(&$variables){
...
$variables['my_var'] = 'value';
...
}
?>
Вместо Notice: Undefined variable: my_var ?
Получить $my_var точно так же, как и в preprocess_page.
Ну так оно не работает:
Если я создаю $my_var в preprocess_page
на выходе я получаю Undefined variable: my_var
preprocess:
<?php
function mytheme_preprocess_page(&$variables) {
$variables['my_var'] = 'My Value';
}
?>
views-view-unformatted--myview--page.tpl.php:
<?php print $my_var; ?>
Итог: Notice: Undefined variable: my_var в функции include() ...
Логично, препроцесс пэйджа задаёт переменные для пэйдж.тпл.