Передать переменные из функции предварительной обработки HTML в функцию предварительной обработки страницы?

10

В моей пользовательской теме hook_preprocess_page()и hook_preprocess_html()функциях мне часто нужно идентифицировать одну и ту же информацию. Вместо того, чтобы выполнять один и тот же if, если оператор проверяет оба идентификатора, идентифицируют одну и ту же информацию, было бы гораздо разумнее просто сделать это один раз для обоих, а затем передать эту информацию другой функции предварительной обработки. Как я могу это сделать? Я попробовал следующее, но это не сработало:

function myTheme_preprocess_page(&$vars){
    $vars['myValue'] = 7;
}

function myTheme_preprocess_html(&$vars){
    //$vars['myValue'] should equal 7...
}

Я также попробовал это наоборот (установил значение в функции предварительной обработки html, а затем извлек его в функции предварительной обработки страницы), но это тоже не сработало. В связи с этим возникает вопрос: в каком порядке обрабатываются эти функции предварительной обработки? Мне кажется, что функция предварительной обработки страницы предшествует HTML, это правильно?

maxedison
источник

Ответы:

14

Для этого вам понадобится либо переменная, globalлибо staticпеременная ... лично я бы порекомендовал пойти staticи реализовать универсальную вспомогательную функцию, используя статический шаблон Drupal, например:

function _myTheme_var($var_name, $new_val = NULL) {
  $vars = &drupal_static(__FUNCTION__, array());

  // If a new value has been passed
  if ($new_val) {
    $vars[$var_name] = $new_val;
  }

  return isset($vars[$var_name]) ? $vars[$var_name] : NULL;
}

function myTheme_preprocess_page(&$vars){
  $vars['some_var'] = _myTheme_var('my_var', 7); // Set the value and retrieve it
}

function myTheme_preprocess_html(&$vars){
  $vars['some_var'] = _myTheme_var('my_var'); // Get the value
}

В $varsмассивах для каждой функции Preprocess совершенно разные объекты в памяти , так что вы не сможете использовать этот массив , чтобы передать вещи вокруг. Я видел, как этот тип паттернов часто используется в ядре Drupal, поэтому я думаю, что это будет наилучшим способом.

РЕДАКТИРОВАТЬ

О и да, hook_preprocess_page()вызывается раньше hook_preprocess_html()... насколько я знаю, Drupal работает в некотором роде "наизнанку", поэтому hook_preprocess_html(), вероятно, будет последним, который запускается в сборке страницы.

Клайв
источник
3

Я выполнил это с похожим случаем «узел» и «страница», выполнив:

function mymodule_preprocess_node(&$vars) {
  _mymodule_preprocess_vars($vars,'node');
}

function mymodule_preprocess_page(&$vars) {
  _mymodule_preprocess_vars($vars,'page');
}

function _mymodule_preprocess_vars(&$vars, $where) {

  // all vars common to both node and page set here

  switch($where) {

    case 'node':

      // node only vars set here;

      break;

    case 'page':

      // page only vars set here;

      break;
  }
}

поэтому я думаю, что он будет работать аналогично с «страницы» и «HTML» вместо.

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