Работая над небольшим проектом, столкнулся с проблемой – если какой-либо модуль не предоставляет хуков по темизации вывода своего контента, то довольно сложно темизировать представить информацию в нужном виде. Но как всегда – Друпал гибок и могуч, и эту проблему можно обойти если модуль использует (и регистрирует) свои функции темизации в общем реестре.
Опишу суть проблемы. В моем проекте использовался свой тип материала (определенный соответствующим модулем), который (тип материала) посредством этого модуля выводился в две колонки (при этом был переопределен вывод ноды, что в общем то не важно) . Но кроме этого в данном типе материала использовались несколько словарей, определяющих некоторые специфичные свойства данного типа материала. Термины данных словарей выводились в ноде в виде активных ссылок при клике на которых должны выводиться ноды с соответствующим признаком. Вся проблема заключалась в том, что вывод должен осуществляться в точно в том же виде как и основной вывод предоставляемый модулем (т.е. в нашем случае в две колонки) и при этом модуль taxonomy не предоставляет интерфейса по переопределению вывода, но при этом имеет зарегистрированную функцию темизации taxonomy_term_page.
Решение данной проблемы возможно за счет подмены функции темизации в глобальном регистре тем Друпала. В этом нам поможет хук
hook_theme_registry_alter(&$theme_registry) , который позволяет переопределить любую зарегистрированную функцию темизации на свою (кстати не только функцию непосредственно темизации, но и preprocess функции и еще много чего интересного, советую посмотреть, что содержится в переменной $theme_registry).
Ну что же перейдем к конкретике.
Модуль который определяет новый тип материала и его вывод называется условно loross (это, что бы в дальнейшем не ссылаться на то, что фрагмент hook в названии функции надо заменять на наименование своего модуля).
В первую очередь определим функцию псевдо-темизации, которая заменит нам стандартную функцию вывода модуля taxonomy (theme_taxonomy_term_page).
Определим хук в нашем модуле который переназначит нужную нам функцию темизации
<?php
function loross_theme_registry_alter(&$theme_registry) {
// переназначим вывод для таксономии
$theme_registry['taxonomy_term_page']['function'] = 'theme_taxonomy_loross_term_page';
}
?>
<?php
// lmodel – это тип материала определенный в модуле
define ('LMODEL_NODE_TYPE', 'lmodel');
function
theme_taxonomy_loross_term_page($tids, $result) {
// нам надо определить входит ли данный термин в словарь прикрепленный
// к данному типу материала
$is_replace_theme = true;
// получаем список словарей для данного типа материала
$voc = taxonomy_get_vocabularies(LMODEL_NODE_TYPE);
$voc_vid = array();
// и сохраняем их в массиве
if ($voc && is_array($voc)) {
foreach($voc as $key => $value){
$voc_vid[] = $value->vid;
}
}
// проверяем принадлежит ли термин словарю включенному в тип материала
foreach($tids as $key => $tid){
$t = taxonomy_get_term($tid);
if(!in_array($t->vid,$voc_vid)) {
$is_replace_theme = false;
break;
}
}
// если нет, то используем стандартную функцию модуля taxonomy
if(!$is_replace_theme) {
$output = theme_taxonomy_term_page($tids, $result);
}
else {
// если это наш случай, то начинаем определять свой вывод в виде таблицы мз двух столбцов
$output ='';
$rows = array();
$i = 1;
$row=array();
while ($node = db_fetch_object($result)) {
$n = node_load($node->nid);
$class = (($i % 2) == 0)?'lmodel-item right': 'lmodel-item left';
$row[] =array('data'=>theme('lmodel',$n),'class'=>$class);
if (($i % 2)==0) {
$rows[]=$row;
$row=array();
}
$i++;
}
// здесь мы отдельно обрабатываем случай, когда в выборку попала только одна нода
if(!count($rows) && count($row)) {
$rows[] = $row;
}
$attributes = array('class' => "lmodel-view");
if (count($rows)) {
// Здесь формируем стандартный табличный вывод
$pager = theme('pager', NULL, variable_get('default_nodes_main', 10));
// и листалку
$output .= theme('table', NULL, $rows, $attributes);
}
$output .= $pager;
}
return $output;
}
?>
Вот и все, теперь после сброса кэша регистра тем, вместо стандартного вывода материалов нашего типа для прикрепленных терминов будет использован вывод определенный в нашей функции (при этом нашу функцию даже не надо регистрировать в регистре тем (см. hook_theme), так как она подменяет уже зарегистрированную там функцию темизации.
Посмотреть как это выглядит в реале, можно на сайте www.loross.ru – весь вывод с облака тэгов и терминов внутри нод организован через подмену функции темизации (при этом не модули cck ни модуль views – не используется) .
PS. Да сайт пока в разработке, так что критика в адрес контента и дизайна принимается но со скидкой на недоделанность
Ссылка на оригинал статьи
Комментарии
Главное это задокументировать, что бы следующий программер не убился бы об стену пытаясь понять что не так работает.