Using hook_form_alter in a custom module

Making what would seem to be really simple HTML changes in Drupal can appear really perplexing until you learn about the hook_alter functions. These Drupal specific functions are great for you to override Drupal behavior when the normal configuration options don’t provide a means to do so. That’s really important too: learning when to write code and when not to for Drupal. Always explore the available options for changing the way a module or theme presents data before you try to write code until you really know how to use Drupal properly. Writing code is satisfying but a waste of time in Drupal if someone has already written it for you.

But if there is an occasion to write some code, here is a really simple example of what to do to alter the presentation through a hook. Specifically, we are going to reverse the display of the user name and email fields on the user registration form so that the user name field is listed below the email field, the opposite of the way the form is written. This is the high level stuff that we are about to do.

The function or “hook” to override a form is:


where hook will be replaced by the name of the module I am going to create to do this and FORM_ID will be replaced by the ID of the actual form.

  1.  Identify the form ID of the Drupal form, in this case the User Registration Form.
  2.  Find the form in the core so that we can see what it is, where it lives and how it does what it does
  3. Create a new module to override the form so that we can make a very simple change

Find the form
Go to the form in a browser
View its HTML source in the browser
Figure out the form ID of the form you are altering. The ID will be the “id” attribute of the HTML form tag.
In the case of the User Registration form, the ID is, user_register_form. I can see this in the HTML source as “ID=user-register-form” but I know that the machine name will be with underscores and not dashes. Now, this is where it gets a bit tricky. Since the form is the user registration form, I know that I am certainly dealing with the Core User Module. I know enough about Drupal to know this is likely true so I know where to look. What I am emphasizing is to be really careful and ONLY do this in a test environment until you really know what you are doing. See my post about Get Pantheon if you want a good free Drupal testbed. One of the things that you can do to track down the area of code that you want to work with is to search through the .module file(s) for rendered text. When I look at the Drupal form (the user registration form in this case) that I want to alter, I note that there is a description that says, “Spaces are allowed; punctuation is not allowed except for periods, hyphens, apostrophes, and underscores.” If I search for that specific text in the user.module file, I am taken to line 1039. This is the precise area that I want to change, so I know that I am in the right area. If you are unsure of which .module file you need, you can expand your spearch to look at multiple files.

This is the code from the user.module file. It shows the user name code, then the email code below.

$form[‘account’][‘name’] = array(
‘#type’ => ‘textfield’,
‘#title’ => t(‘Username’),
‘#maxlength’ => USERNAME_MAX_LENGTH,
‘#description’ => t(‘Spaces are allowed; punctuation is not allowed except for periods, hyphens, apostrophes, and underscores.’),
‘#required’ => TRUE,
‘#attributes’ => array(‘class’ => array(‘username’)),
‘#default_value’ => (!$register ? $account->name : ”),
‘#access’ => ($register || ($user->uid == $account->uid && user_access(‘change own username’)) || $admin),
‘#weight’ => -10,
$form[‘account’][‘mail’] = array(
‘#type’ => ‘textfield’,
‘#title’ => t(‘E-mail address’),
‘#maxlength’ => EMAIL_MAX_LENGTH,
‘#description’ => t(‘A valid e-mail address. All e-mails from the system will be sent to this address. The e-mail address is not made public and will only be used if you wish to receive a new password or wish to receive certain news or notifications by e-mail.’),
‘#required’ => TRUE,
‘#default_value’ => (!$register ? $account->mail : ”),

Since we want to reverse the display order of the two fields, this is what we’ll do. Notice the ‘#weight’ key of the array for the user name? since that weight is “light” it will float to the top. If we give it a heavier weight, it will sink.

I create these items:

  • a folder called registeruser in sites/all/modules
  • a file called – this can just have all the normal .info stuff
  • a file called registeruser.module – the code is below:

function registeruser_form_user_register_form_alter(&$form, &$form_state, $form_id) {
$form[‘account’][‘name’][‘#weight’] = 1;

Since I just want to alter the one key, I can write it on just the two lines to make it simpler. The weight is now 1 instead of -10 so it will sink below the default of 0.
I enable my new module and test it out. I see now that the fields are in the reversed order. This change isn’t groundbreaking or anything, but it is a good example of how to user the hook_form_alter() function.

Use the hook_field_schema function from your custom module’s .install file

Many custom modules will not need to add information directly to your MySQL database. But if you do want to store new info from your module, you’ll need to include a .install file with your .module and .info files and use the hook function listed above to do this.

This references a great book that I picked up from Yeah, I know; another shameless plug. But it is worth it.

This is the code that you need to place in your install file. You’ll note that it looks similar to the SQL statements that you would use to add the info manually.

* Implements hook_field_schema()
function countryinfo_field_schema() {
$columns = array(
‘country’ => array(
‘description’ => ‘Two letter ISO country code of this
‘type’ => ‘varchar’,
‘length’ => 2,
‘not null’ => FALSE,
‘default’ => ”,
return array(
‘columns’ => $columns,

If this is the type of development you want to be able to do, take a look at the book at

Drupal – When to Code and when NOT to….

I have found a really great book for those who want to do Drupal development from O’Reilly.Programmer’s Guide to Drupal. This isn’t really a book for those who want to lhaveearn PHP though. It’s for those who are already comfortable with coding and want to apply those skills to Drupal.


What this book does really well is to show you when to start writing your own code and when not to. It also recommends that a novice Drupal developer learn to build sites in Drupal without any custom coding at all in the beginning. With something like 24,000 modules out there, there is always a good chance that someone has already written code for the very purpose you have. Or that judicious use of core modules will allow you to get where you need to be.

Check this book out: it is AWESOME!

How to write a working Drupal Module

The power of Drupal can only be leveraged best if you learn how to write your own custom modules. If you know a bit of PHP and aren’t intimidated by functions, elements, arrays and the like, this is the best place to start. Community Docs. This tutorial will take you through the ins and outs of writing a basic but very functional Drupal module. This tutorial will, in great detail, explain all the steps needed to create a module that will allow you to show a configurable number of posts in a block, create a configuration menu option for the module and include a Help page.

I’ve looked at many online tutorials on how to write basic modules and this one is the best. It has the most thorough explanations and is rigorous in its adherence to Drupal commenting standards, coding standards and naming conventions. As well as the Drupal specific functions that make developing for Drupal easier. If you want to learn Drupal PHP development, this is the place to start.

Resolved – Error 495 in Drupal – panels_renderer_standard.class.php

Notice: Undefined index: settings in panels_renderer_standard->render_pane() line 495 panels_renderer_standard.class.php). this is the original error. this is my contribution to the issue on

Posted by pjmcghee on October 23, 2013 at 8:46am new

Hey, I was able to resolve this error pretty easily. I had been working with some new styles, making a clone of an existing, changing styles around on a specific panel pane. then, i decided that i really needed to make the change to the entire column. so i added a style there and changed the panel pane style back to the original style. i then began receiving the error.

I was quite sure what was going on after reading this post (and thanks @merlinofchaos! for everything!). I recreated the offending, or broken panel pane to make sure it worked properly, deleted the original pane and saved the page. the error is now gone.

then, i added the original style to the new, recreated pane. now, all is correct and the error is gone. and i have the new style on the column so that i can style the whole thing the way that works best for me.

so there never was actually an empty style, i believe that the system just got a little confused with the multiple changes. that also seems to be consistent with some drupal panel behavior. sometimes you just need to delete and recreate rather than fix unless you want to really dig into the db. and i really don’t!

small price to pay for the amazing panels module. @merlinofchaos – you rock.

Drupal Site indexing – MySQL Errors, CRON timeouts

Since I recently dumped almost 17,000 new nodes into my DB in a relatively short time, I have been keeping a close eye on how the back end is responding. The main concern that I have is the indexing process for the new data. I began receiving errors from MySQL as seen in the SS.

In the Drupal Admin UI, check the number of nodes that are indexed per


CRON run. In my case, I had it set to 500, the maximum. This was a bit of overkill and I ended up making the value lower. I also increased the PHP memory, which you can check under “status reports”.

…PHP 5.3.27 (more information)
PHP extensions Enabled
PHP memory limit 512M
PHP register globals Disabled…

I really had simply to tweak the settings. I ended up at 100 nodes per run, one run per hour and PHP mem allocation as seen above. From the Search Options UI, you can see the status of the indexing, how fast, how many nodes, etc.

Flag Content right from a View

I installed the Views for PHP module. 33k installs and somehow I missed this. Then, I found this great post on how to use the Global:PHP “field” to add PHP that will allow for a Flag entry right on the View.

This gives me a nice simple way to bookmark content. Very nice. The screecast tells you all you need to know. Plus, the info given can have many applications. VERY COOL.

Thanks to the guys at for the info.

Image – Module – Screencast on adding the PHP using the Views PHP module

Customizing your theme

Once again, I have a book recommendation for you. And this one may be the best of any that I have picked up. Ric Shreves’ Drupal 7 Themes. This one is great. But I do have to warn you that it isn’t for novices. I started reading this one several months ago and decided that I needed to brush up on some PHP, CSS and HTML stuff, AND learn more Drupal before I could really make use of it. But if yLearn drupalou are at that point, where the idea of adding a content type for a specific need is understood, where the files that go into a theme are reasonably well understood, then this one will be for you. This is the book that I am really going to be able to make use of going forward in my theming.


Good book for PHP, MySQL and Apache

I have been working with this particular book now for a couple of months now and I have to say that it is one of my favorites.

Sam’s Teach Yourself PHP, MySQL and Apache. – this link goes to Amazon.Image

This book is perfect for where I want to go with Drupal. xAMP is the Drupal backbone and this book covers everything that I need from the last three letters of this acronym. There code sample are well documented and helpful. Check it out if you plan to be able to develop for Drupal and not just implement the modules and themes that are on