Passar variáveis ​​da função de pré-processo html para a função de pré-processo de página?

10

Nos meus temas hook_preprocess_page()e hook_preprocess_html()funções personalizados, geralmente preciso identificar as mesmas informações. Em vez de executar essencialmente a mesma instrução if, verifica as mesmas informações, faria muito mais sentido fazê-lo apenas uma vez nos dois e depois passar essas informações para a outra função de pré-processo. Como posso fazer isso? Eu tentei o seguinte, mas não funcionou:

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

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

Também tentei o contrário (definir o valor na função html de pré-processo e depois recuperá-lo na função de pré-processo de página), mas isso também não funcionou. O que levanta uma questão relacionada: em que ordem essas funções de pré-processo são processadas? Parece-me que a função de pré-processamento da página vem antes da html, está correta?

maxedison
fonte

Respostas:

14

Você vai precisar de uma variável globalou staticpara fazer isso ... pessoalmente, eu recomendaria ir statice implementar uma função auxiliar genérica usando o padrão estático do Drupal da seguinte maneira:

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
}

As $varsmatrizes para cada função de pré-processo são objetos completamente diferentes na memória, assim você não poderá usar essa matriz para distribuir as coisas. Já vi esse tipo de padrão usado muito no núcleo do Drupal, então acho que seria o melhor caminho a percorrer.

EDITAR

Ah, e sim, já hook_preprocess_page()foi chamado antes hook_preprocess_html()... até onde sei, o Drupal funciona de uma maneira "de dentro para fora", então hook_preprocess_html()provavelmente seria o último executado em uma compilação de página.

Clive
fonte
3

Eu consegui isso com um caso semelhante de 'node' e 'page' fazendo:

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;
  }
}

então eu imagino que funcionaria da mesma forma com 'page' e 'html'.

Jimajamma
fonte
Sim, isso funcionaria. Mas não é muito eficiente, porque os $ vars que precisam de algum tipo de processamento teriam esse processamento feito várias vezes.
maxedison
verdade, se há algo em comum entre as funções de pré-processo, como definir uma variável para algum resultado sql complexo, sim, você provavelmente não deseja fazer isso várias vezes, mas isso é facilmente resolvido com algum static processamento como a primeira resposta. e as configurações de peso leve podem realmente ser mais rápidas, pois você não tem a sobrecarga da chamada de função para cada conjunto de variáveis, apenas a primeira vez em que chama da função principal. E, obviamente, as principais partes (nó e página) são definidas apenas uma vez.
precisa saber é o seguinte