Drupal: Develop a Minimum Function Set of Module (English)

Understanding the development of Drupal's module is also equals to understand a concept of node (content type), a hook system (callback function named 'hook'), and a form ($form).

I have already explained Drupal's hook system in "Drupal: a Minimum Set of Hooks to Develop a Module". So let me try to implement a module concretely here. The module name is 'hook'.

It is necessary to implement a module with four files such as yourmodule.info, yourmodule.install, yourmodule.module, yourmodule.css since Drupal 5. Therefore, in case of a developement of a module called 'hook', those four files must be created. This hook module includes a set of fields such as a title, a body and a unique value hid (= hook ID) with one of letters from 'A' to 'E' in this 'hook' module. A letter 'A' to 'E' to be displayed will be stored the corresponding a value from one to five in a database. The default value of hid can be set in https://yourdomain.com/admin/settings/hook. The following is an example of the 'hook' module.

hook.info

; Semi-colon is a comment.
name = Hook
description = "A module template."
package =
version = VERSION

;
version = "5.x-1.x-dev"
project = "Example"

hook.install

<?php

/**
* Implementation of hook_install()
* Bind into Drupal's module system admin/build/modules.
* Basically make a database table which stores data handled by this module.
*/
function hook_install() {

  switch (
$GLOBALS['db_type']) {
    case
'mysql':
    case
'mysqli':
     
db_query("CREATE TABLE `hook`
                (
                  `nid` INT( 10 ) UNSIGNED NOT NULL ,
                  `hid` INT(  3 ) UNSIGNED NOT NULL DEFAULT '1',
                   PRIMARY KEY ( `nid` )
                )  ENGINE = MYISAM"
             
);
      break;

    case
'pgsql':
      break;
  }
}

/**
* Implementation of hook_uninstall()
* Drop a table that this module was using.
* Also delete a set of values in this module by variable_del
*/
function hook_uninstall() {

 
db_query('DROP TABLE {hook}');
 
variable_del('hook_option'); // Doi NOT Forget!

}

?>

hook.module

<?php

// Define constant strings
define('MODULE_NAME', 'Hook');
define('PRIVILEGE_ADMIN'  'administer' MODULE_NAME . ' server settings');
define('PRIVILEGE_CREATE' 'create'     MODULE_NAME . ' forms and docs');
define('PRIVILEGE_VIEW'   'view'       MODULE_NAME . ' forms and docs');
define('PRIVILEGE_EDIT'   'edit own'   MODULE_NAME . ' forms and docs');

/**
* The implementation of hook_help()
* Explain the URL in every single case statement
*/
function hook_help($section) {

  switch (
$section) {

  case
'admin/help#hook':
   
$o .= '<p>' . t('Submit, view and manage hook lists.') . '</p>';
    return
$o;

  case
'admin/modules#description':
    return
t('Allows users to submit, view and manage job records');

  case
'node/add#hook':
    return
t('Add a ' . MODULE_NAME . ' record.');

  }
}

/**
* The implementation of hook_perm()
* The definitions here may use access controls in admin/user/access
*/
function hook_perm() {

  return array(
         
PRIVILEGE_ADMIN,
         
PRIVILEGE_CREATE,
         
PRIVILEGE_VIEW,
         
PRIVILEGE_EDIT
       
);
}

/**
* The implementation of hook_access()
* Do access control of create, update, delete, view.
* @param op four values such as create, view, update, delete
*/
function hook_access($op, $node) {

  global
$user;

  if (
$op == 'create') {
    return
user_access(PRIVILEGE_CREATE);
  }

  if (
$op == 'view') {
    return
user_access(PRIVILEGE_VIEW);
  }

  if (
$op == 'update' || $op == 'delete') {
    if (
user_access(PRIVILEGE_EDIT)
    && (
$user->uid == $node->uid)) {
      return
TRUE;
    }
  }
}

/**
* The implementaiton of hook_menu()
* Describe Drupal's menus (paths), corresponding functions called by clicking it,
* and the combinations of access control.
*/
function hook_menu($may_cache) {

 
$items = array();

  if (
$may_cache) {

   
$items[] = array(
     
'path'                => 'node/add/hook',
     
'title'               => t('Hook'),
     
'access'              => user_access(PRIVILEGE_CREATE)
    );

   
$items[] = array(
     
'type'                => MENU_NORMAL_ITEM,
     
'path'                => 'admin/settings/hook',
     
'title'               => t(MODULE_NAME . ' default settings'),
     
'access'              => user_access(PRIVILEGE_ADMIN),
     
'callback'            => 'drupal_get_form',
     
'callback arguments'  => 'hook_admin',
     
'description'         => 'Configure Hook default settings'
   
);

  }

  return
$items;
}

/**
* The implementation of hook_node_info()
* Define content types.  Put a module name into 'hook'.
* 'hook' may not be only this module name but also different one.
* Allow to realize several forms in this one module by adding a set of
* hook, name, module, description into array
* Must keep a set of hook, name, module, description.
*/
function hook_node_info() {

  return  array(
             
'hook'        => array(
             
'name'        => t('Hook'),
             
'module'      => 'hook',
             
'description' => t('You can make a hook record and view them.')
            )
          );
}

/**
* The implementaiton of hook_admin()
* Allow to define multiple unique default values in admin/settings/hook
* by implementing this hook.
*/
function hook_admin() {

 
// hostname
 
$form['hook_option'] = array(
   
'#type'            => 'select',
   
'#title'           => t('hid default value'),
   
'#default_value'   => variable_get('hook_option', 1),
   
'#options'         => array('1'=>'A', '2'=>'B', '3'=>'C', '4'=>'D', '5'=>'E'),
   
'#size'            => 1,
   
'#weight'          => -10,
   
'#required'        => TRUE
 
);

  return
system_settings_form($form);
}

/**
* The implementation of hook_form()
* Define a form.
* @param node An instance of stored node when editting
* @return $form Drupal will make a form automatically when a form object is returned.
*/

function hook_form(&$node) {

 
// $form['hid']
 
$hid = $node->hid ? $node->hid : variable_get('hook_option', 1);

 
$form['title'] = array(
   
'#type'           => 'textfield',
   
'#title'          => t('Title'),
   
'#default_value'  => $node->title,
   
'#weight'         => -8,
   
'#required'       => TRUE,
  );

 
$form['hid'] = array(
   
'#type'           => 'select',
   
'#title'          => t('Hook hid value'),
   
'#options'        => array('1'=>'A', '2'=>'B', '3'=>'C', '4'=>'D', '5'=>'E'),
   
'#default_value'  => $hid,
   
'#weight'         => -6,
   
'#required'       => TRUE
 
);

 
// full description / body
 
$form['body_filter']['body'] = array(
   
'#type'           => 'textarea',
   
'#title'          => t('Body'),
   
'#rows'           => 4,
   
'#default_value'  => $node->body,
   
'#weight'         => -5,
   
'#required'       => TRUE
 
);

  
$form['body_filter']['format'] = filter_form($node->format);

  return
$form;
}

/**
* The implementation of hook_view()
* Display values stored in a form.
* @param &$node An object to be displayed
* @param $teaser boolean: Is a teaser or a full node?
* @param $page   boolean: Is the own page displayed?
*/
function hook_view(&$node, $teaser = FALSE, $page = FALSE) {

 
$node = node_prepare($node, $teaser);

 
$node->content['title'] = array(
   
'#value'  => theme('hook_title', $node->title),
   
'#weight' => -8
 
);

 
$node->content['hid'] = array(
   
'#value'  => theme('hook_hid',   $node->hid),
   
'#weight' => -6
 
);

 
$node->content['body'] = array(
   
'#value'  => theme('hook_body'$node->body),
   
'#weight' => -4
 
);

  return
$node;
}

/**
* The implementation of hook_insert()
* Called when a submit button is pressed in a form of creating a new content.
* Store values to your own prepared fields.  basic node information will be
* stored by Drupal.
* nid is also necessary as a primary key in your prepared table because nid which
* stands for 'node ID' is making a relation in between Drupal's node and your own data.
*/
function hook_insert($node) {

 
db_query(
   
"INSERT INTO {hook} (`nid`, `hid`) VALUES ( %d,        %d        )",
                                               
$node->nid, $node->hid
 
);
}

/**
* The implementation of hook_update()
* Called when a submit button is pressed in a form with editting mode.
*/
function hook_update($node) {

 
db_query("UPDATE {hook} set `hid`=%d WHERE nid=%d", $node->hid, $node->nid);
}

/**
* The implementation of hook_delete()
* Called when a delete button is pressed in a form.
*/
function hook_delete(&$node) {

   
db_query('DELETE FROM {hook} WHERE `nid`=%d', $node->nid);
}

/**
* The implementation of hook_load()
* Store data that you want to process in your module into your prepared table
* by yourself (hook_insert, hook_update).
* Drupal will automatically process node information which is a minimum set of content,
* however, it is necessary to tell Drupal the differentical information in between
* a Drupal's node and your module's processing data in a field in your table
* when you want to display your data in your module. that your module processes.
* This is the implementation of the function.
*/
function hook_load($node) {

 
$r db_fetch_object(
         
db_query('SELECT `hid` FROM {hook} WHERE nid=%d', $node->nid)
        );

  return
$r;
}

/**
* The implementation of hook_validate()
* Called before hook_insert or hook_update are executed.
* Validate the inputted vlaues sent from a form to this module
* by implement this hook function.
*/
function hook_validate($form_id, $form_values) {

// dump the form validate variables
//print '<code>' . print_r($form_values, true); exit();

}

/**
* The implementation of theme_hook_title()
* Link to the style sheet when displaying a title
*/
function theme_hook_title($content) {

 
$output .= '<div class="hook_view_title">';
 
$output .= t('Title:');
 
$output .= $content;
 
$output .= '</div>';

  return
$output;
}

/**
* The implementation of theme_hook_body()
* Link to the style sheet when displaying a body
*/
function theme_hook_body($content) {

 
$output .= '<div class="hook_view_body">';
 
$output .= t('Body:');
 
$output .= $content;
 
$output .= '</div>';

  return
$output;
}

/**
* The implementation of theme_hook_hid()
* Link to the style sheet when displaying hid
*/
function theme_hook_hid($content) {

 
$options = array('1'=>'A', '2'=>'B', '3'=>'C', '4'=>'D', '5'=>'E');

 
$output .= '<div class="hook_view_value">';
 
$output .= t('hid value: %value', array('%value' => $options[$content]));
 
$output .= '</div>';

  return
$output;
}

?>

hook.css

/* Write the following appropriately */

#hook {
  margin-top: 0;
}
#hook img {
  margin-bottom: 0.75em;
}
#hook .hook-icon {
  float: right;
  display: block;
}
#hook .hook-item {
  margin-bottom: 1.5em;
}
#hook .hook-item-title {
  margin-bottom: 0;
  font-size: 1.3em;
}
#hook .hook-item-meta, .hook-item-body {
  margin-bottom: 0.5em;
}
#hook .hook-item-categories {
  font-size: 0.9em;
}
#hook td {
  vertical-align: center;
}
#hook td.categorize-item {
  white-space: nowrap;
}
#hook .categorize-item .body {
  margin-top: 0;
}
#hook .categorize-item h3 {
  margin-bottom: 1em;
  margin-top: 0;
}

トラックバック URL: https://perltips.twinkle.cc/trackback/198
Posted on 2007-05-24 by yas |
Drupal で、必要最低限の機能のモジュールを作る。
Trackback from Perl Tips: Drupal でのモジュール開発を理解するということは node のコンセプト......
Posted by Perl Tips (未認証ユーザ) on 2007/04/19(木) 09:23
Drupal: Minimum Hooks to Develop Your Own Module
Trackback from Perl Tips: Obviously there is a learning curve to ......
Posted by Perl Tips (未認証ユーザ) on 2007/04/21(土) 20:39
Drupal で、モジュールを開発するために必要な最低限の hook
Trackback from Perl Tips: Drupal の hook (つまりコールバック/Callback)は、その世......
Posted by Perl Tips (未認証ユーザ) on 2007/04/21(土) 20:43