Czy przekazać zmienne z funkcji wstępnego przetwarzania HTML do funkcji wstępnego przetwarzania strony?

10

W moim niestandardowym motywie hook_preprocess_page()i hook_preprocess_html()funkcjach często muszę identyfikować te same informacje. Zamiast zasadniczo uruchamiać to samo, jeśli instrukcja sprawdza zarówno identyfikację tych samych informacji, o wiele bardziej sensowne byłoby po prostu zrobienie tego raz w obu z nich, a następnie przekazanie tych informacji do innej funkcji wstępnego przetwarzania. W jaki sposób mogę to zrobić? Próbowałem następujące, ale to nie działało:

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

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

Próbowałem też na odwrót (ustawienie wartości w funkcji HTML preprocessu, a następnie pobranie jej w funkcji preprocesu strony), ale to też nie działało. Które rodzi powiązane pytanie: w jakiej kolejności są przetwarzane te funkcje preprocesowania? Wydaje mi się, że funkcja wstępnego przetwarzania strony jest dostępna przed HTML, prawda?

maxedison
źródło

Odpowiedzi:

14

Będziesz potrzebował zmiennej globallub staticzmiennej, aby to osiągnąć ... osobiście poleciłbym pójście statici implementację ogólnej funkcji pomocniczej przy użyciu statycznego wzorca Drupala, takiego jak:

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
}

Te $varstablice dla każdej funkcji Preprocesuj są zupełnie różne obiekty w pamięci, więc nie będzie w stanie wykorzystać tę tablicę przejść rzeczy wokół. Widziałem taki wzór często używany w rdzeniu Drupala, więc myślę, że byłby to najlepszy sposób.

EDYTOWAĆ

No i tak, hook_preprocess_page()jest wywoływany wcześniej hook_preprocess_html()... o ile wiem, Drupal działa w sposób „wywrotowy”, więc hook_preprocess_html()prawdopodobnie byłby to ostatni, który jest uruchamiany w kompilacji strony.

Clive
źródło
3

Dokonałem tego w podobnym przypadku „węzła” i „strony”, wykonując:

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

więc wyobrażam sobie, że działałoby podobnie z „page” i „html”.

Jimajamma
źródło
Tak, to by zadziałało. Ale to nie jest bardzo wydajne, ponieważ te $ vars, które wymagają jakiegoś przetwarzania, przetworzyłyby je wielokrotnie.
maxedison
prawda, jeśli jest to coś ciężkiego wspólnego między funkcjami wstępnego przetwarzania, jak ustawienie zmiennej na jakiś złożony wynik SQL, tak, prawdopodobnie nie chcesz robić tego wiele razy, ale łatwo to rozwiązać przy pomocy static przetwarzania takiego jak pierwsza odpowiedź. i lekkie ustawienia mogą być w rzeczywistości szybsze, ponieważ nie masz narzutu wywołania funkcji dla każdego zestawu zmiennych, tylko za pierwszym razem podczas wywoływania z funkcji głównej. I oczywiście główne części (węzeł i strona) są ustawiane tylko raz.
Jimajamma,