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

C H A P T E R 2

■ ■ ■

Writing a Module

Modules are the basic building blocks that form the foundation of Drupal and are the mechanisms for extending the functionality provided by the off-the-shelf version of Drupal, also known as Drupal core. I often explain to those who are unfamiliar with Drupal that modules are like Lego building blocks. They fit together perfectly by following a predefined set of guidelines, and with a combination of modules, you can build rich and complex solutions.

There are two general categories of Drupal modules—core and contributed. Core modules are those that are shipped with Drupal and include modules such as polls, menus, taxonomy, search, feed aggregator, and forums. Contributed modules are all of the modules created by the community that extend and enhance the functional footprint of Drupal core. There are literally thousands of contributed modules available for download at http://drupal.org/project/modules and span everything from simple single task modules, such as displaying the current date and time, to complex solutions, such as an e-commerce storefront.

In this chapter, I will show you how to build a custom module from scratch. As you build the module, you’ll learn about the standards to which modules must adhere. I need a realistic goal, so let’s focus on the real-world problem of annotation. When looking through the pages of a Drupal web site, you may want to write a note about that page. We could use Drupal’s comments feature to accomplish this, but comments are typically viewable by anyone visiting the site, or authenticated users. Annotations, on the other hand, are viewable only by the node’s author.

Creating the Files

The first thing we are going to do is to choose a name for the module. The name “annotate” seems appropriate—it’s short and descriptive. Next, I need a place to put the module. Contributed and custom modules are stored in the /sites/all/modules directory, with each module stored in its own directory that uses the same name as the module.

Note Drupal core modules are stored in the /modules directory—protecting your custom and contributed modules from being overwritten or deleted during an upgrade.

13

CHAPTER 2 WRITING A MODULE

You may wish to create a /sites/all/modules/custom directory to hold any modules that you create from scratch, making it easy for someone looking at your site to understand which modules are contributed modules that were downloaded from Drupal.org and which modules were custom-coded for this site. Next I’ll create an annotate directory within the /sites/all/modules/custom directory to hold all of the files associated with the annotate module.

The first file I will create for the new module is the annotate.info file. Every module in Drupal 7 must have a .info file, and the name must match the name of the module. For the annotate module, the basic information required for Drupal to recognize the module is

name = Annotate

description = "Allows users to annotate nodes." package = Pro Drupal Development

core = 7.x

files[] = annotate.module files[] = annotate.install files[] = annotate.admin.inc

configure=admin/config/content/annotate/settings

The structure of the file is standard across all Drupal 7 modules. The name element is used to display the name of the module on the Modules configuration page. The description element describes the module and is also displayed on the Modules configuration page. The package element defines which package or group the module is associated with. On the Modules configuration page, modules are grouped and displayed by package. The Core field defines the version of Drupal the module was written for. The php element defines what version of PHP is required by the module. And, the files element is an array of the names of the files that are associated with the module. In the case of the annotation module, the files associated with this module are the annotate.module and annotate.install files.

We could assign optional values in addition to those listed previously. Here’s an example of a module that requires PHP 5.2 and is dependent on the forum and taxonomy modules being installed in order for this module to work.

name = Forum confusion

description = Randomly reassigns replies to different discussion threads. core = 7.x

dependencies[] = forum dependencies[] = taxonomy files[] = forumconfusion.module files[] = forumconfusion.install

package = "Evil Bob's Forum BonusPak" php = 5.2

Now we’re ready to create the actual module. Create a file named annotate.module inside your sites/all/modules/custom/annotate subdirectory. Begin the file with an opening PHP tag and a CVS identification tag, followed by a comment:

14

CHAPTER 2 WRITING A MODULE

<?php

/**

*@file

*Lets users add private annotations to nodes.

*Adds a text field when a node is displayed

*so that authenticated users may make notes.

*/

First, note the comment style. We begin with /**, and on each succeeding line, we use a single asterisk indented with one space ( *) and */ on a line by itself to end a comment. The @file token denotes that what follows on the next line is a description of what this file does. This one-line description is used so that api.module (see http://drupal.org/project/api), Drupal’s automated documentation extractor and formatter, can find out what this file does. While you’re on Drupal.org, also visit http://api.drupal.org. Here you’ll find detailed documentation on every API that Drupal provides. I suggest you take a moment and look around this section of Drupal.org. It’s an invaluable resource for those of us who develop or modify modules.

After a blank line, we add a longer description aimed at programmers who will be examining (and no doubt improving) our code. Note that we intentionally do not use a closing tag (?>); these are optional in PHP and, if included, can cause problems with trailing whitespace in files (see http:// drupal.org/coding-standards#phptags).

Note Why are we being so picky about how everything is structured? It’s because when hundreds of people from around the world work together on a project, it saves time when everyone does things one standard way. Details of the coding style required for Drupal can be found in the “Coding standards” section of the Developing for Drupal Handbook (http://drupal.org/coding-standards).

Our next order of business is to define some settings so that we can use a web-based form to choose which node types to annotate. There are two steps to complete. First, we’ll define a path where we can access our settings. Then, we’ll create the settings form. To make a path, I need to implement a hook, specifically hook_menu.

Implementing a Hook

Drupal is built on a system of hooks, sometimes called callbacks. During the course of execution, Drupal asks modules if they would like to do something. For example, when a node is being loaded from the database prior to being displayed on a page, Drupal examines all of the enabled modules to see whether they have implemented the hook_node_load() function. If so, Drupal executes that module’s hook prior to rendering the node on the page. We’ll see how this works in the annotate module.

15

CHAPTER 2 WRITING A MODULE

The first hook that we will implement is the hook_menu() function. We’ll use this function to add two menu items to the administrative menu on our site. We will add a new “annotate” menu item off of the main admin/config menu and a submenu item under “annotate” named “settings,” which when clicked will launch the annotate configuration settings page. The values of our menu items are arrays consisting of keys and values describing what Drupal should do when this path is requested. We’ll cover this in detail in Chapter 4, which covers Drupal’s menu/callback system. We name the call to hook_menu annotate_menu”—replacing “hook” with the name of our module. This is consistent across all hooks— you always replace the word “hook” with the name of your module.

Here’s what we’ll add to our module:

/**

* Implementation of hook_menu(). */

function annotate_menu() { $items['admin/config/annotate'] = array(

'title' => 'Node annotation',

'description' => 'Adjust node annotation options.', 'position' => 'right',

'weight' => -5,

'page callback' => 'system_admin_menu_block_page',

'access arguments' => array('administer site configuration'), 'file' => 'system.admin.inc',

'file path' => drupal_get_path('module', 'system'),

);

$items['admin/config/annotate/settings'] = array( 'title' => 'Annotation settings',

'description' => 'Change how annotations behave.', 'page callback' => 'drupal_get_form',

'page arguments' => array('annotate_admin_settings'), 'access arguments' => array('administer site configuration'), 'type' => MENU_NORMAL_ITEM,

'file' => 'annotate.admin.inc',

);

return $items;

}

Don’t worry too much about the details at this point. This code says, “When the user goes to http://example.com/?q=admin/config/annotate/settings, call the function drupal_get_form(), and pass it the form ID annotate_admin_settings. Look for a function describing this form in the file annotate.admin.inc. Only users with the permission administer site configuration may view this menu item.” When the time comes to display the form, Drupal will ask us to provide a form definition (more on that in a minute). When Drupal is finished asking all the modules for their menu items, it has a menu from which to select the proper function to call for the path being requested.

Note If you’re interested in seeing the function that drives the hook mechanism, see the module_invoke_all() function in includes/module.inc (http://api.drupal.org/api/function/module_invoke_all/7).

16

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