Пользовательские записи в режимах просмотра сущностей?


Предыстория + вопрос

Я хочу перенести entdispfieldui на Drupal 8. (проблема)

Модуль позволяет конструктору сайтов добавлять новые записи в режим просмотра сущностей, настраивать и размещать их среди обычных полей. Эти записи существуют для каждого режима просмотра /пакета/ типа сущности.

Мне интересно, как лучше всего добиться этого в Drupal 8. Подходит ли одна из приведенных ниже идей? Зачем мне использовать его поверх другое?

Идеи до сих пор

Идея 1: Дополнительные поля + объекты конфигурации

Функция Hook_entity_extra_field_info() позволяет вставлять "псевдо" поля в пакет сущностей, но в разных режимах просмотра. Идея состояла бы в том, чтобы использовать функцию hook_form_alter() для удаления элементов из тех режимов просмотра, которым они не принадлежат.

Я нашел здесь некоторую документацию по дополнительным полям: https://www.webomelette.com/creating-pseudo-fields-drupal-8

Записи будут храниться как объекты конфигурации, с ключами, чтобы определить, к какому режиму просмотра они принадлежат.

Для этого я начал смотреть на https://www.drupal.org/docs/8/api/configuration-api/creating-a-configuration-entity-type-in-drupal-8

Идея 2: Учитесь у field_group и набора дисплеев

Field_group делает что-то похожее на то, что я пытаюсь сделать. За исключением того, что записи являются не псевдополями, а группами. Но все же это записи или "вещи", которые существуют в режиме просмотра и могут быть созданы и удалено.

Но я обнаружил, что field_group не использует для этого тип сущности конфигурации. Вместо этого в field_group.entity_display.schema.yml я нахожу следующее:

core.entity_view_display.*.*.*.third_party.field_group:
  type: sequence
  label: 'Field group settings on entity view'

Аналогичные строки можно найти в файле ds.entity_display.schema.yml или field_layout.схема.yml. Хотя они не используют type: sequence. Я думаю, это потому, что они хранят настройки для самого режима просмотра, а не для записей в режиме просмотра.

Поэтому мне интересно, что означает core.entity_view_display.*.*.*.third_party... и почему я должен использовать эту последовательность +type: вместо объекта конфигурации тип?

И если я использую этот метод, будет ли по-прежнему иметь смысл работать с hook_entity_extra_field_info()?

Author: donquixote, 2017-08-20

1 answers

У меня получилось!

Есть много деталей, которые необходимо рассмотреть, так что вот лишь приблизительный обзор.

Сохранение записей.

Я решил хранить записи не в сущностях конфигурации, а в виде необработанных записей конфигурации. Это кажется проще и предотвращает рекурсию с помощью функции hook_entity_extra_field_info().

Для каждой записи мы храним:

  • Конфигурация, которая указывает нам, как должен отображаться элемент при просмотре сущности.
  • Необязательно, административный ярлык и/или ярлык для потребления посетителями.

Мы НЕ храним вес (порядок/положение между другими полями). Благодаря hook_entity_extra_field_info(), Drupal сделает это за нас!

Мы не храним идентификатор или имя машины в качестве значения в записи. Вместо этого имя машины является частью ключа, ссылающегося на запись конфигурации.

Каждая запись идентифицируется ключом формата "entdisp.vme.$entity_type_id.$bundle.$view_mode.$entry_machine_name".

Entdisp.view_mode_entry.схема.yml:

entdisp.vme.*.*.*.*:
  type: ignore

Очевидно, что это могло бы быть более сложным, но это работает для меня.

Грубые формы для добавления + удаления

Аналогично модулю field_group, создайте формы для добавления и удаления записей режима просмотра.

Например, admin/structure/types/manage/article/display/full будет иметь ссылку действия "Добавить запись EntDisP", ведущую к admin/structure/types/manage/article/display/full/entdisp/add.

Hook_entity_extra_field_info()

Регистрируйте дополнительные поля для каждого пакета с заполнителями для метки и другими настройки.

/**
 * Implements hook_entity_extra_field_info().
 */
function entdisp_entity_extra_field_info() {

  $ids = \Drupal::configFactory()->listAll('entdisp.vme.');

  $fill = ['', '', '', '', '', ''];

  $defaults = [
    'label' => '_',
    'visible' => FALSE,
  ];

  $extra = [];
  foreach ($ids as $id) {
    $pieces = explode('.', $id) + $fill;
    if (in_array('', $pieces, TRUE)) {
      continue;
    }
    list(,,$entity_type_id, $bundle, $view_mode, $vme_name) = $pieces;
    // $view_mode is not used!
    $extra[$entity_type_id][$bundle]['display']['entdisp_' . $vme_name] = $defaults;
  }

  return $extra;
}

Функция Hook_form_entity_view_display_edit_form_alter()

Изменить entity_view_display_edit_form.

В $form['fields'] и в $form['#extra'] мы уже находим по одной записи для каждого дополнительного поля, которое мы ранее зарегистрировали.

Для каждой записи в $form['#extra'], которая начинается с "entdisp_", выполните следующие действия:

  • Проверьте, существует ли соответствующая запись в настройках.
  • Если нет, удалите запись из $form['fields'] и из $form['#extra'].
  • Если да, измените элемент в $form['fields'][$name], чтобы присвоить ему метку и элементы управления конфигурацией. Взгляните на field_group_field_ui_display_form_alter() и на EntityViewDisplayEditForm в ядре.

Все это немного сложно и требует больше работы, чем можно объяснить здесь. Но это проще, чем в field_group, благодаря трюку с hook_entity_extra_field_info().

Hook_entity_view()

В этом крючке для каждого элемента в $display->getкомпоненты() мы

  • найдите соответствующую запись конфигурации.
  • добавьте элемент визуализации в $build.

Это может выглядеть примерно так: https://www.webomelette.com/creating-pseudo-fields-drupal-8

 1
Author: donquixote, 2017-08-21 03:46:27