I have a lot of mymodule_form_FORM_ID_alter()s in my module and I want to move them to a separate file (mymodule.form.inc), I found hook_hook_info() but I couldn't figure out how to use it for that specific case.

I tried adding:

$hooks['form_alter'] = array(
  'group' => 'form'

to mymodule_hook_info() but it didn't run the form alterers that I moved to the separate file. Any ideas how to get it to work?

  • How about including the this file in mymodule.module? Sep 18, 2011 at 10:36
  • With hook_hook_info() there is not need to manually include the file.
    – apaderno
    Aug 18, 2012 at 13:06
  • If you only want to move implementations of one specific module, then hook_module_implements_alter() would do the trick. But be careful, there are people who would say this is a bad practice. drupal.stackexchange.com/questions/108884/…
    – donquixote
    Apr 2, 2014 at 20:34

3 Answers 3


It works pretty well, the only thing is that if you want to implement hook_form_FORM_ID_alter(), you need to add:

  $hooks['form_FORM_ID_alter'] = array(
    'group' => 'form'
  return $hooks;
  • yep, it works that way. Too bad there's no generic way and we have to manually type each form alterer there.
    – Daniel
    Sep 20, 2011 at 8:43
  • There is a general way - you can use hook_form_alter() instead of hook_form_FORM_ID_alter() in both places - in hook_hook_info() as well as in your hook name. Sep 20, 2011 at 12:44

Don't. This is not supported by Drupal core. In fact, hook_hook_info is intended for modules declaring hooks, not modules implementing them.

In addition, if two modules on a site declare a group for the same hook, all uses of the hook in $module.$group.inc files will break.

Instead, create stubs that do a module_load_include, and then a function call.


You can also use the solution found here.

Here's an easy way to get ALL hook_form_FORM_ID_alter() implementations loaded from a .inc file, WITHOUT declaring them each separately in hook_hook_info().

In MY_MODULE.module add the following code.

 * Implements hook_hook_info_alter().
function MY_MODULE_hook_info_alter(&$hooks) {
  $hooks['form_alter']['group'] = 'form'; 

Then in MY_MODULE.form.inc make sure to add the following code.

 * Implements hook_form_alter().
function MY_MODULE_form_alter(&$form, &$form_state, $form_id) {

// Add all MY_MODULE_form_FORM_ID_alter() functions below here.

With the above MY_MODULE_form_alter() declared in this .inc file (even if it's empty), all MY_MODULE_form_FORM_ID_alter() implementations declared in the same file will get loaded properly. Without this function the file will not be loaded at all.

This works because drupal_prepare_form() calls hook_form_alter() (and loads this .inc file) before calling hook_form_FORM_ID_alter() for each form build.

  • It is almost all correct, except that the hook to implement is hook_hook_info(), not hook_hook_info_alter(). There is not need to define hook_form_alter() in the included file, as the include file is first loaded, and then Drupal checks the function implementing the hook exists. In the case it doesn't exists, the file is already included, and Drupal would find the implementations of hook_form_FORM_ID_alter().
    – apaderno
    Aug 18, 2012 at 13:24
  • The code I copied over is a solution that lets you avoid declaring each FORM_ID_alter() in hook_hook_info(), in case you find that convenient.
    Aug 20, 2012 at 21:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.