将变量从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...
}

我还尝试了另一种方法(在preprocess html函数中设置值,然后在页面preprocess函数中检索它),但这也不起作用。哪个提出了一个相关的问题:这些预处理功能按什么顺序处理?在我看来,页面预处理功能位于html之前,是正确的吗?

Answers:


14

您将需要a globalstatic变量来完成此操作...个人而言,我建议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每个预处理函数的数组都是内存中完全不同的对象,因此您将无法使用该数组来传递事物。我已经看到这种模式在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;
  }
}

因此我想它可以与'page'和'html'类似地工作。


是的,那行得通。但这不是很有效,因为那些需要某种处理的$ vars将多次处理。
maxedison 2012年

是的,如果在预处理功能之间有一个重量级的共同点,例如将变量设置为一些复杂的sql结果,是的,您可能不想多次执行此操作,但这可以通过static 第一个答案之类的处理轻松解决。轻量级设置实际上可能会更快,因为您没有每个主变量集的函数调用开销,这只是第一次从主函数中调用。显然,主要部分(节点和页面)仅设置一次。
Jimajamma 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.