Темизация не стандартными методами в Друпал

ср, 03.11.2010 20:26 :: olk

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

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

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

Ну что же перейдем к конкретике. Модуль который определяет новый тип материала и его вывод называется условно loross (это, что бы в дальнейшем не ссылаться на то, что фрагмент hook в названии функции надо заменять на наименование своего модуля). В первую очередь определим функцию псевдо-темизации, которая заменит нам стандартную функцию вывода модуля taxonomy (theme_taxonomy_term_page).

Определим хук в нашем модуле который переназначит нужную нам функцию темизации

  1. function loross_theme_registry_alter(&$theme_registry) {
  2.  // переназначим вывод для таксономии
  3.   $theme_registry['taxonomy_term_page']['function'] = 'theme_taxonomy_loross_term_page';
  4. }

  1. // lmodel – это тип материала определенный в модуле
  2. define ('LMODEL_NODE_TYPE', 'lmodel');
  3.  
  4. function theme_taxonomy_loross_term_page($tids, $result) {
  5. // нам надо определить входит ли данный термин в словарь прикрепленный
  6. // к данному типу материала
  7.   $is_replace_theme = true;
  8. // получаем список словарей для данного типа материала
  9.   $voc = taxonomy_get_vocabularies(LMODEL_NODE_TYPE);
  10.   $voc_vid = array();
  11. // и сохраняем их в массиве
  12.   if ($voc && is_array($voc)) {
  13.         foreach($voc as $key => $value){
  14.         $voc_vid[] = $value->vid;
  15.         }
  16.   }
  17.  
  18. // проверяем принадлежит ли термин словарю включенному в тип материала
  19.   foreach($tids as $key => $tid){
  20.         $t = taxonomy_get_term($tid);
  21.     if(!in_array($t->vid,$voc_vid)) {
  22.                 $is_replace_theme = false;
  23.                 break;
  24.         }
  25.   }
  26. //  если нет, то используем стандартную функцию модуля taxonomy
  27.   if(!$is_replace_theme) {
  28.         $output = theme_taxonomy_term_page($tids, $result);
  29.   }
  30.   else {
  31. // если это наш случай, то начинаем определять свой вывод в виде таблицы мз двух столбцов
  32.     $output ='';
  33.     $rows = array();
  34.     $i = 1;
  35.     $row=array();
  36.     while ($node = db_fetch_object($result)) {
  37.       $n = node_load($node->nid);
  38.       $class = (($i % 2) == 0)?'lmodel-item right': 'lmodel-item left';
  39.       $row[] =array('data'=>theme('lmodel',$n),'class'=>$class);
  40.       if (($i % 2)==0)  {
  41.         $rows[]=$row;
  42.         $row=array();
  43.       }
  44.            $i++;
  45.     }
  46. // здесь мы отдельно обрабатываем случай, когда в выборку попала только одна нода
  47.    if(!count($rows) && count($row)) {
  48.         $rows[] = $row;
  49.    }
  50.  
  51.    $attributes = array('class' => "lmodel-view");
  52.    if (count($rows)) {
  53. // Здесь формируем стандартный табличный вывод
  54.    $pager = theme('pager', NULL, variable_get('default_nodes_main', 10));
  55. // и листалку
  56.    $output .= theme('table', NULL, $rows, $attributes);
  57.    }
  58.    $output .= $pager;
  59.    }
  60.   return $output;
  61. }
Вот и все, теперь после сброса кэша регистра тем, вместо стандартного вывода материалов нашего типа для прикрепленных терминов будет использован вывод определенный в нашей функции (при этом нашу функцию даже не надо регистрировать в регистре тем (см. hook_theme), так как она подменяет уже зарегистрированную там функцию темизации.

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

PS. Да сайт пока в разработке, так что критика в адрес контента и дизайна принимается но со скидкой на недоделанность ;)

Добавить комментарий
« Добавить комментарий
» Добавить комментарий