Need some help with your project? Contact me

I’m Hooked! 4: Altering module or theme information

The last posts in this series have enjoyed a bit of continuity with regards to their topics. We looked at what hooks are, how they can be declared and played a bit with a custom module that creates its own block. However, we will have to break this continuity now if we want to cover some other cool stuff as well.

This week, we will look at hook_system_info_alter(). Its purpose is to add to or alter information that is passed from a module or theme .info file.

What is it?

First of all, what do we have in these .info files? Apart from the required identification information like the name, description and version, I believe the most important thing is the region declaration. I mean you also have stylesheets, theme settings and all sorts of other stuff but regions are critical to a Drupal site and you cannot declare them elsewhere.

So if your custom module needs to dynamically create some regions, what do you do? You use hook_system_info_alter(). I wrote a post on how to do this so you can go there for more details on this particular part - don’t want to cover the same thing here.

But this hook can help you with other stuff too. You can use it to assign default theme settings that will be constant on any site your module is installed on, using any theme. You can also add or modify default stylesheets or javascript files used by themes or modules. For instance if your module builds on top of another one, you can easily replace its .css file with your own.

How does it work?

The hook takes three parameters: &$info, $file, $type. The first contains the .info file information such as region declarations, stylesheets and stuff like this - that are passed through reference in order to be altered. The $file object contains information about the module or theme and $type checks if it is a 'theme' or a 'module' the .info file belongs to.

So you’d generally use these last two parameters in your php condition to distinguish between themes and modules and to target your code to individual module or theme .info file. This is quite important because you can apply changes in bulk here if you don’t wrap your alterations with well targeted conditions.

An example. Let’s say we are creating a module (demo) that "extends" the Node module (which belongs to core). One of the things demo wants to do is remove one of the stylesheets the Node module passes to Drupal via its .info file.

I happen to know that the Node module comes with a stylesheet called node.css. (You can look in the file itself or in the page source of your site). To disable that file from being passed to Drupal, we need to perform the following operation in our demo module:

function demo_system_info_alter(&$info, $file, $type) {
  if($type == 'module' && $file->name == 'node') {
    unset($info['stylesheets'][all]['node.css']);
  }    
}

Now this code is pretty straightforward. If the type of .info file in question belongs to a module (rather than a theme) AND if the machine name of that module is node, unset the node.css stylesheet. Clear the cache and you will no longer see that file loaded if you check the page source.

It is important to remember that the stylesheet reference to node.css remains in the .info file of the Node module. Nothing gets deleted so if you disable the demo module, the node.css file gets added back into the registry.

OK, but how do we know what is in these hook parameters? To build up a function like we just did, you’ll need to search a bit through them - for instance if you have no idea what is inside the $file object or how the $info array is structured. With the Devel module, you can print them out with the dpm() function. And you can even use the Search Krumo module for a better experience at that. But, I found that the values get printed out only on admin pages, so don’t worry if they don’t appear on your homepage.

So give it a go and let me know if your run into any trouble.

Add new comment

You must have Javascript enabled to use this form.