Hubungkan ke formatter bidang modul lain?


9

Saat ini saya mencoba untuk mengimplementasikan bidang gambar yang direferensikan simpul pada situs Drupal 7 saya yang akan mengubah itu 'mode tampilan' tergantung pada logika pemrograman sebelum render. Bidang saat ini sedang diberikan pada sejumlah jenis konten melalui pengaturan mode tampilan mereka, yang masing-masing menggunakan formatter bidang 'Rendered node'.

percobaan pertama

Ide pertama saya adalah menerapkan yang berikut ini, mengingat hook adalah hook adalah 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;
  }
}

Jelas bertukar HOOK dengan nama modul saya.

Ini tidak benar-benar peduli jika di atas akan memecat sebelum atau setelah fungsi asli node_reference_field_formatter_viewdi node_reference.modulekarena saya baik akan menimpa keluaran itu seluruhnya atau, mudah-mudahan, memodifikasi nilai-nilai sebelum rendering. Satu-satunya masalah adalah, pengait di atas tampaknya berfungsi hanya pada basis per modul - yaitu tidak di seluruh situs, jadi pada dasarnya itu tidak menyala untuk modul saya.

Sekarang jelas saya bisa menulis formatter bidang saya sendiri untuk menampilkan node yang diberikan. Tapi sepertinya agak sia-sia mengingat sudah ada yang ada.

pendekatan lain

Pendekatan saya yang lain adalah dengan HOOK_preprocess_nodedan HOOK_preprocess_fieldtetapi yang pertama tidak mengandung view_modeinformasi apa pun , dan yang terakhir mengandung setidaknya 5 struktur rumit yang berbeda yang semuanya memiliki referensi ke view_modeproperti di tingkat yang berbeda - dan rasanya agak tidak sopan harus memodifikasi masing-masing nilai-nilai. Bahkan ketika saya telah mengubah view_modeproperti tertentu , gambar yang dihasilkan tidak berubah.

pertanyaan

Adakah yang tahu cara bersih untuk masuk sebelum formatter bidang merender (modul kontrib) dan mengubah pengaturannya berdasarkan permintaan per halaman - yaitu dengan tidak harus mengubah pengaturan mode tampilan permanen jenis konten yang sebenarnya?


2
Saya sudah mencari hook_field_formatter_view_alter()atau serupa untuk mungkin lebih dari satu tahun sekarang, sayangnya tidak ada. FYI hook_preprocess_node()pasti tidak memiliki view_modetersedia untuk itu, itu di $vars['view_mode'], tidak $vars['node']->view_modemana Anda mungkin telah tergoda untuk mencoba.
Clive

Terima kasih @Clive untuk info, oh dan untuk menunjukkan yang view_modepada hook_preprocess_node, saya bodoh! Saya ingin tahu apakah hal seperti hook_field_formatter_view_alter()ini ada di D8 ...
Pebbl

Saya belum melihat apa-apa ... tapi kemudian semuanya dikonversi menjadi plugin di D8 (saya tidak yakin tentang bidang) jadi mungkin Anda bisa mengganti kelas yang ada untuk menyelesaikan pekerjaan, itu akan ideal . Inilah harapan!
Clive

1
@Clive, apakah Anda sudah menemukan hook alter ajaib Anda yang disebutkan di sini untuk D7?
tyler.frankenstein

Jawaban:


11

Pertanyaan itu menyebutkan bahwa hook_field_formatter_view()hanya dipanggil pada modul asal, tetapi Anda dapat mengambil kepemilikan formatter bidang melalui hook_field_formatter_info_alter().

Anda harus dapat mengatur modulekunci formatter ke MYMODULE seperti:

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

Kemudian Anda dapat menerapkan MYMODULE_field_formatter_view(), secara opsional memberi makan melalui modul yang ada yang menanganinya untuk mendapatkan elemen untuk diubah.

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
}

Bisakah Anda menguraikan jawaban Anda? Berikan beberapa kode?
Scott Joudry

Solusi yang bagus, saya hampir tidak pernah berpikir untuk mengambil kepemilikan penuh dari bisnis modul lain (dan menyampaikan kembali setelah perubahan) ... coba saja dan saya berakhir dengan kode yang jauh lebih sederhana. Bersulang!
Pebbl

1
@ EsccottJoudry ~ mungkin hanya layak dicatat bahwa jika Anda mengambil alih dengan cara ini Anda perlu memastikan Anda memiliki metode untuk semua field_formatterfungsi yaitu node_reference MYMODULE_field_formatter_settings_summarydan dan MYMODULE_field_formatter_settings_form(bahkan jika mereka hanya fungsi proxy kembali ke modul asli) jika tidak kembali- end UI rusak pada panel mode tampilan, ketika mencoba menemukan metode ini dalam modul yang salah.
Pebbl

Pendekatan Graham C menarik, tetapi membutuhkan terlalu banyak penggantian.
milkovsky

2

Ok jadi saya menyadari mengapa perubahan saya #view_modebaik hook_preprocess_nodedan hook_preprocess_fieldstidak berfungsi. (Terima kasih kepada Clive untuk menunjukkan bahwa aku benar-benar merindukan kehadiran #view_modedi hook_preprocess_node) .

Masalah saya berasal dari fakta bahwa #view_modesudah diproses dan dikonversi ke #image_styleproperti yang benar - sesuatu yang saya lalai mencari.

Meski begitu, mengubah nilai ini tampaknya terlalu tergantung pada pengait mana Anda memodifikasinya. Akhirnya saya dapat beberapa kode, yang sebenarnya mengubah gambar yang diberikan:

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

Hal di atas masih tidak terasa fasih, tetapi setidaknya itu berfungsi. Saya akan mengambil kata Clive pada kenyataan bahwa metode _alter seperti itu tidak ada untuk formatters lapangan - memalukan, formatters adalah fitur yang sangat kuat dari D7, alangkah baiknya memiliki kemampuan yang lebih besar.

Bagaimanapun, jika ada orang di masa depan yang memiliki ide yang lebih baik, jawablah :)


0

Pendekatan termudah adalah menggunakan Panelizer .

Jika tidak menggunakan Panelizer tetapi mode tampilan Drupal default atau Display Suite, coba hook_field_display_alter () atau hook_field_display_ENTITY_TYPE_alter () .

Anda memiliki entitas, konteks tampilan serta semua pengaturan formatter di sana. Dan Anda dapat dengan mudah mengubah pengaturan render bidang. Anda bahkan dapat mengubah formatter bidang ke yang berbeda.

Pendekatannya bekerja sempurna bagi saya. Satu-satunya kelemahan adalah bahwa Anda mungkin bingung dengan pengaturan yang berbeda di UI "Kelola tampilan".


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.