Темизация не стандартными методами

Главные вкладки

Аватар пользователя olk olk 3 ноября 2010 в 20:45

Работая над небольшим проектом, столкнулся с проблемой – если какой-либо модуль не предоставляет хуков по темизации вывода своего контента, то довольно сложно темизировать представить информацию в нужном виде. Но как всегда – Друпал гибок и могуч, и эту проблему можно обойти если модуль использует (и регистрирует) свои функции темизации в общем реестре.

Опишу суть проблемы. В моем проекте использовался свой тип материала (определенный соответствующим модулем), который (тип материала) посредством этого модуля выводился в две колонки (при этом был переопределен вывод ноды, что в общем то не важно) . Но кроме этого в данном типе материала использовались несколько словарей, определяющих некоторые специфичные свойства данного типа материала. Термины данных словарей выводились в ноде в виде активных ссылок при клике на которых должны выводиться ноды с соответствующим признаком. Вся проблема заключалась в том, что вывод должен осуществляться в точно в том же виде как и основной вывод предоставляемый модулем (т.е. в нашем случае в две колонки) и при этом модуль 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'NULLvariable_get('default_nodes_main'10));
// и листалку
   
$output .= theme('table'NULL$rows$attributes);
   }
   
$output .= $pager;
   }
  return 
$output;
}
?>

Вот и все, теперь после сброса кэша регистра тем, вместо стандартного вывода материалов нашего типа для прикрепленных терминов будет использован вывод определенный в нашей функции (при этом нашу функцию даже не надо регистрировать в регистре тем (см. hook_theme), так как она подменяет уже зарегистрированную там функцию темизации.

Посмотреть как это выглядит в реале, можно на сайте www.loross.ru – весь вывод с облака тэгов и терминов внутри нод организован через подмену функции темизации (при этом не модули cck ни модуль views – не используется) .
PS. Да сайт пока в разработке, так что критика в адрес контента и дизайна принимается но со скидкой на недоделанность Wink
Ссылка на оригинал статьи

Комментарии

Аватар пользователя seaji seaji 3 ноября 2010 в 23:28

Главное это задокументировать, что бы следующий программер не убился бы об стену пытаясь понять что не так работает.