Welcome to the Geeks & God Static Archive. Read more »

Creating a Simple Drupal Module

User Rating:
4.210525
Average: 4.2 (38 votes)

In the latest episode of Geeks and God, Matt and Rob talked about creating custom modules and using hook_form_alter to modify Drupal forms. They also talked about this in the Drupal 6 Overview in Episode 90. There are numerous resources on using Drupal hook code, and there's a lengthy tutorial on creating a module, but I've never seen anything that shows how blindingly simple it is. So that's the goal of this brief tutorial.

I'm going to show you how to create a very simple Drupal 6 module that uses hook_form_alter to remove a few fields from the node edit form, but only for blog and page nodes. We'll alter different fields for each type. This should give you a foundation for more complex custom work.

In its simplest form, a custom module is installed in its own directory under sites/all/modules, in a folder that matches the module name. A simple module requires two files: an info file that describes the module, and a module file that contains the php code.

Let's create a folder called sites/all/modules/mysite and build a bare-bones mysite.info file using the text editor of your choice.

name = My Site
description = Provides custom functionality for this site
core = 6.x
 
project = "mysite"
package = Other

If we simply created a skeleton mysite.module file, we could already enable our new module, although it wouldn't do anything until we actually added some code to it. The actual act of creating a module is that simple. But let's go ahead and create our form altering module, and then I'll explain it.

<?php
// $Id$
 
/**
 * @file
 * Drupal Module: mysite
 * Adds custom code specific to this Drupal 6 site.
 */
 
/**
 * Implementation of hook_form_alter().
 */
function mysite_form_alter(&$form, &$form_state, $form_id) {
  // print $form_id;
  switch ($form_id) {
    case 'blog_node_form':
      // remove some unwanted node editing fields
      $form['revision_information']['#access'] = 0;
      $form['menu']['#access'] = 0;
      $form['author']['#access'] = 0;
      // override node options permissions defined by 'administer nodes'
      $form['options']['#access'] = 1;
      $form['options']['status']['#access'] = 1;
      $form['options']['promote']['#access'] = 0;
      $form['options']['sticky']['#access'] = 0;
    break;
    case 'page_node_form':
      // don't ever allow page nodes to be promoted or sticky
      $form['options']['promote']['#access'] = 0;
      $form['options']['sticky']['#access'] = 0;
    break;
  }
}

The comment section at the top is not required, but you should include this to stay consistent with Drupal coding standards.

To implement hook_form_alter, simply create a function called modulename_form_alter, using the parameters shown. Drupal will automatically use this function if it exists in your module.

If you're not sure which form you're altering, uncomment the print $form_id line, and form names will appear at the top of your page. (Remove this line in production environments, of course!)

Notice that we're mostly just ripping out sections of the form. Removing the author section does not work well, however, because it makes all nodes authored by the anonymous user. By disabling the author section of the form, I'm removing the ability to override authorship information even for users who would normally be allowed to do so, like the site administrator.

That's all there is to it, but you may be wondering how I know what values to manipulate. Add the following section of code after (or replacing) the unset commands, and you'll see:

$form['form_array'] = array(
  '#value' => '<pre>'. print_r($form, 1) .'</pre>',
  '#weight' => '99',
);

This piece of code adds a new element, called form_array to the form. It will spit out a big ugly hunk of preformatted text at the end of your node edit form, showing all of the existing form elements, any of which can be altered.

So go ahead and create this simple module on a test site, and have fun. With even a basic understanding of php syntax, you'll be tweaking up those input forms in no time, and your users will love you for removing all of those confusing fields they don't need to see.

Updated 22-Dec-2008

  • Fixed a syntax error.
  • Changed code to use #access property instead of unsetting values. (See also this comment by Matt Farina.)
  • Added lines to enable "Published" checkbox on all blog entries regardless of "administer nodes" permission.
  • Added some comments to the code.

error in above code

4

There is a syntax error in line 17 above:

unset($form['options');
should be:
unset($form['options']);

Syntax Error Fixed

Error fixed. Thanks, Arlin!

Micah

Thanks for posting this

5

Thanks for posting this Micah. This was a big help to me.

bobkepford.com

I'm trying to modify a node

5

I'm trying to modify a node form so that a CCK User reference field has the node author as the default value. The code below will populate the field with a specific user but I need it to be dynamic. Anyone have an idea of how to do this? Thanks.

<?php
// $Id$

/*
* @file
* Drupal Module: Articulation Forms
* Adds custom code specific to this Drupal 6 site.
*/

function articulation_forms_form_alter(&$form, &$form_state, $form_id) {
//  print $form_id;
  switch ($form_id) {
    case 'articulation_node_form':
// Populate the cck user_ref field with the author of the node. The current user
         global $user;
$form['field_teacher']['#default_value']= Array (0 => Array ( 'uid' => 15));

       
    }
}

bobkepford.com

You need to change the

5

You need to change the following line;

$form['field_teacher']['#default_value']= Array (0 => Array ( 'uid' => 15));

to:

$form['field_teacher'][0]['#default_value']['uid']= $form['uid']['#value'];

The caveat with this approach is that this will always set the CCK field to the node author. This means that any existing field_teacher value will be clobbered with the node author. Additional logic will be required to check if field_teacher is already set and to proceed accordingly.

That works perfectly. Thanks

5

That works perfectly. Thanks so much

bobkepford.com

Cron module

5

Hi,

Thanks for this article. I am experienced with Drupal but never created a module. I am not a programmer but not afraid to put in some effort. The module I would like to develop is quite simple I guess, see my post here: http://drupal.org/node/599554 I short i'd like to make a module that puts a site in maintenance modus, based on the day of the week. E.g. a website would only be online on certain days.

Do you have any pointer for me to start? Like this article? I would have to get familiar with the basics to get me started.

Sample Module

3

HI All,

I need full sample of module, anybody please give the example of modules

Cheers
Balaji

Questions in my Mind

5

Hi Micah, i am new in Drupal world and so having many wonders in my mind. Few very silly questions related to your tutorial are, when i created the module folder (namely: mysite) and placed that folder (including with mysite.info and mysite.module) into all/modules, then shouldn't it appear into my Administer-Modules list? In another way, how to activate my own created module(s)?

Moreover, Micah, suppose in my drupal site i would like to have many pages but some pages will have my own personal forms. Actually i already crated many forms by PHP and connected to mysql database long time ago and now if i wanna use those forms into my drupal site then can you please help me to find the simple steps. Main two questions are:

a) How to embed those forms to my drupal site?

b) Currently those forms are hooked up with my own defined mysql tables and fields. How can i convert those to drupal defines tables and fields?

I started reading various materials few days ago but it is so much reading that i lost my track. Therefore, I will be really glad if can get your help. Your tutorial is very nicely written and so was thinking you will be the right guy.

Best wishes

5Thanks for posting

3

5Thanks for posting this Micah.
This was a big help to me.

bobkepford.
com
Frank Verdin