it-swarm.com.de

Vorverarbeitungsfunktion pro Inhaltstyp

Ich habe einige Inhaltstypen, die ich auf unterschiedliche Weise vorverarbeiten muss. Damit template.php in meinem Thema foo sieht derzeit so aus:

function foo_preprocess_node(&$variables) {
    if ('news' ==$variables['type']) _preprocess_news($variables);
    if ('event'==$variables['type']) _preprocess_event($variables);
    if ('alert'==$variables['type']) _preprocess_alert($variables);
    ...
}

function _preprocess_news(&$variables) {
    ...
}

function _preprocess_event(&$variables) {
    ...
}

function _preprocess_alert(&$variables) {
    ...
}

Ich möchte in der Lage sein, eine Drupal -spezifische Vorverarbeitungsfunktion anzugeben, die den Computernamen des Inhaltstyps verknüpft. Ich habe versucht, foo_preprocess_news aber es wird nie aufgerufen.

Gibt es einen besseren Weg?

24
cherouvim

Der Name der Vorverarbeitungsfunktion basiert auf dem Namen des Themas. Für theme_table() lautet Ihre Vorverarbeitungsfunktion also MYTHEME_preprocess_table().

Da es keine theme_node_node_type - Funktion gibt, funktioniert ein Vorverarbeitungs-Hook wie foo_preprocess_news Oder foo_preprocess_node_news Nicht sofort.

Sie könnten die Themenregistrierung überschreiben, damit sie sich für Knoten anders verhält, aber ich würde es wirklich nicht empfehlen; es könnte sehr chaotisch werden.

Ich bin ein großer Fan von Refactoring-Code, aber in Ihrem Fall denke ich nicht, dass dies notwendig ist. Wenn Sie eine komplexe Logik haben, die abhängig vom Knotentyp in Ihrem Vorverarbeitungs-Hook ausgeführt werden muss, erscheint es mir als gute Praxis, sie auf die von Ihnen derzeit verwendete Weise auf verschiedene Funktionen zu verteilen.

Die andere Methode wäre natürlich, ein benutzerdefiniertes Modul für jeden der verschiedenen Inhaltstypen zu implementieren und hook_preprocess_node() in jedem zu implementieren. Auf diese Weise kann die Vorverarbeitungsfunktion jedes Moduls für einen anderen Inhaltstyp verantwortlich sein.

Dies kann jedoch für Ihre Situation übertrieben sein. Wenn Sie keine zusätzliche Logik (d. h. keine themenbezogene Vorverarbeitungslogik) für jeden Inhaltstyp haben, fügt diese Methode wahrscheinlich keinen zusätzlichen Wert hinzu.

10
Clive

Das Zen-Unterthema erreicht dies, indem es dies zu seiner Funktion theme_preprocess_node hinzufügt:

function foo_preprocess_node(&$variables, $hook) {
  ...
    // Optionally, run node-type-specific preprocess functions, like
  // foo_preprocess_node_page() or foo_preprocess_node_story().
  $function = __FUNCTION__ . '_' . $variables['node']->type;
  if (function_exists($function)) {
    $function($variables, $hook);
  } 
  ...
}

Wenn Sie einen Inhaltstyp namens "news" haben, können Sie eine Funktion namens "foo_preprocess_node_news" in Ihrer Datei template.php erstellen.

31
Evil E

Ich hatte gerade ein ähnliches Problem , weshalb Google mich auf diese Seite brachte: Meine Knotenvorverarbeitungsfunktion wurde so enorm groß, dass ich mich lieber aufteilen würde die Funktion in mehrere Dateien.

Ich habe bereits einen ähnlichen Ansatz in meiner Datei template.php gemacht, die alle Änderungsfunktionen enthält, und da dieselbe Methode hier perfekt funktioniert, dachte ich, ich würde meinen Ansatz teilen:

Dateisetup im Ordner MYTHEME/preprocess:

- node.preprocess.inc
- node--blog-post.preprocess.inc
- node--device-variation.preprocess.inc
- (...)

sie sollten bereits node.preprocess.inc haben, die anderen können Sie selbst erstellen. Wie Sie sie wirklich nennen, ist eher willkürlich, aber geben Sie ihnen besser Namen, die sie gut identifizieren und zum gesamten drupal-Benennungssystem) passen.
weiter zum Inhalt dieser Dateien!

node.preprocess.inc, hier mache ich so etwas:

<?php

function MYTHEME_preprocess_node(&$variables) {

    switch($variables['type']) {

      case 'blog_post':
        // if the type of the node is a Blog Post, include this:
        include 'node--blog-post.preprocess.inc';
        break;

      case 'device_variation':
        // if Device Variation, include this:
        include 'node--device-variation.preprocess.inc';
        break;

      case 'foo':
        // ...
        break;
    }

    // additional stuff for all nodes

}

wir wechseln grundsätzlich durch den Typ des aktuellen Knotens. Was Sie durchschalten, liegt bei Ihnen. #id, #view_mode, Alles abhängig von Ihren genauen Anforderungen.
Sobald eine Übereinstimmung vorliegt, wird die angegebene Datei geladen und auf ihren Inhalt so reagiert, als ob sie direkt in diese Funktion geschrieben worden wäre.

der Inhalt dieser included -Dateien sieht genauso aus, als würden Sie ihn in die Datei node.preprocess.inc einfügen, außer dass wir die Vorverarbeitungsfunktion nicht erneut aufrufen:

node--device-variation.preprocess.inc

<?php

    // Device Name
    $device = drupal_clean_css_identifier(strtolower($variables['title']));

    // Determine whether only Device Version is of type 'N/A' and set ppvHasVariations accordingly
    $deviceHasVariations = true;
    if( $variables['content']['product:field_model_variation'][0]['#options']['entity']->weight == 0 ) {
        $deviceHasVariations = false;
    }
    //...

sie können dies grundsätzlich mit so vielen Dateien tun, wie Sie möchten, und sogar mehrere Switches kaskadieren, z. B. bestimmte Knotenvorverarbeitungsdateien je nach #view_mode weiter aufteilen und eine Datei für den Ansichtsmodus full haben und eine andere für die teaser

ich hoffe, das hilft, sollte jemand jemals wieder auf diese Frage stoßen (:

2
Bird-Kid

Implementieren Sie in Ihrem Haupt-Hook_preprocess_node am Ende den folgenden Code

$preprocess_function = 'themename_node__' . $node->type . '__preprocess';
if (function_exists($preprocess_function)) {
 $preprocess_function($variables);
}

Sie hätten also jetzt nach Knotentyp vorverarbeitet

1
Ziftman

call_user_func() übergibt keine Parameter als Referenz. Im Fall von $variables Funktionieren Ihre preprocess_foo() -Funktionen nur für Kopien des ursprünglichen Arrays. Änderungen an Nichtobjekten werden während des verbleibenden Rendervorgangs nicht übernommen.

1
kishkash