Passer des variables de la fonction de prétraitement html à la fonction de prétraitement de la page?

10

Dans mes thèmes hook_preprocess_page()et hook_preprocess_html()fonctions personnalisés, j'ai souvent besoin d'identifier les mêmes informations. Plutôt que d'exécuter essentiellement la même chose si l'instruction vérifie les deux identifient les mêmes informations, il serait beaucoup plus logique de le faire une seule fois dans les deux, puis de transmettre ces informations à l'autre fonction de prétraitement. Comment puis-je faire ceci? J'ai essayé ce qui suit mais cela n'a pas fonctionné:

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

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

Je l'ai également essayé dans l'autre sens (en définissant la valeur dans la fonction html de prétraitement puis en la récupérant dans la fonction de prétraitement de la page), mais cela n'a pas fonctionné non plus. Ce qui soulève une question connexe: dans quel ordre ces fonctions de prétraitement, euh, sont-elles traitées? Il me semble que la fonction de prétraitement des pages précède celle en html, est-ce correct?

maxedison
la source

Réponses:

14

Vous aurez besoin d'un globalou d' une staticvariable pour accomplir cela ... personnellement, je recommanderais d'utiliser staticet d'implémenter une fonction d'assistance générique en utilisant le modèle statique de Drupal comme ceci:

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
}

Les $varstableaux pour chaque fonction de prétraitement sont des objets complètement différents en mémoire, vous ne pourrez donc pas utiliser ce tableau pour faire circuler les choses. J'ai vu ce genre de modèle utilisé beaucoup dans le noyau Drupal, donc je pense que ce serait la meilleure façon de procéder.

ÉDITER

Oh et oui, hook_preprocess_page()est appelé avant hook_preprocess_html()... pour autant que je sache, Drupal fonctionne d'une manière "à l'envers" donc ce hook_preprocess_html()serait probablement le dernier qui soit exécuté dans une page.

Clive
la source
3

J'ai accompli cela avec un cas similaire de 'nœud' et 'page' en faisant:

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

j'imagine donc que cela fonctionnerait de la même manière avec 'page' et 'html' à la place.

Jimajamma
la source
Oui, ça marcherait. Mais ce n'est pas très efficace car ces $ vars qui ont besoin d'une sorte de traitement feraient ce traitement plusieurs fois.
maxedison
Vrai, si c'est quelque chose de lourd en commun entre les fonctions de prétraitement, comme définir une variable sur un résultat SQL complexe, oui, vous ne voulez probablement pas le faire plusieurs fois, mais cela est facilement résolu avec un static traitement comme la première réponse. et les paramètres légers peuvent en fait être plus rapides car vous n'avez pas la surcharge d'appel de fonction pour chaque ensemble de variables, juste la première fois lors d'un appel à partir de la fonction principale. Et évidemment, les parties principales (nœud et page) ne sont définies qu'une seule fois.
Jimajamma