[how-to] Создаем раздел меню и выводим его в блок программно

Главные вкладки

Аватар пользователя Stutzer Stutzer 13 августа 2010 в 4:34

По умолчанию в Друпале доступны всего три раздела меню (custom menus): Navigation, Primary links и Secondary links.
Однако, часто приходится создавать дополнительные разделы, которые далее можно использовать в виде блоков.
«Мышкой» создание нового раздела меню и последующая настройка вывода блока делается элементарно, однако порой бывает полезно автоматизировать (читай «написать модуль») действия по созданию разделов меню и выводу соответствующих блоков.

Сегодня я как раз столкнулся с подобной задачей и рад поделиться с вами ее решением (возможно не самым идеальным).
К сожалению, Друпал не предоставляет API для подобных действий, поэтому пришлось работать напрямую с бд.

Итак, задача:
написать модуль, который при установке создавает несколько разделов меню, а соответствующие им блоки размещает в определнных регионах. При отключении модуля блоки меняют меняют статус на скрытый

Придумаем для модуля нехитрое название footerLinks и вперед:

Файл footerLinks.info
В котором происходит создание разделов меню при установке модуля

<?php

// Основной файл модуля нам понадобится для вызова функции footerLinks_get_custom_menus()
include_once ('footerLinks.module');

/**
 * Implementation of hook_install().
 */

function footerLinks_install() {
 
  // Получаем необходимые данные по создаваемым разделам меню (see footerLinks.module)
  $custom_menus = footerLinks_get_custom_menus();
 
  // Создаем разделы мею
  foreach ( $custom_menus as $custom_menu ) {
    drupal_set_message( t('%menu_name created succesfully', array('%menu_name' => $custom_menu['menu_name'])) );
    drupal_write_record('menu_custom', $custom_menu);
  }
 
}

Файл footerLinks.module
В котором содержится вся необходимая информация о разделах меню, а также создаются и активируются соответствующие разделам блоки

<?php
/**
 * file
 * footerLinks module core
 */

/**
 * Функция возвращает массив с описанием трех разделов меню
 */

function footerLinks_get_custom_menus() {
  return array(

    'project_links' => array(
      // Машинное имя меня (может содержать строчные буквы, тире, цифры)
      'menu_name' => 'project-links',
      // Человекочитаемый заголовок
      'title' => t('Project info'),
      // Описание (опционально)
      'description' => 'The project links menu is provided by FooterLinks module. It is placed in the footer and contains links about project.',
      // Регион, в который необходимо поместить данное меню
      'region' => 'footer_block_2',
    ),

    'help_links' => array(
      'menu_name' => 'help-links',
      'title' => 'Help info',
      'description' => 'The help links menu is provided by FooterLinks module. It is placed in the footer.',
      'region' => 'footer_block_3',
    ),

    'subscription_links' => array(
      'menu_name' => 'subscription-links',
      'title' => 'Subscription links',
      'description' => 'The subscription links menu is provided by FooterLinks module. It is placed in the footer and contains RSS links, twitter link etc.',
      'region' => 'footer_block_4',
    ),
  );
}
 

/**
 * Implementation of hook_enable().
 * При включении модуля активируем блоки с разделами меню
 */

function footerLinks_enable() {
 
  // Получаем всю необходимую информацию
  $custom_menus = footerLinks_get_custom_menus();

  // Обновляем состояние блоков
  // Это важно, поскольку только после выполнения этой функции
  // становятся доступными блоки с разделами меню
  _block_rehash();
 
  // Залезаем своими рученками в БД, чтобы изменить статус блоков (поместить в определенный регион и сделать их видимыми)
  foreach ( $custom_menus as $custom_menu ) {
    db_query(
      "UPDATE {blocks} SET status = 1, region = '%s' WHERE module = 'menu' AND delta = '%s'",
      $custom_menu['region'], $custom_menu['menu_name']
    );
    // В целях отладки выводим сообщение
    drupal_set_message(
      t(
        '%menu_name placed into %region region',
        array(
          '%menu_name' => $custom_menu['menu_name'],
          '%region' => $custom_menu['region'],
        )
      )
    );
  }
}

/**
 * Implementation of hook_disable().
 * При выключении модуля — скрываем блоки с разделами меню
 */

function footerLinks_disable() {

  // Получаем всю необходимую информацию
  $custom_menus = footerLinks_get_custom_menus();

  // Опять залезаем своими рученками в БД и меняем статус блоков на 0
  foreach ( $custom_menus as $custom_menu ) {
    drupal_set_message( $custom_menu['menu_name'] . ' removed from ' .$custom_menu['region'] . 'region' );
    db_query(
      "UPDATE {blocks} SET status = 0 WHERE module = 'menu' AND delta = '%s'",
      $custom_menu['menu_name']
    );
  }

  // Обновляем состояние блоков на всякий случай
  _block_rehash();
}

Вот и все. Надеюсь, кто-нибудь найдет ответы на свои вопросы в данной статье.
Кстати, блоки с разделами меню не выводятся, пока в них не присутствует ни одной ссылки.

Для программного создания ссылки в новоявленном разделе меню можно воспользоваться стандартным API друпала:

<?php
$link = array(
  'nemu_name' => 'project-links',
  'link_path' => 'node/N',
  'link_title' => 'About project'
);
menu_link_save($item);

Альтернативный, возможно, более грамотный способ создания раздела меню — через drupal_execute

<?php
module_load_include('inc', 'menu', 'menu.admin');
       
$form_state = array();
$form_state['values'] = array(
  'menu_name' => 'test-menu',
  'title' => 'Test Menu Title',
  'description' => 'Test Menu Description',
);

drupal_execute('menu_edit_menu', $form_state, NULL);

Комментарии

Аватар пользователя q2_faith q2_faith 22 августа 2010 в 0:20

встала проблема продублировать примари линкс в другом блоке
не подскажите решение или в каком направлении думать? заранее спасибо