ertttert
Books-CMS.clan.su

Часто встречающиеся задачи

В настоящем разделе рассмотрены некоторые типичные подходы к часто встречающимся задачам, которые приходится решать разработчикам при работе с меню.

Назначение обратных вызовов без добавления ссылки в меню

Часто бывает необходимо создать отображение URL-адреса на функцию без создания видимого элемента меню. Например, веб-форма может иметь функцию JavaScript, которой нужно получить из Drupal список состояний — поэтому требуется связать URL и PHP-функцию, но все это не должно отображаться ни в одном навигационном меню. Это делается назначением элементу меню типа MENU_CALLBACK, как в первом примере в данной главе.

Вывод элементов меню в виде вкладок

Обратный вызов, который отображается в виде вкладки, называется локальной задачей (local task) и имеет тип MENU_LOCAL_TASK или MENU_DEFAULT_LOCAL_TASK. Заголовок локальной задачи должен быть коротким глаголом, таким как “add” (добавить) или “list” (перечислить). Локальные задачи ведут себя как некоторая разновидность объектов, вроде ноды или пользователя. Их можно считать семантическими объявлениями элемента меню, который обычно отображается в виде вкладки — примерно так же, как дескриптор является семантическим объявлением и обычно отображается как полужирный шрифт. Для отображения вкладок у локальных задач должен быть родительский элемент. Обычно назначается обратный вызов корневому пути вроде milkshake, а затем локальные задачи назначаются путям, расширяющим этот путь — вроде milkshake/prepare, milkshake/drink и т.п. В Drupal имеется встроенная поддержка тем для двух уровней локальных задач в виде вкладок. (Базовая система поддерживает и дополнительные уровни, но тогда тема должна обеспечить поддержку их отображения.) Порядок отображения вкладок определяется алфавитным упорядочением заголовков элементов меню. Если он вас не устраивает, элементам меню можно назначить весовые ключи, и тогда элементы будут упорядочены по весам. Приведенный ниже пример содержит код для вывода двух главных вкладок и двух вложенных вкладок для стандартной локальной задачи. Создайте файл sites/all/modules/custom/milkshake/milkshake.info со следующим содержимым:

name = Milkshake
description = Demonstrates menu local tasks.
package = Pro Drupal Development
core = 7.x
files[] = milkshake.module

Затем создайте файл sites/all/modules/custom/milkshake/milkshake.module:


<?php
/**
* @file
* Модуль для изучения системы меню Drupal, в частности, локальных задач.
*/

/**
* Реализация hook_menu().
*/

function milkshake_menu() {

 $items['milkshake'] = array(
 'title' => 'Milkshake flavors',
 'access arguments' => TRUE,
 'page callback' => 'milkshake_overview',
 'type' => MENU_NORMAL_ITEM,
 );

 $items['milkshake/list'] = array(
 'title' => 'List flavors',
 'access arguments' => TRUE,
 'type' => MENU_DEFAULT_LOCAL_TASK,
 'weight' => 0,
 );

 $items['milkshake/add'] = array(
 'title' => 'Add flavor',
 'access arguments' => TRUE,
 'page callback' => 'milkshake_add',
 'type' => MENU_LOCAL_TASK,
 'weight' => 1,
 );

 $items['milkshake/list/fruity'] = array(
 'title' => 'Fruity flavors',
 'access arguments' => TRUE,
 'page callback' => 'milkshake_list',
 'page arguments' => array(2), // Передается 'fruity'.
 'type' => MENU_LOCAL_TASK,
 );

 $items['milkshake/list/candy'] = array(
 'title' => 'Candy flavors',
 'access arguments' => TRUE,
 'page callback' => 'milkshake_list',
 'page arguments' => array(2), // Передается 'candy'.
 'type' => MENU_LOCAL_TASK,
 );

 return $items;
}

function milkshake_overview() {

 $output = t('The following flavors are available...');
 // ... какой-то код
 return $output;
}

function milkshake_add() {
 return t('A handy form to add flavors might go here...');
}

function milkshake_list($type) {
 return t('List @type flavors', array('@type' => $type));
}
drupal
Интерфейс с вкладками показан на рис. 4.12.

Сокрытие существующих элементов меню

Существующие элементы меню можно скрыть, изменив их атрибут hidden. Предположим, что по какой-то причине необходимо удалить элемент меню Create content (Создать контент). Для этого воспользуемся уже знакомой функцией hook_menu_link_alter():
/**
* Реализация hook_menu_link_alter().
*/
function menufun_menu_link_alter(&$item) {
 // Сокрытие ссылки Create content.
 if ($item['link_path'] == 'node/add') {
 $item['hidden'] = 1;
 }
}

Использование menu.module

Активация модуля меню Drupal предоставляет удобный пользовательский интерфейс для администрирования сайта и настройки существующих меню вроде меню навигации или главного меню, а также для добавления новых меню. При выполнении функции menu_rebuild() из файла includes/menu.inc структура данных, представляющая дерево меню, сохраняется в базе данных. Это происходит при активации или отключении модулей или других действиях, которые меняют компоновку дерева меню. Данные сохраняются в таблице menu_router, а информация о ссылках — в таблице menu_links. В процессе создания ссылок для страницы Drupal сначала создает дерево на основе информации путей, полученной из реализаций хуков меню в модулях и хранящейся в таблице menu_router, а затем эта информация переопределяется информацией о меню из базы данных. Такое поведение позволяет использовать модуль menu.module для изменения родительского пункта, пути, заголовка и описания дерева меню — базовое дерево не меняется, а создаваемые данные просто переопределяют его.
На заметку! Тип элемента меню (такой как ENU_CALLBACK или DEFAULT_LOCAL_TASK) представлен в базе данных своим десятичным эквивалентом.
Модуль menu.module также добавляет раздел в форму ноды для оперативного добавления элементов меню из текущей статьи.

Распространенные ошибки

Вы только что реализовали в своем модуле хук меню, но обратные вызовы не срабатывают, меню не отображаются или все вообще не работает. Ниже перечислены основные моменты, которые следует проверить.
  • Возможно, вы указали в ключе access callback функцию, которая возвращает FALSE?
  • Возможно, вы забыли добавить строку return $items; в конце хука меню?
  • Возможно, вы записали значение аргументов access или page в виде строки, а не массива?
  • Очистили ли вы кэш меню и перестроили ли меню?
  • Если вы хотите, чтобы элементы меню имели вид вкладок, и задали тип MENU_LOCAL_TASK, то назначили ли вы родительский элемент, у которого имеется обратный вызов страницы?
  • Если вы работаете с локальными задачами, то имеется ли на странице не менее двух вкладок (только тогда они появляются)?
  • Всего комментариев: 0
    Имя *:
    Email *:
    Код *:


    Бесплатный конструктор сайтов - uCoz