Variablen von der HTML-Vorverarbeitungsfunktion an die Seitenvorverarbeitungsfunktion übergeben?

10

In meinen benutzerdefinierten Themen hook_preprocess_page()und hook_preprocess_html()Funktionen muss ich häufig dieselben Informationen identifizieren. Anstatt im Wesentlichen dasselbe auszuführen, wenn die Anweisung beide eingecheckt hat, um die gleichen Informationen zu identifizieren, wäre es viel sinnvoller, dies nur einmal in beiden zu tun und diese Informationen dann an die andere Vorverarbeitungsfunktion zu übergeben. Wie kann ich das machen? Ich habe Folgendes versucht, aber es hat nicht funktioniert:

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

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

Ich habe es auch umgekehrt versucht (den Wert in der HTML-Vorverarbeitungsfunktion festlegen und dann in der Seitenvorverarbeitungsfunktion abrufen), aber das hat auch nicht funktioniert. Was eine verwandte Frage aufwirft: In welcher Reihenfolge werden diese Vorverarbeitungsfunktionen verarbeitet? Es scheint mir, dass die Seitenvorverarbeitungsfunktion vor der HTML-Funktion steht. Ist das richtig?

Maxedison
quelle

Antworten:

14

Sie benötigen entweder eine globaloder eine staticVariable, um dies zu erreichen. Ich persönlich würde empfehlen, staticeine generische Hilfsfunktion zu verwenden und zu implementieren, indem Sie das statische Muster von Drupal wie folgt verwenden:

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
}

Die $varsArrays für jede Vorverarbeitungsfunktion sind völlig unterschiedliche Objekte im Speicher, sodass Sie dieses Array nicht zum Weitergeben von Dingen verwenden können. Ich habe gesehen, dass diese Art von Muster im Drupal-Kern häufig verwendet wird, daher denke ich, dass dies der beste Weg wäre.

BEARBEITEN

Oh und ja, hook_preprocess_page()wird vorher aufgerufen hook_preprocess_html()... soweit ich weiß, arbeitet Drupal auf eine Art "von innen nach außen", also hook_preprocess_html()wäre es wahrscheinlich die letzte, die in einem Seitenaufbau ausgeführt wird.

Clive
quelle
3

Ich habe dies mit einem ähnlichen Fall von 'Knoten' und 'Seite' erreicht, indem ich Folgendes getan habe:

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

Ich würde mir also vorstellen, dass es stattdessen ähnlich mit 'page' und 'html' funktioniert.

Jimajamma
quelle
Ja, das würde funktionieren. Aber es ist nicht sehr effizient, weil diese $ vars, die irgendeine Art von Verarbeitung benötigen, diese Verarbeitung mehrmals durchführen lassen würden.
Maxedison
stimmt, wenn es etwas Schwergewichtiges zwischen Vorverarbeitungsfunktionen ist, wie das Setzen einer Variablen auf ein komplexes SQL-Ergebnis, ja, Sie möchten es wahrscheinlich nicht mehrmals tun, aber das lässt sich leicht mit einer static Verarbeitung wie der ersten Antwort lösen . Die Einstellungen für geringes Gewicht sind möglicherweise sogar schneller, da Sie nicht für jeden Variablensatz den Funktionsaufruf-Overhead haben, sondern nur beim ersten Aufruf der Hauptfunktion. Und natürlich werden die Hauptteile (Knoten & Seite) nur einmal gesetzt.
Jimajamma