Agganciare il formattatore di campo di altri moduli?


9

Attualmente sto cercando di implementare un campo immagine di riferimento nodo sul mio sito Drupal 7 che cambierà la sua 'modalità di visualizzazione' a seconda della logica programmatica appena prima del rendering. Il campo è attualmente in fase di rendering su un numero di tipi di contenuto tramite le impostazioni della modalità di visualizzazione, ciascuno dei quali utilizza il formatter del campo "Nodo reso".

primo tentativo

La mia prima idea è stata quella di implementare quanto segue, considerando che un hook è un hook è un hook:

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

Ovviamente lo scambio di HOOK con il nome del mio modulo.

Non importa se quanto sopra sparerebbe prima o dopo la funzione originale node_reference_field_formatter_view in node_reference.modulequanto avrei neanche ignorare il suo output in tutto o, si spera, modificarne i valori prima del rendering. L'unico problema è che l'hook sopra sembra funzionare solo su base per modulo - cioè non è a livello di sito, quindi sostanzialmente non funziona per il mio modulo.

Ora ovviamente posso scrivere il mio formattatore di campo per generare un nodo renderizzato. Ma sembra un po 'uno spreco considerando che ce n'è già uno che esiste.

altri approcci

I miei altri approcci sono stati HOOK_preprocess_nodee, HOOK_preprocess_fieldma il primo non contiene alcuna view_modeinformazione, e il secondo contiene almeno 5 diverse strutture complicate che hanno tutti riferimenti a una view_modeproprietà a diversi livelli - e sembra piuttosto sconclusionato dover modificare ognuna delle loro valori. Anche quando ho modificato alcune view_modeproprietà l'immagine risultante non cambia.

domanda

Qualcuno sa un modo chiaro per intervenire prima che un renderizzatore di formattazione di campo (di un modulo contrib) e modificare le sue impostazioni in base alla richiesta per pagina - cioè non dover cambiare le impostazioni della modalità di visualizzazione permanente del tipo di contenuto effettivo?


2
Sto cercando un hook_field_formatter_view_alter()o simile probabilmente da oltre un anno, purtroppo non esiste. FYI hook_preprocess_node()sicuramente non ha view_modea sua disposizione, è in $vars['view_mode'], non $vars['node']->view_modeche si potrebbe avere avuto la tentazione di provare.
Clive

@Clive grazie per le informazioni, oh e per aver sottolineato l' view_modeacceso hook_preprocess_node, sciocco me! Mi chiedo se hook_field_formatter_view_alter()esiste qualcosa del genere in D8 ...
Pebbl,

Non ho ancora visto nulla ... ma poi tutto viene convertito in plugin in D8 (non sono sicuro dei campi), quindi potrebbe essere che tu possa semplicemente ignorare una classe esistente per fare il lavoro, sarebbe l'ideale . Spero!
Clive

1
@Clive, hai trovato il tuo uncino magico menzionato qui per D7?
tyler.frankenstein,

Risposte:


11

La domanda menziona hook_field_formatter_view()solo il modulo di origine, ma puoi diventare proprietario del formattatore di campo tramitehook_field_formatter_info_alter() .

Dovresti essere in grado di impostare la modulechiave del formattatore su MYMODULE come:

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

Quindi è possibile implementare MYMODULE_field_formatter_view(), facoltativamente alimentando il modulo esistente che lo ha gestito per ottenere un elemento da modificare.

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
}

Puoi approfondire la tua risposta? Fornire un codice?
Scott Joudry,

Bella soluzione, non penso quasi mai di impossessarmi completamente del business di un altro modulo (e di tornare indietro dopo le modifiche) ... ma l'ho appena provato e finisco con un codice molto più semplice. Saluti!
Pebbl

1
@ScottJoudry ~ potrebbe valere la pena notare che se si subentra in questo modo è necessario assicurarsi di disporre dei metodi per tutte le field_formatterfunzionalità di node_reference ovvero MYMODULE_field_formatter_settings_summarye MYMODULE_field_formatter_settings_form(anche se sono solo funzioni proxy al modulo originale), altrimenti il ​​back- l'interfaccia utente finale si interrompe su qualsiasi pannello della modalità di visualizzazione, quando ha cercato di trovare questi metodi nel modulo sbagliato.
Pebbl,

L'approccio di Graham C è interessante, ma richiede troppe sostituzioni.
milkovsky

2

Ok, quindi ho capito perché i miei cambiamenti #view_modein entrambi hook_preprocess_nodee hook_preprocess_fieldsnon funzionavano. (Grazie a Clive per aver sottolineato che mi ero completamente perso la presenza di #view_modein hook_preprocess_node) .

Il mio problema derivava dal fatto che #view_modeera già stato elaborato e convertito nella #image_styleproprietà corretta - qualcosa che avevo trascurato di cercare.

Anche così, la modifica di questo valore sembra dipendere troppo dal tipo di hook in cui è stato modificato. Alla fine ho comunque funzionato del codice, che in realtà cambia l'immagine renderizzata:

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

Quanto sopra non sembra ancora molto eloquente, ma almeno funziona. Prenderò la parola di Clive sul fatto che un tale metodo alterato non esiste per i formattatori di campo - è un peccato, i formattatori sono una funzione estremamente potente di D7, sarebbe bello avere più capacità di potenziamento.

Ad ogni modo, se qualche persona futura ha idee migliori, rispondi :)


0

L'approccio più semplice sarà l'utilizzo del Panelizer .

Se non usi Panelizer ma le modalità di visualizzazione Drupal predefinite o Display Suite, prova hook_field_display_alter () o hook_field_display_ENTITY_TYPE_alter () .

Hai un'entità, visualizza il contesto e tutte le impostazioni del formatter lì. E puoi facilmente modificare le impostazioni di rendering dei campi. Puoi anche cambiare il formattatore del campo con uno diverso.

L'approccio funziona perfettamente per me. L'unico svantaggio è che potresti essere confuso con impostazioni diverse nell'interfaccia utente "Gestisci display".


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.