I'm facing an issue for a few hours now. I created a new module that must render an admin page with some settings and another one with analytics data. The second one must use a custom template file that I created for the occasion.

I added a hook_theme() in my .module file and everything worked fine for a while.

When refactoring my code I wanted to move the hook_theme() in a subfile.inc of my module. Even though I cleared the caches, I always get the issue Theme hook "my_custom_template" not found..

After moving back the hook in the .module file everything work again.

Are they some hooks that must be in the .module file only. As the hook_install() and hook_uninstall() must be in the .install file?

3 Answers 3


Just to clarify, you mean the actual hook_theme() implementation, correct? Not a theme hook you are defining in hook_theme(). If so, by default, all hooks must be in the .module file. Hooks are meant to be callable at any time, and only .module files are loaded by default on every page load. However you can tell Drupal that a hook is in a different file by implementing hook_hook_info():

function hook_hook_info()
   $hooks['theme'] = ['group' => 'theme'];

   return $hooks;

With this code, Drupal will look for the hook (the array key 'theme') in the file MODULENAME.GROUPNAME.inc. In this case your GROUPNAME is defined as 'theme' in hook_hook_info(), so Drupal will load MODULENAME.theme.inc, whenever hook_theme() is invoked.

Now, if you meant that you want to put a theme hook that you define inside hook_theme() in another file, then you need to declare the file for that theme hook:

function hook_theme()
  return array
    'some_theme_key' => array
      'variables' => array(),
      'file' => 'path/to/file.inc', // relative to module root

In this case, when the system tries to load the theme some_theme_key, it will load the file [MODULEFOLDER]/path/to/file.inc.

  • Thanks Jaypan, I wasn't aware that all hooks must be in the .module file. I thought that my .inc file mentioned in the .info file would be loaded as well.
    – Tim
    Commented Dec 27, 2016 at 7:18
  • I think those files are only scanned for classes. I'm not entirely clear on that though. It was something that was initially introduced as a requirement for D7, but then that requirement was dropped before D7 was released. The functionality was retained, but it was never clear to me exactly what/how it worked.
    – Jaypan
    Commented Dec 27, 2016 at 8:42
  • Ok, thanks for the addition. Would a require_once at the begining of the .module file be considered wrong?
    – Tim
    Commented Dec 27, 2016 at 16:08
  • Nothing is wrong - if it works it works. But the method I showed will be more lightweight.
    – Jaypan
    Commented Dec 27, 2016 at 23:20

Try using module_load_include() in your custom_module.module to load your .inc file

  • 1
    You should use require_once instead, module_load_include is only for use inside functions when Drupal is bootstrapped
    – Clive
    Commented Dec 26, 2016 at 17:59
  • Totally right Clive . Jaypan answer is the normal way. It must be a cache matter, but Tim, you can try first if it works with module_load_include, if so, switch to Clive answer's for Best practices. Commented Dec 26, 2016 at 18:06

Try adding the reference to your file subfile.inc into info-file of your module.

files[] = subfile.inc
  • 1
    files is for class autoloading, this won't have the desired effect
    – Clive
    Commented Dec 26, 2016 at 18:00

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.