Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Apress.Pro.Drupal.7.Development.3rd.Edition.Dec.2010.pdf
Скачиваний:
63
Добавлен:
14.03.2016
Размер:
12.64 Mб
Скачать

CHAPTER 4 THE MENU SYSTEM

If you wanted to use the values passed in the URL, you could update the page callback function, using the values as follows:

function menufun_hello($first_name = '', $last_name = ‘’) {

return t('Hello @first_name @last_name from @from_first_name @from_last_name', array('@first_name' => $first_name, '@last_name' => $last_name));

}

Update your version, clear cache, and give it a try to see the results when you use http://example.com/?q=menufun.

Page Callbacks in Other Files

If you don’t specify otherwise, Drupal assumes that your page callback can be found inside your .module file. In Drupal 7, many modules are split up into multiple files that get conditionally loaded so that a minimum amount of code is loaded on each page request. The file key (e.g., ‘file’ => ‘menufun_greetings.inc’) of a menu item is used to specify the name of the file that contains the callback function.

As an example, I’ll update the menufun.module hook_menu() function to include the name of the file where the new callback function resides. The following code adds ‘file’ => ‘menufun_greeting’ to the item array. I also changed the page callback to menufun_greeting just to demonstrate that the callback isn’t using the function that already exists in the menufun.module file.

/**

* Implementation of hook_menu(). */

function menufun_menu() { $items['menufun'] = array(

'title' => 'Menu Fun',

'page callback' => 'menufun_greeting', 'file' => 'menufun_greeting.inc',

'page arguments' => array('Jane', 'Doe'), 'access callback' => TRUE,

'type' => MENU_CALLBACK,

);

return $items;

}

Next I’ll create a new file named menufun_greeting.inc in the menufun directory with the following code.

<?php

function menufun_greeting($first_name = '', $last_name = '', $from_first_name='', $from_last_name='') {

return t('Hello @first_name @last_name from @from_first_name @from_last_name', array('@first_name' => $first_name, '@last_name' => $last_name, '@from_first_name' =>

$from_first_name, '@from_last_name' => $from_last_name));

}

67

CHAPTER 4 THE MENU SYSTEM

Save both files, clear your cache, and test the revised approach. You should get exactly the same results, only this time the callback function resides externally from the .module file.

Adding a Link to the Navigation Block

In the menufun example, we declared that our menu item was of type MENU_CALLBACK. By changing the type to MENU_NORMAL_ITEM, we indicate that we don’t simply want to map the path to a callback function; we also want Drupal to include it in a menu.

function menufun_menu() { $items['menufun'] = array(

'title' => 'Menu Fun',

'page callback' => 'menufun_greeting', 'file' => 'menufun_greeting.inc',

'page arguments' => array('Jane', 'Doe'), 'access callback' => TRUE,

'type' => MENU_NORMAL_ITEM,

);

return $items;

}

The menu item would now show up in the navigation block, as shown in Figure 4-6.

Figure 4-6. The menu item appears in the navigation block.

If we don’t like where it is placed, we can move it up or down by decreasing or increasing its weight. Weight is another key in the menu item definition:

function menufun_menu() { $items['menufun'] = array(

'title' => 'Greeting',

'page callback' => 'menufun_hello',

68

CHAPTER 4 THE MENU SYSTEM

'page arguments' => array('Jane', 'Doe'), 'access callback' => TRUE,

'weight' => -1,

);

return $items;

}

The effect of our weight decrease is shown in Figure 4-7. Menu items can also be relocated without changing code by using the menu administration tools, located at Structure -> Menus (the menu module must be enabled for these tools to appear).

Figure 4-7. Heavier menu items sink down in the navigation block.

Menu Nesting

So far, we’ve defined only a single static menu item. Let’s add a second and another callback to go with it:

function menufun_menu() { $items['menufun'] = array(

'title' => 'Menu Fun',

'page callback' => 'menufun_greeting', 'file' => 'menufun_greeting.inc',

'page arguments' => array('Jane', 'Doe'), 'access callback' => TRUE,

'type' => MENU_NORMAL_ITEM, 'weight' => '-1',

);

$items['menufun/farewell'] = array( 'title' => 'Farewell',

'page callback' => 'menufun_farewell', 'file' => 'menufun_greeting.inc',

69

Download from Wow! eBook <www.wowebook.com>

CHAPTER 4 THE MENU SYSTEM

'access callback' => TRUE, 'type' => MENU_NORMAL_ITEM,

);

return $items;

}

Next in the menufun_greeting.inc file, add the page callback function menufun_farewell, as shown here:

function menufun_farewell() {

return t('Goodbye');

}

After updating the module, remember to clear cache.

Drupal will notice that the path of the second menu item (menufun/farewell) is a child of the first menu item’s path (menufun). Thus, when rendering (transforming to HTML) the menu, Drupal will indent the second menu, as shown in Figure 4-8. It has also correctly set the breadcrumb trail at the top of the page to indicate the nesting. Of course, a theme may render menus or breadcrumb trails however the designer wishes.

Figure 4-8. Nested menu

Access Control

In our examples so far, we’ve simply set the access callback key of the menu item to TRUE, meaning that anyone can access our menu. Usually, menu access is controlled by defining permissions inside the module using hook_permission() and testing those permissions using a function. The name of the function to use is defined in the access callback key of the menu item and is typically user_access. Let’s define a permission called receive greeting; if a user does not have a role that has been granted this

70

CHAPTER 4 THE MENU SYSTEM

permission, the user will receive an “Access denied” message if he or she tries to go to http://example.com/?q=menufun.

/**

* Implementation of hook_permission() */

function menufun_permission() { return array(

'receive greeting' => array( ‘title' => t('Receive a greeting'),

'description' => t('Allow users receive a greeting message'), ),

);

}

/**

* Implementation of hook_menu(). */

function menufun_menu() { $items['menufun'] = array(

'title' => 'Menu Fun',

'page callback' => 'menufun_greeting', 'file' => 'menufun_greeting.inc',

'page arguments' => array('Jane', 'Doe'), 'access callback' => 'user_access',

'access arguments' => array('receive greeting'), 'type' => MENU_NORMAL_ITEM,

'weight' => '-1',

);

$items['menufun/farewell'] = array( 'title' => 'Farewell',

'page callback' => 'menufun_farewell', 'file' => 'menufun_greeting.inc', 'access callback' => 'user_access',

'access arguments' => array('receive greeting'), 'type' => MENU_NORMAL_ITEM,

);

return $items;

}

In the preceding code, access will be determined by the result of a call to user_access ('receive greeting'). In this way, the menu system serves as a gatekeeper, determining which paths may be accessed and which will be denied based on the user’s role.

71

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]