¿Pasar variables de la función de preproceso html a la función de preproceso de página?

10

En mis temas hook_preprocess_page()y hook_preprocess_html()funciones personalizados, a menudo necesito identificar la misma información. En lugar de ejecutar esencialmente lo mismo si la instrucción verifica tanto la identificación de la misma información, tendría mucho más sentido hacerlo una vez en ambos y luego pasar esa información a la otra función de preproceso. ¿Cómo puedo hacer esto? Intenté lo siguiente pero no funcionó:

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

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

También lo intenté al revés (estableciendo el valor en la función html de preproceso y luego recuperándolo en la función de preproceso de página) pero tampoco funcionó. Lo que plantea una pregunta relacionada: ¿en qué orden se procesan estas funciones de preproceso? Me parece que la función de preproceso de la página viene antes que la html, ¿es correcto?

maxedison
fuente

Respuestas:

14

Necesitará una variable globalo una staticvariable para lograr esto ... personalmente, recomendaría ir statice implementar una función auxiliar genérica utilizando el patrón estático de Drupal de esta manera:

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
}

Las $varsmatrices para cada función de preproceso son objetos completamente diferentes en la memoria, por lo que no podrá usar esa matriz para pasar cosas. He visto que este tipo de patrón se usa mucho en el núcleo de Drupal, así que creo que sería la mejor manera de hacerlo.

EDITAR

Ah, sí, hook_preprocess_page()se llama antes hook_preprocess_html()... por lo que sé, Drupal funciona de una manera "de adentro hacia afuera", por hook_preprocess_html()lo que probablemente sea el último que se ejecute en la construcción de una página.

Clive
fuente
3

Logré esto con un caso similar de 'nodo' y 'página' haciendo:

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

así que me imagino que funcionaría de manera similar con 'page' y 'html' en su lugar.

Jimajamma
fuente
Sí, eso funcionaría. Pero no es muy eficiente porque esos $ vars que necesitan algún tipo de procesamiento harían ese procesamiento varias veces.
maxedison
Es cierto, si es algo pesado en común entre las funciones de preproceso, como establecer una variable en algún resultado sql complejo, sí, probablemente no desee hacerlo varias veces, pero eso se resuelve fácilmente con algún static procesamiento como la primera respuesta. y la configuración de peso ligero en realidad podría ser más rápida ya que no tiene la sobrecarga de llamadas de función para cada conjunto de variables, solo la primera vez que llama desde la función principal. Y, obviamente, las partes principales (nodo y página) solo se configuran una vez.
Jimajamma