Пользовательские записи в режимах просмотра сущностей?
Предыстория + вопрос
Я хочу перенести 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()?
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