it-swarm.com.de

In den Feldformatierer eines anderen Moduls einbinden?

Ich versuche gerade, ein knotenreferenziertes Bildfeld auf meiner Drupal 7-Site) zu implementieren, das den Ansichtsmodus abhängig von der programmatischen Logik unmittelbar vor dem Rendern ändert. Das Feld wird derzeit auf einer Reihe von gerendert Inhaltstypen über ihre Anzeigemoduseinstellungen, von denen jeder den Feldformatierer 'Gerenderter Knoten' verwendet.

erster Versuch

Meine erste Idee war, Folgendes zu implementieren, wenn man bedenkt, dass ein Haken ein Haken ist:

function HOOK_field_formatter_view( $entity_type, $entity, $field ... ){
  switch ($display['type']) {
    case 'node_reference_node':
      /* Programatical logic here to modfy field render settings */
    break;
  }
}

Offensichtlich wird HOOK gegen den Namen meines Moduls ausgetauscht.

Es war nicht wirklich wichtig, ob das Obige vor oder nach der ursprünglichen Funktion node_reference_field_formatter_view In node_reference.module Ausgelöst wurde, da ich entweder die Ausgabe vollständig überschreiben oder hoffentlich die Werte vor dem Rendern ändern würde. Das einzige Problem ist, dass der obige Hook nur auf Modulbasis zu funktionieren scheint - d. H. Er ist nicht standortweit, sodass er für mein Modul im Grunde nicht ausgelöst wird.

Jetzt kann ich natürlich meinen eigenen Feldformatierer schreiben, um einen gerenderten Knoten auszugeben. Aber es scheint eine Verschwendung zu sein, wenn man bedenkt, dass es bereits eine gibt.

andere Ansätze

Meine anderen Ansätze waren HOOK_preprocess_node Und HOOK_preprocess_field, Aber ersteres enthält keine view_mode Informationen, und letzteres enthält mindestens 5 verschiedene komplizierte Strukturen, auf die sich alle beziehen eine view_mode - Eigenschaft auf verschiedenen Ebenen - und es fühlt sich ziemlich hackig an, jeden ihrer Werte ändern zu müssen. Selbst wenn ich bestimmte view_mode - Eigenschaften geändert habe, ändert sich das resultierende Bild nicht.

Frage

Kennt jemand eine saubere Möglichkeit, vor dem Rendern eines Feldformatierers (eines Contrib-Moduls) einzugreifen und seine Einstellungen pro Seitenanforderung zu ändern - d. H. Indem die Einstellungen für den permanenten Ansichtsmodus des tatsächlichen Inhaltstyps nicht geändert werden müssen?

9
Pebbl

In der Frage wird erwähnt, dass hook_field_formatter_view() nur im Ursprungsmodul aufgerufen wird, Sie jedoch den Besitz des Feldformatierers über hook_field_formatter_info_alter() übernehmen können.

Sie sollten in der Lage sein, den Schlüssel module des Formatierers auf MYMODULE zu setzen, wie:

function MYMODULE_field_formatter_info_alter(&$info) {
  $info['some_field_formatter']['module'] = 'MYMODULE';
}

Dann Sie können MYMODULE_field_formatter_view() implementieren und optional das vorhandene Modul durchlaufen, das es verarbeitet hat, um ein zu änderndes Element zu erhalten.

function MYMODULE_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  // Your custom logic
  $element = OTHER_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display);
  // Any alterations
}
11
Graham C

Ok, also wurde mir klar, warum meine Änderungen an #view_mode In hook_preprocess_node Und hook_preprocess_fields Nicht funktionierten. (Danke an Clive für den Hinweis, dass ich die Anwesenheit von #view_mode In hook_preprocess_node Völlig verpasst habe).

Mein Problem ergab sich aus der Tatsache, dass #view_mode Bereits verarbeitet und in die richtige #image_style - Eigenschaft konvertiert wurde - etwas, nach dem ich nicht gesucht hatte.

Trotzdem scheint das Ändern dieses Werts zu stark davon abhängig zu sein, in welchem ​​Hook Sie ihn geändert haben. Endlich funktioniert jedoch Code, der das gerenderte Bild tatsächlich ändert:

function HOOK_preprocess_field( &$vars ){
  $element     = &$vars['element'];
  $entity_type = !empty($element['#entity_type']) ? $element['#entity_type'] : 'unknown';
  $bundle      = !empty($element['#bundle'])      ? $element['#bundle']      : 'unknown';
  $view_mode   = !empty($element['#view_mode'])   ? $element['#view_mode']   : 'unknown';
  $field_name  = !empty($element['#field_name'])  ? $element['#field_name']  : 'unknown';
  switch ( "$entity_type:$view_mode:$bundle/$field_name" ) {
    case 'node:full:mlandingpage/field_lead_image':
      if ( !empty($vars['items']) && 
           ($subelement = &$vars['items'][0]) ) {
        if ( !empty($subelement['field_image']) && 
             ($subfield = &$subelement['field_image'][0]) ) {
          /// this needs to be set to the image_style value, not the view_mode value.
          $subfield['#image_style'] = 'grid-normal-4-cols';
        }
      }
    break;
  }
}

Das Obige fühlt sich immer noch nicht sehr eloquent an, aber es funktioniert zumindest. Ich nehme Clives Wort auf die Tatsache, dass es eine solche _alter-Methode für Feldformatierer nicht gibt - es ist eine Schande, dass Formatierer ein äußerst leistungsfähiges Merkmal von D7 sind. Es wäre schön, mehr Erweiterungsmöglichkeiten zu haben.

Wie auch immer, wenn zukünftige Leute bessere Ideen haben, antworte :)

2
Pebbl

Am einfachsten ist es, Panelizer zu verwenden.

Wenn Sie Panelizer nicht verwenden, aber standardmäßig Drupal Ansichtsmodi oder Display Suite), versuchen Sie hook_field_display_alter () oder hook_field_display_ENTITY_TYPE_alter () .

Sie haben Entität, Anzeigekontext sowie alle Formatierungseinstellungen dort. Und Sie können die Einstellungen für das Rendern von Feldern einfach ändern. Sie können den Feldformatierer sogar in einen anderen ändern.

Der Ansatz funktioniert perfekt für mich. Der einzige Nachteil ist, dass Sie möglicherweise mit unterschiedlichen Einstellungen in der Benutzeroberfläche "Anzeige verwalten" verwechselt werden.

0
milkovsky

https://www.drupal.org/node/2130757 Es gibt ein gutes Beispiel. hook_field_formatter_third_party_settings_form () ist nützlich, um die Form des vorhandenen Feldformatierers zu ändern.

Dies funktioniert jedoch nicht mit Feldgruppen.

0
Pierre Noel