Зачепити в форматник поля іншого модуля?


9

На даний момент я намагаюся реалізувати поле зображень, на яке посилається вузол, на моєму сайті Drupal 7, яке змінить його "режим перегляду" в залежності від програмної логіки безпосередньо перед візуалізацією. Наразі це поле рендерується для кількох типів вмісту через їх налаштування режиму відображення, кожен з яких використовує форматник поля "Наданий вузол".

перша спроба

Моя перша ідея полягала в тому, щоб реалізувати наступне, вважаючи, що гак - це гак - це гачок:

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

Очевидно, міняючи HOOK на ім'я мого модуля.

Це на самому ділі не має значення , якщо вище стрілятиме до або після вихідної функції node_reference_field_formatter_viewв node_reference.moduleтому , що я або перевизначити його висновок повністю або, сподіваюся, змінити його значення перед візуалізацією. Єдина проблема полягає в тому, що вищезазначений гак, здається, функціонує лише на основі кожного модуля, тобто він не є загальномісцевим, тому в основному він не працює для мого модуля.

Тепер, очевидно, я можу написати власний форматник поля для виведення виведеного вузла. Але це, здається, трохи марно, враховуючи, що вже є такий, який існує.

інші підходи

Мої інші підходи були до HOOK_preprocess_nodeі , HOOK_preprocess_fieldале перший не містить будь - яких view_modeінформації, а друга містить , щонайменше , 5 різних складних структур , які все мають посилання на view_modeвласність на різних рівнях - і він відчуває себе досить Hacky , щоб змінити у кожного з них значення. Навіть коли я змінив певні view_modeвластивості, отримане зображення не змінюється.

питання

Хтось знає про чистий спосіб вступити до того, як формувач поля виведе (модуля вкладки) та змінить його налаштування на основі запиту на сторінку - тобто не потрібно змінювати фактичні параметри постійного режиму перегляду типу вмісту?


2
Я шукав hook_field_formatter_view_alter()подібне або, мабуть, вже більше року, він, на жаль, не існує. FYI, hook_preprocess_node()безумовно, має в своєму view_modeрозпорядженні це, але це $vars['view_mode']не те, $vars['node']->view_modeщо ви могли б спробувати спробувати.
Клайв

@Clive дякую за інформацію, ой і за вказівку view_modeна hook_preprocess_node, нерозумно мене! Цікаво, чи є щось подібне hook_field_formatter_view_alter()в D8 ...
Pebbl

Я ще нічого не бачив ... але тоді все перетворюється на плагіни в D8 (я не впевнений у полях), тож може бути, що ви можете просто замінити існуючий клас, щоб виконати роботу, це було б ідеально . Ось сподівання!
Клайв

1
@Clive, ти знайшов твій чарівний гачок з альтера, згаданий тут для D7?
tyler.frankenstein

Відповіді:


11

У запитанні зазначається, що hook_field_formatter_view()викликається тільки вихідний модуль, але ви можете взяти право власності на форматник поля через hook_field_formatter_info_alter().

Ви повинні мати можливість встановити moduleключ форматера на MYMODULE, наприклад:

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

Потім ви можете реалізувати MYMODULE_field_formatter_view(), необов'язково, подачу через існуючий модуль, який обробляв його, щоб отримати елемент для зміни.

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
}

Чи можете ви детальніше пояснити свою відповідь? Надати якийсь код?
Скотт Джодрі

Приємне рішення, я майже ніколи не думаю, щоб повною мірою володіти бізнесом іншого модуля (і ретрансляцію після змін) ... просто спробував це, хоча і в кінцевому підсумку набагато простіший код. Ура!
Pebbl

1
@ScottJoudry ~ може просто варто відзначити, що якщо ви перейдете таким чином, вам потрібно переконатися, що у вас є методи для всіх field_formatterфункцій node_reference, тобто MYMODULE_field_formatter_settings_summaryі MYMODULE_field_formatter_settings_form(навіть якщо вони є лише проксі-функціями назад до початкового модуля), інакше кінцевий інтерфейс інтерфейсу відбувається на будь-яких панелях режиму відображення, коли він намагався знайти ці методи в неправильному модулі.
Pebbl

Підхід Грехама С цікавий, але вимагає занадто багато змін.
мілковський

2

Гаразд, я зрозумів, чому мої зміни #view_modeв тому чи іншому hook_preprocess_nodeі hook_preprocess_fieldsне працювали. (Спасибі Clive за вказівку на те , що я повністю пропустив присутність #view_modeв hook_preprocess_node) .

Моя проблема виникла з того, що я #view_modeвже був оброблений і перетворений у правильну #image_styleвластивість - те, що я знехтував шукати.

Незважаючи на це, зміна цього значення здається занадто сильно залежною від того, в якому гачку ви його змінили. Я, нарешті, дійшов деякого коду, який фактично змінює надане зображення:

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

Сказане все ще не дуже красномовно, але принаймні це працює. Я візьму слово Клайва про те, що такий метод _alter не існує для польових форматів - це шкода, форматори - надзвичайно потужна особливість D7, непогано було б мати більше можливостей для збільшення.

У будь-якому випадку, якщо будь-які майбутні люди мають кращі ідеї, відповідайте :)


0

Найпростіший підхід буде використовувати Panelizer .

Якщо ви не використовуєте Panelizer, але режими перегляду Drupal за замовчуванням або Display Suite, спробуйте гак_field_display_alter () або ho_field_display_ENTITY_TYPE_alter () .

У вас є сутність, контекст відображення, а також усі налаштування форматера. Ви можете легко змінити настройки візуалізації поля. Ви навіть можете змінити форматник поля на інший.

Підхід для мене ідеально підходить. Єдиним недоліком є ​​те, що вас можуть збентежити різні налаштування в інтерфейсі "Керування дисплеєм".


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.