Как работает hook_theme ()? - PullRequest
       4

Как работает hook_theme ()?

8 голосов
/ 12 октября 2011

Мне трудно понять, что делает hook_theme () .

Насколько я понимаю, это как-то связано с возможностью переопределения шаблонов.

Я смотрел на:

  $theme_hooks = array(
    'poll_vote' => array(
      'template' => 'poll-vote',
      'render element' => 'form',
    ),
    'poll_choices' => array(
      'render element' => 'form',
    ),
    'poll_results' => array(
      'template' => 'poll-results',
      'variables' => array('raw_title' => NULL, 'results' => NULL, 'votes' => NULL, 'raw_links' => NULL, 'block' => NULL, 'nid' => NULL, 'vote' => NULL),
    ),
    'poll_bar' => array(
      'template' => 'poll-bar',
      'variables' => array('title' => NULL, 'votes' => NULL, 'total_votes' => NULL, 'vote' => NULL, 'block' => NULL),
    ),
  );

Не могли бы вы привести пример, как это работает?

Ответы [ 3 ]

22 голосов
/ 12 октября 2011

Он позволяет модулю определять его тем, которые затем могут быть переопределены любым другим модулем / темой. Это также даст возможность любому модулю использовать хук, такой как mymodule_preprocess_theme_name, для изменения переменных, передаваемых возможной функции темы или файлу шаблона.

Существует два основных способа инициализации функции темы:

theme('poll_results', array('raw_title' => 'title', 'results' => $results, etc...));

и

$build = array(
  '#theme' => 'poll_results',
  '#raw_title' => 'title',
  '#results' => $results,
  etc...
); // Note the '#' at the beginning of the argument name, this tells Drupal's `render` function that this is an argument, not a child element that needs to be rendered.

$content = render($build); // Exact equivalent of calling the previous example now that you have a render array.

Пожалуйста, имейте в виду, что вам следует избегать прямого вызова theme () (согласно документации в theme.inc), так как это:

  • Обход кэширования.
  • Обходит значения по умолчанию для типов, определенных в hook_element_info (), включая присоединенные активы
  • Обходит этапы pre_render и post_render.
  • Обход JavaScript сообщает информацию.

В Drupal 8 theme () является закрытой функцией _theme (). Для получения более подробной информации см. www.drupal.org / node / 2173655 .

Если вы сравните эти два элемента с элементом poll_results в приведенном выше примере, вы, вероятно, сможете понять, что происходит ... поскольку PHP не является строго типизированным языком, Drupal предоставляет «именованные аргументы» через массив ключей, передаваемый в функцию theme, или как хешированные ключи в массиве рендеринга.

Что касается 'render element', то это в основном говорит системе тем, что эта функция темы будет вызываться с использованием массива render, с одним именованным аргументом (в данном случае form). Код будет выглядеть примерно так:

$build = array(
  '#theme' => 'poll_choices',
  '#form' => $form
);

Это передаст все, что в переменной $form, функции темы как единственный аргумент.

Относительно клавиши template:

'poll_vote' => array(
  'template' => 'poll-vote',
  'render element' => 'form',
)

определяет тему с именем poll_vote, в которой используется файл шаблона (отсюда и ключ template) с именем poll-poll.tpl.php (это условно). Путь к этому файлу шаблона будет найден с помощью пути к модулю, который его реализует (например, modules / poll / poll-voice.tpl.php), поэтому файлы шаблона можно размещать в подпапках основной папки модуля. .

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

Файлы шаблонов предпочтительнее, если у вас есть достаточный объем HTML для вывода по теме, или вам просто не нравится писать HTML в строках внутри PHP (лично я этого не делаю). Однако в любом случае переменные, передаваемые при вызове темы (либо с использованием theme(), либо с помощью массива рендеринга, как описано выше), сами передаются в файл шаблона или функцию темы. Итак:

function theme_poll_results(&$vars) {
  $raw_title = $vars['raw_title'];
  $results = $vars['results'];
  // etc...
}

Если бы вы использовали файл шаблона вместо этого же метода, переменные были бы доступны как $raw_title, $results и т. Д., Так как Drupal запускает extract на $vars перед синтаксическим анализом файла шаблона.

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

3 голосов
/ 13 марта 2012

Drupal 6

Я застрял весь день с этим и теперь успешно реализован, поэтому, поделившись своими выводами здесь, может, это поможет понять hook_theme.

Есть 3 шага:

  1. hook_theme

    function YOURMODULENAME_theme() {
      return array(
        'xxx_xxx' => array(
        'template' => 'xxx-xxx', // define xxx-xxx.tpl.php inside module
        'arguments' => array('xxx' => null), //define $xxx so it will available in your xxx-xxx.tpl.php
        ),
      );
    }
    
  2. echo / return тема в вашей .tpl или любая .module

    $output = theme('xxx_xxx', $xxx);
    
  3. Теперь переменные магически доступны в вас xxx-xxx.tpl.php.

    <?php echo $xxx ?>
    

Примечание: вы можете передать $ xxx как массив, объект или что-то еще:)

0 голосов
/ 19 ноября 2013

Есть еще один способ: (можно найти в теме Bartik)

Сценарий здесь таков, что мы создали наш собственный модуль и хотим переопределить вывод по умолчанию, скажем, для узла с заголовком 'zzz'only.
Мы не знаем и на самом деле не заботимся о том, как генерируется вывод по умолчанию.Все, что нам нужно, это указать Drupal использовать наш собственный файл шаблона (node ​​- custom - name.tpl.php) для рендеринга этого конкретного узла.

Это шаги:

  1. Сообщите Drupal, где находится наш файл шаблона.(Помните, что эта функция вступит в силу только один раз и после очистки кеша Drupal):

    // Implements hook_theme()
    function mymodulename_theme() { 
      $theme = array();
      $theme['node__custom__name'] = array(
        'render element' => 'node',
        'template' => 'path_from_mymodule_root/node__custom__name',
        );
      return $theme;
    }
    
  2. Сообщите Drupal, где и когда его использовать

    //Implements hook_preprocess_node()
    function mymodulename_preprocess_node($vars) {
        if($vars['node']->title == 'zzzz') {
            $vars['theme_hook_suggestions'][] = 'node__custom__name';
            ... your other code ...
         }
     }
    

    Теперь Drupal будет использовать наш файл шаблона только для этого конкретного случая, при условии, что файл 'node-custom-name.tpl.php' находится в объявленном пути, в противном случае он продолжит поиск в соответствии с соглашениями по именованию предложений для запасного варианта.шаблон.

...