Интеграция custom entity с панелайзером

Как интегрировать entity с panelizer

Panelizer[1] - модуль, позволяющий кастомизировать контент сущностей, используя систему шаблонов и layouts. Для управления структурой сущности используется панель, поэтому можно перетаскивать блоки, добавлять новые пейны, управлять контекстом и т.д. Для того, чтобы панелайзер "увидел" кастомную entity, необходимо с ним интегрироваться. Об этом и пойдет сегодня речь.

Содержание

Объявление плагина entity

Для интеграции воспользуемся сущностью, созданной в прошлой статье Расширяем возможности кастомной entity. Для начала создадим необходимую структуру папок:

1
2
3
4
5
6
7
8
MYMODULE
 |
 +--plugins
     |
     +--entity
         |
         +--MYMODULE_entity.inc
         +--PanelizerEntityMYMODULE.class.inc

Файл MYMODULE_entity.inc содержит определение плагина.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * @file
 * Definition of MYMODULE entity plugin.
 */
 
$plugin = array(
  'handler' => 'PanelizerEntityMYMODULE',
  'entity path' => MYMODULE_ENTITY_PATH . '/%MYMODULE_entity_object',
  'uses page manager' => TRUE,
  // Список хуков, которые будут отрабатывать для данного плагина. Данный список
  // может быть дополнен/минимизирован.
  'hooks' => array(
    'menu' => TRUE,
    'admin_paths' => TRUE,
    'permission' => TRUE,
    'panelizer_defaults' => TRUE,
    'form_alter' => TRUE,
    'default_page_manager_handlers' => TRUE,
  ),
);

Для того чтобы созданный плагин был виден панелайзеру, необходимо объявить его тип в файле MYMODULE.module используя hook_ctools_plugin_type()[2], а также указать папку расположения плагинов.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
 * Implements hook_ctools_plugin_type().
 */
function MYMODULE_ctools_plugin_type() {
  return array(
    'MYMODULE_entity' => array(
      'cache' => FALSE,
      'process' => array(
        'function' => 'panelizer_entity_plugin_process',
      ),
      'classes' => array('handler'),
    ),
  );
}
 
/**
 * Implements hook_ctools_plugin_directory().
 */
function MYMODULE_ctools_plugin_directory($module, $plugin) {
  if (in_array($module, array('panelizer', 'ctools', 'page_manager', 'panels'))) {
    return 'plugins/' . $plugin;
  }
}

Описание класса, наследуемого от PanelizerEntityDefault

В определении плагина был указан хэндлер PanelizerEntityMYMODULE, теперь самое время его описать.
Содержимое файла PanelizerEntityMYMODULE.class.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/**
 * Panelizer Entity MYMODULE plugin class.
 *
 * Handles specific functionality for MYMODULE entity.
 */
class PanelizerEntityMYMODULE extends PanelizerEntityDefault {
  public $supports_revisions = TRUE;
  public $entity_admin_root = 'admin/structure/MYMODULE-types/manage/%MYMODULE_entity_type_name';
  public $entity_admin_bundle = 4;
  public $views_table = 'MYMODULE_entity';
  public $uses_page_manager = TRUE;
 
  /**
   * {@inheritdoc}
   */
  public function entity_access($op, $entity) {
    return MYMODULE_entity_object_access($op, $entity);
  }
 
  /**
   * {@inheritdoc}
   */
  public function entity_save($entity) {
    MYMODULE_entity_object_save($entity);
  }
 
  /**
   * {@inheritdoc}
   */
  public function entity_identifier($entity) {
    return t('This MYMODULE entity');
  }
 
  /**
   * {@inheritdoc}
   */
  public function entity_bundle_label() {
    return t('MYMODULE entity type');
  }
 
  /**
   * {@inheritdoc}
   *
   * Определение хэндлера.
   */
  public function hook_default_page_manager_handlers(&$handlers) {
    $handler = new stdClass();
    $handler->disabled = FALSE;
    $handler->api_version = 1;
    $handler->name = 'MYMODULE_view_panelizer';
    $handler->task = 'MYMODULE_view';
    $handler->subtask = '';
    $handler->handler = 'panelizer_node';
    $handler->weight  = -100;
    $handler->conf = array(
      'title'   => t('MYMODULE entity'),
      'context' => 'argument_entity_id:MYMODULE_entity_1',
      'access'  => array(),
    );
    $handlers['MYMODULE_view_panelizer'] = $handler;
 
    return $handlers;
  }
 
  /**
   * {@inheritdoc}
   *
   * Включение формы создания ревизий для сущности. Элемент формы будет
   * отображаться на каждой странице редактирования настроек панелайзера
   * (settings, context, layout, content). Если необходимо отображать элемент
   * только на определенных страницах, то нужно внести изменения в этот
   * метод (передавать FALSE в качестве первого элемента массива).
   */
  public function entity_allows_revisions($entity) {
    return array(TRUE, TRUE);
  }
 
  /**
   * {@inheritdoc}
   *
   * Здесь размещаем логику альтера для форм (settings, context, layout,
   * content) в зависимости от $form_id, если конечно это необходимо.
   */
  public function hook_form_alter(&$form, &$form_state, $form_id) {
 
  }
}

Демонстрация работы

Для демонстрации интеграции кастомной сущности с панелайзером создадим новый тип MYMODULE entity.
добавление нового типа сущности
Затем переходим на страницу управления панелайзера через меню Configuration → Content authoring → Panelizer. Если все сделано верно, то созданный тип сущности должен появиться на данной странице. Отмечаем, что данный тип должен быть Panelized, Full page override. Кроме того включим чекбоксы для дефолтного шаблона и Allow Panel Choice.
страница управления panelizer
После сохранения настроек на этой странице, ссылка list в колонке OPERATIONS будет вести на страницу со списком шаблонов.
список шаблонов panelizer
Можно создать свой собственный шаблон, переопределить существующий. Кроме того в настройках шаблона есть возможность выбрать layout, настроить контекст, добавить дефолтные пейны и т.д. Добавим новый пейн в дефолтный шаблон. Для этого перейдем в настройки контента по ссылке Content.
опции шаблона
Для добавления нового пейна, необходимо нажать на иконку иконка добавления контента в верхней левом углу панели. В появившемся попапе выбираем New custom content и заполняем предложенную форму текстом.
panelizer добавление нового контента
По кнопке Save сохраняем изменения.
Далее необходимо создать страницу для отображения кастомной сущности. Создаем страницу с помощью page manager через меню Structure → Pages → Add custom page и заполняем как приведено на рисунке ниже.
page_manager новая кастомная страница
Далее переходим к выбору аргумента. Отмечаем, что аргумент является идентификатором сущности.
page_manager выбор аргумента
Сохраняем все изменения. Создаем новую сущность типа Cars через меню Add mymodule entity → Cars или по ссылке MYMODULE-entity/add/cars и переходим по пути /MYMODULE-entities/[id сущности]. В результате view entity будет отображен с помощью панелайзера, его шаблона и настроек контента.
рендер сущность с помощью панелайзера

Дополнительная информация по статье

  1. https://www.drupal.org/project/panelizer - ссылка на проект Panelizer.
  2. http://www.drupalcontrib.org/api/drupal/contributions!ctools!ctools.api.php/function/hook_ctools_plugin_type/7 - описание ctools хука hook_ctools_plugin_type().