Нодус: Вложенные типы
Предположим, что у наших кошек есть аксессуары (ошейник, хозяин, и т.д.). Причем без кошки аксессуары не существуют (и хозяин тоже), т.е. нет отдельной страницы и т.п. Тогда аксессуары - это вложенный тип.
Редактирование/добавление этого типа происходит на странице основного типа во всплывающем окне.
Создание вложенного типа
Вложенный тип создается также как и обычный, но обладает некоторыми особенностями. Во-первых, в нем необходимо переопределить метод independent().
// app/components/Nodus/app/Datatype/Accessories.php class Component_Nodus_App_Datatype_Accessories_Type extends Component_Nodus_Datatype implements Core_ModuleInterface { ... public function independent() { return false; } }
Т.е. наш тип является зависимым (от того типа в который будет вложен). Во-вторых, у полей есть параметр independent_only, если он установлен в true, то данное свойство не доступно при редактировании/добавлении вложенного типа.
Тем самым убираются лишние поля редактирования, которые загромождают форму редактирования. Из стандартных полей independent_only установлен у
- url
- mnemocode
- access_subheader
- access_view
- access_edit
- meta_subheader
- meta_title
- meta_description
- meta_keywords
Если необходимо скрыть ещё какое-то поле или наоборот показать скрытое по умолчанию, то параметр independent_only можно переопределить как и любой другой параметр поля
public function fields() { ... 'subheader_pub' => array( 'independent_only' => true ), 'published' => array( 'independent_only' => true ), 'lang' => array( 'independent_only' => true ), 'mnemocode' => array( 'independent_only' => true ) ... }
В остальном вложенный тип такой же как и обычный тип.
Поле nodus_items_embedded
Чтобы появилась возможность редактировать аксессуары кошек, надо добавить им поле nodus_items_embedded, например
// app/components/Nodus/app/Datatype/Cat.php class Component_Nodus_App_Datatype_Cat_Type extends Component_Nodus_Datatype implements Core_ModuleInterface { ... 'year' => array( 'type' => 'nodus_items_embedded', 'selector' => 'accessories', 'modal_width' => 1000, 'caption' => 'Аксессуары', 'tab' => 'default', ), }
Основной параметр здесь selector - мнемокод или объект селектора, с помощью которого выводится редактируемый список.
В нашем случае передан мнемокод вложенного типа accessories, т.е. используется селектор по умолчанию.
Параметр modal_width определяет ширину всплывающего окна редактирования.
По умолчанию селектору устанавливается режим отображения embedded-table, шаблон которого можно найти в Nodus/views/embeded-table/.
Этот шаблон выводит таблицу с кнопками редактирования и удаления записей, а также позволяет drag-and-drop менять сортировку.
Есть второй стандартный режим отображения списка редактирования embedded-gallery, который показывает список в виде галереи, что удобно при создании сложных галерей (как это ни странно).
В этом режиме также доступна drag-and-drop сортировка и удаление/редактирование записей. Что бы установить режим отображения списка в embedded-gallery или любой произвольный режим отображения достаточно установить параметр selector_mode, например:
... 'year' => array( 'type' => 'nodus_items_embedded', 'selector_mode' => 'embedded-gallery', 'selector' => 'accessories', 'modal_width' => 1000, 'caption' => 'Аксессуары', 'tab' => 'default', 'preview_field' => 'gallery' ), ...
В данном случае указан ещё один дополнительный параметр preview_field, который задает поле, из которого будет браться preview картинка. По умолчанию этот параметр установлен в image, т.е. если во вложенном типе есть поле с именем image, то, по умолчанию, preview картинка будет браться из него. Тип preview поля может быть image или gallery.
Редактирование полей вложенного типа из списка
Начиная с версии Нодуса 3.0.33, есть возможность организовать редактирование полей вложенного типа из списка в админке.
Сделать это можно как непосредственно в описании самого вложенного типа, так и в описании основного типа.
1. Описание полей во вложенном типе данных.
В модуле описания вложенного типа данных в методе admin_list_fields()
при описании поля, которое должно редактироваться из списка, добавляем свойство edit
. В котором в виде массива описываются настройки поля.
// /app/components/Nodus/app/Datatype/Models.php class Component_Nodus_App_Datatype_Models_Type extends Component_Nodus_Datatype implements Core_ModuleInterface { ... public function admin_list_fields($fields = array()) { return array_merge_recursive($fields, array( ... 'podshipniki' => array( 'caption' => 'Подшипники, шт.', 'edit' => array( 'style' => 'width: 100px;', ), 'weight' => 1200, ), 'peredatochnoe' => array( 'caption' => 'Передаточное число', 'edit' => array( 'style' => 'width: 100px;', ), 'weight' => 1300, ), )); ... } }
В админке будут доступны поля для редактирования непосредственно из списка.
2. Добавление полей в модуле описания основного типа данных.
При описании полей основного типа добавляем поле типа nodus_item_embedded
. И в этом поле необходимо добавить опцию list_fields
, где в виде массива описать все поля, которые будут выводиться в админке в списке. При этом, в самом вложенном типе (метод admin_list_fields) можно не описывать поля. Необходимо учитывать, что при описании полей в обоих случаях, они все будут выведены.
// app/components/NodusCatalog/app/Item/Type.php class Component_NodusCatalog_App_Item_Type extends Component_NodusCatalog_Datatype_Item_Type implements Core_ModuleInterface { public function fields() { $fields = array_merge(parent::fields(), array( 'subitems' => array( 'type' => 'nodus_items_embedded', 'selector' => 'models', 'modal_width' => 800, 'tab' => 'subitems', 'weight' => 600, 'list_fields' => array( 'podshipniki' => array( 'caption' => 'Подшипники, шт.', 'edit' => array( 'style' => 'width: 100px;', ), 'weight' => 1200, ), 'peredatochnoe' => array( 'caption' => 'Передаточное число', 'edit' => array( 'style' => 'width: 100px;', ), 'weight' => 1300, ), ), )); ... }
Сохранение данных при редактировании из списка и запись в базу данных происходит при общем сохранении (кнопкой «Сохранить»).
Вывод вложенных типов в шаблоне
Вывод в шаблоне вложенных типов производится по тому же принципу, что и вывод основного. Т.е. в шаблоне также доступен объект записи $item со всей своей информацией. Например, выведем в шаблоне full.phtml все аксессуары, относящиеся к коту.
// app/components/Nodus/app/Datatype/Cat/full.phtml ... <?php $subitems = $item->field('accessory')->items();?> ... <?php foreach ($subitems as $subitem) { echo $this->nodus->item($subitem); }?> ...