ertttert
В Drupal поддерживается множество различных типов нод (в пользовательском интерфейсе они называются типами контента (content type)), такие как статьи и базовые страницы. Мы ограничим использование аннотаций только некоторыми типами нод. Для этого понадобится создать страницу, где можно сообщить модулю о том, какие типы контента мы хотим аннотировать. На этой странице будет представлен набор флажков — по одному для каждого существующего типа контента. Это позволит конечному пользователю указать, какие типы контента могут аннотироваться, сбросив или установив соответствующие флажки (рис. 2.1). Такая страница является административной, а это значит, что ее код необходимо загружать и синтаксически анализировать только при необходимости. Поэтому мы поместим этот код в отдельный файл, а не в annotate.module
, который будет загружаться и выполняться при каждом веб-запросе. Поскольку Drupal было указано, что искать форму параметров нужно в файле annotate.admin.inc
, мы создадим файл sites/all/modules/annotate/annotate.admin.inc и поместим в него следующий код:
/** * @file * Обратные вызовы административной страницы для модуля аннотирования. */ /** * Создание формы. Настройка аннотирования. * * @ingroup forms * @see system_settings_form(). */function annotate_admin_settings() {// Получение массива типов нод: ключи — это внутренние имена, // а значения — "дружественные имена". Например: // array('page' => 'Basic Page', 'article' => 'Articles') $types =node_type_get_types() ;foreach( $typesas $node_type) { $options[$node_type->type] = $node_type->name; } $form['annotate_node_types'] =array( '#type' => 'checkboxes','#title' =>t( 'Users may annotate these content types') ,// Пользователи могут аннотировать эти типы контента '#options' => $options,'#default_value' =>variable_get( 'annotate_node_types',array( 'page')) ,'#description' =>t( 'A text field will be available on these content types to make author-specific notes.') ,// Для этих типов контента будут доступны текстовые // поля, предназначенные для авторских заметок ) ;return system_settings_form( $form, TRUE) ; }
Формы в Drupal представляются в виде вложенной древовидной структуры — т.е. массива массивов. Эта структура описывает, каким образом механизм отображения форм Drupal должен представлять эту форму. Для наглядности лучше размещать каждый элемент массива в отдельной строке. Средства формы отмечаются знаком checkboxes;
это означает, что на основании ассоциативного массива будет создано несколько флажков. Этот массив уже содержится в переменной $options. Содержимое переменной $options присваивается выходным данным функции
[article] =>stdClass Object ( [type] => article[name] => Article[base] => node_content[description] => Use articles for time-sensitive content like news, press releases or blog posts.[help] =>[has_title] => 1[title_label] => Title[has_body] => 1[body_label] => Body[custom] => 1[modified] => 1[locked] => 0[orig_type] => article)
Ключами массива объектов являются внутренние имена Drupal для типов нод, а дружественные имена (т.е., которые выводятся пользователю) содержатся в атрибуте
. Это позволит циклу Basic page
и article
, а также для всех других типов контента, доступных на сайте. Заголовок элементу формы назначается определением значения свойства
Следующая директива — checkboxes
является множественным элементом формы (т.е. флажков несколько), значением
variable_get( 'annotate_node_types',array( 'page'))
Drupal позволяет программистам сохранять и выбирать любые значения с помощью специальной пары функций: variables
и доступны в любой момент при обработке запроса. А поскольку эти переменные выбираются из базы данных при каждом запросе, не следует хранить таким способом большие объемы данных. Обратите внимание: функции Basic Page
).
Здесь добавлено описание, которое немного поможет администратору сайта понять, что следует поместить в данное поле. О формах речь пойдет в главе 11. Теперь добавим код для обработки добавления и удаления поля аннотации в типах контента. Если администратор сайта отмечает тип контента, к этому типу контента должно быть добавлено поле для аннотации. Если администратор сайта решит убрать поле аннотации из типа контента, это поле должно быть удалено. Для определения поля и связывания его с типом контента мы используем интерфейс
системы Drupal. Этот API-интерфейс обрабатывает все действия, связанные с настройкой поля, включая создание таблицы в базе данных Drupal для хранения значений, отправленных авторами контента, создание элемента формы, который будет использоваться для сбора информации, вводимой автором, и связывание поля с типом контента и вывод этого поля на форме редактирования ноды при отображении ноды на странице. Программный интерфейс Field API будет рассмотрен в главе 4. Вначале понадобится создать подпрограмму проверки, которая будет вызываться при отправке формы администратором сайта. В этой подпрограмме модуль проверит, установлен или сброшен флажок для типа контента. Если он сброшен, будет выполнена проверка, что тип контента не содержит связанного с ним поля аннотации. Если содержит, это означает, что администратор сайта желает удалить такое поле из данного типа контента, и нужно удалить аннотации, которые уже занесены в базу данных. Если флажок установлен, модуль проверяет, существует ли поле в данном типе контента, и если нет, модуль добавляет такое поле к типу контента./** * annotate_admin_settings_validate */ function annotate_admin_settings_submit( $form, $form_state) {// Цикл по всем флажкам типов контента, имеющихся на форме. foreach ( $form_state['values']['annotate_node_types']as $key => $value) {// Если флажок для типа контента сброшен, проверяем, // имеется ли у данного типа контента связанное с ним поле аннотации, // с помощью функции field_info_instance. Если имеется, // нужно удалить поле аннотации, т.к. флажок сброшен. if ( !
$value) { $instance =field_info_instance( 'node', 'annotation', $key) ;if (!
empty( $instance) ) {field_delete_instance( $instance);watchdog( "Annotation", "Deleted annotation field from content type: ".$key); }// Конец варианта, когда аннотация существует, и ее необходимо удалить. }else {// Если флажок для типа контента установлен, проверяем, связано ли с данным // типом контента поле. Если нет, добавим в тип контента поле аннотации. $instance =field_info_instance( 'node', 'annotation', $key) ;if (empty( $instance) ) { $instance =array( 'field_name' => 'annotation','entity_type' => 'node','bundle' => $key,'label' =>t( 'Annotation') ,'widget_type' => 'text_textarea_with_summary','settings' =>array( 'display_summary' => TRUE) ,'display' =>array( 'default' =>array( 'type' => 'text_default',) ,'teaser' =>array( 'type' => 'text_summary_or_trimmed',) ,) ,) ; $instance =field_create_instance( $instance) ;watchdog( "Annotation", "Added annotation field to content type: ".$key) ; }// Конец варианта, когда поля аннотации нет, и оно добавляется. }// Конец оператора if. }// Конец оператора foreach. }
Теперь нужно создать файл .install
для нашего модуля. Этот файл содержит одну или несколько функций, которые вызываются при инсталляции или удалении модуля. В нашем случае при инсталляции модуля должно быть создано поле аннотации, чтобы администраторы сайта могли связывать его с типами контента. При удалении модуля необходимо удалить поле аннотации из всех типов контента и удалить поле с его содержимым из базы данных Drupal. Для этого в каталоге модуля аннотирования понадобится создать новый файл по имени annotate.install
. Первая вызываемая функция — hook_install()
. В соответствии со стандартами именования функций хуков в Drupal мы назовем ее hook
именем модуля. В функции hook_install
будет выполняться проверка существования поля с помощью Field API, и если оно не существует, будет создаваться поле аннотации.
<?php/** * Реализация hook_install() */ function annotate_install() {// Проверка, существует ли поле аннотации. $field =field_info_field( 'annotation') ;// Если поле аннотации не существует, оно создается. if (empty( $field) ) { $field =array( 'field_name' => 'annotation','type' => 'text_with_summary','entity_types' =>array( 'node') ,'translatable' => TRUE, ); $field =field_create_field( $field) ; } }
После этого нужно создать функцию удаления (деинсталляции) с помощью hook_uninstall
. Мы создадим функцию с именем annotate_uninstall
и воспользуемся функцией отслеживания watchdog
для записи сообщения администратору сайта о том, что модуль деинсталлирован. Затем применим API-функцию
/** * Реализация hook_uninstall() */ function annotate_uninstall() {watchdog( "Annotate Module", "Uninstalling module and deleting fields") ; $types =node_type_get_types() ;foreach( $typesas $type) {delete_annotation( $type) ; } $field =field_info_field( 'annotation') ;if ($field) {field_delete_field( 'annotation') ; } }function delete_annotation( $type) { $instance =field_info_instance( 'node', 'annotation', $type->type) ;if ($instance) {field_delete_instance( $instance) ; } }
Последним шагом процесса должно быть включение в файл .module
проверки, является ли лицо, просматривающее ноду, автором этой ноды. Если это не автор, то поле аннотирования нужно скрыть. Мы применим простой подход с помощью функции hook_node_load()
— хука, который вызывается при загрузке ноды. Внутри функции hook_node_load()
будет выполняться проверка, является ли пользователь, просматривающий ноду, его автором. Если это не автор, аннотация скрывается с помощью функции сброса.
/** * Реализация hook_node_load() */ function annotate_node_load( $nodes, $types) { global $user; // Проверка, является ли лицо, просматривающее ноду, автором. // Если нет, аннотация скрывается. foreach ( $nodesas $node) {if ( $user->uid!=
$node->uid) {unset( $node->annotation) ; } } }
Сохраните созданные файлы (.info
, .install
, .admin.inc
, .module
) и щелкните на пункте (Модули) в меню администрирования в верхней части страницы. Наш модуль должен появиться в группе Pro Drupal Development (если не появился, перепроверьте синтаксис файлов annotate.info
и annotate.module
; они должны находиться в каталоге >sites/all/modules/custom). Активируйте новый модуль. После активации модуля перейдите по адресу admin/config/annotate/settings should — там должна появиться форма настройки для annotate.module
(рис. 2.1).
Написав лишь несколько строк кода, мы получили функциональную форму настройки для нашего модуля, которая автоматически сохраняет и запоминает параметры! Это дает некоторое представление о мощи, заложенной в Drupal. Давайте протестируем процесс. Для этого сначала разрешим аннотирование для всех типов контента. Установите все флажки на странице настройки параметров и щелкните на кнопке
(Сохранить конфигурацию). Потом создайте новую ноду базовой страницы и прокрутите ее вниз, пока не увидите поле аннотирования (рис. 2.2).Создайте новую ноду, введя значения в поле заголовка, тела и аннотации. После этого щелкните на кнопке сохранения — результат должен быть похож на показанный на рис. 2.3.
Здесь, даже неявно, не выполнялось ни одной операции с базами данных — непонятно, где Drupal сохраняет и откуда выбирает значения для поля аннотации? Все скрытые операции по созданию таблицы для хранения значения, а также сохранение и выборку значений при сохранении и загрузке ноды выполняет интерфейс Field API. При вызове функция field_data_<имя_поля>
. В случае нашего поля аннотирования таблица называется field_data_annotations
. Более подробно Field API рассматривается в главе 4.
Всего комментариев: 0 | |