[development] Eliminate hooks entirely in Drupal 6
jazepstein at gmail.com
Wed Jan 24 00:55:54 UTC 2007
I agree that callbacks make more sense than hooks, in general, and
that we should be trying to use callbacks instead of hooks wherever
Non-technical analogy that I just thought of:
If you have 100 people in a room, and you're trying to find all the
people in the room who are from Africa (let's say there's 30 African
people in the room - but you don't know that), then it will take a lot
longer to look at each person's name tag, and see if it says 'Africa'
on it, than to simply have the 30 people come up to you, and tell you
that they're the ones from Africa.
Similarly, it takes Drupal a lot longer to go around and look if 50
modules implement hook_nodeapi, than it would take for the 12 modules
in question to just tell Drupal: "hey btw, I implement the nodeapi
However, if you have 100 people in the room, and 98 of them are
Africans, then it's probably easier to just go through each one.
Otherwise the Africans will get annoyed, and say: "hey, we're almost
all African, so why does each one of us have to tell you where we're
Similarly, I think that the (few) hooks that are implemented by
virtually every module, should remain hooks. It would just be a pain
in the a$$ for module developers, otherwise. This is currently only
hook_help() and hook_menu(), AFAIK. I'm not sure if the new menu
system in Drupal 6 will mean less hook_menu() implementations; but if
it doesn't, then hook_menu() should definitely remain a hook, not a
Also, I agree that the performance gain needs to be worth the pain (of
having to register heaps of callbacks). Benchmark results will be
The whole 'linking include files to registered callbacks' idea seems
to me like a GREAT way to kill two birds with one stone. Good
Hang on... you're thinking of applying it all to theme
functions/templates as well... make that 3 birds. With ketchup. :P
On 1/24/07, Earl Miles <merlin at logrus.com> wrote:
> After some discussion this morning, I am putting up a proposal to eliminate
> hooks entirely (though not the concept of hooks) and replace them with
> officially registered callbacks. I have identified several areas where this
> will improve Drupal (primarily in terms of probable performance gains). There
> are 2 parts to this.
> Part 1: drupal_register_callback
> function drupal_register_callback($callback, $function = NULL, $file = NULL)
> This function is only called from a particular location; ideally in its own
> separate .register file that only needs to be loaded when the callback registry
> is being rebuilt. However, it could also be a function within the .module file.
> There are some questions here, primarily balancing ease of use for the
> developer versus performance for the system. When it is called, the system
> should already know which module context is being used.
> This function would register a given callback (examples: nodeapi, form_alter,
> etc) with the Drupal system. The registry would replace the logic
> module_implements uses to determine which module implements which hook.
> The $function would be what's called. In today's world the function would be
> called mymodule_nodeapi; and it would likely not change, but we should allow
> registration to specify the function used. If left blank, the default function
> name would be constructed. (i.e, modulename_hookname).
> The $file would be a file that should live in the same directory as the .module
> file and tells the system which file to conditionally load when that callback
> is invoked. This is one of the things that creates a big advantage in this
> system: We could move callbacks into conditionally loaded files, allowing
> Drupal's minimum per-page codesize to be smaller. The 'nodeapi' hook is not run
> for every page load, but because hooks are anonymous right now, that code
> *must* be present. When you can conditionally load, however, the required size
> of the .module becomes very small. (in fact you would only keep items in that
> file that are called on every or nearly every page load. Currently that's
> hook_init and hook_menu but with changes to hook_menu that one may well be
> eliminated from every-page-load calls, and the .module file itself may not even
> need to be loaded for every page).
> Invoking a callback would still be the same:
> module_invoke('callback', arguments...);
> Part 2:
> function drupal_register_theme($theme, $args, $function = NULL, $file = NULL)
> This works very similarly to callbacks, but it registers a theming function
> that can be overridden by the theme. The only difference in is the $args
> argument, which is an array that tells the function how to translate function
> arguments into the $vars array, for use in .tpl.php files.
> For example, let's say I have the following theme function:
> function theme_foo($node, $bar, $baz);
> The $args array would be: array('node', 'bar', 'baz').
> Themes would also have a similar registry; we may need to make it slightly more
> complex so that it could work with the theme engine to automatically register a
> template. Which means we might want to find a way to make it simpler for
> themers to register the templates they're using (for example, a directory scan
> could find well-named template files and automatically register them based upon
> already known registered info).
> This entire system (callbacks and functions) would be cached, so information
> would only need to be re-read when modules and theme settings are updated. A
> 'development' mode might be necessary that re-reads this information every page
> load. There would probably be some way for devel.module to expose this setting
> and automatically disable development mode when devel.module is enabled.
> Overall benefits to this system:
> 1) Some execution time is saved looking up module hooks. I don't believe this
> is a great deal of execution time, but it is definitely some.
> 2) A great deal of code can be loaded conditionally, reducing Drupal's
> footprint. I believe this could be a *very* significant boost to Drupal and
> could vastly reduce the amount of code that is loaded, making Drupal far, far
> friendlier to hosts that cannot use an opcode cache.
> 3) Certain namespace collisions will be avoided. Developers will no longer be
> penalized for forgetting that mymodule_user() is the user hook.
> 4) Theme functions will no longer have to hunt around for their function; they
> will not have to test the file-system to see if templates exist. They will know
> exactly where to go when the time is right.
> 5) Theme template files will be easier to include in modules. In fact, if
> implemented properly, modules could actually include .tpl.php files, make the
> proper registration, and no theme code will be harmed by being in the .module
> file *at all*.
> 6) phptemplate.engine can have much of its code removed to core, making it
> easier to implement alternative template engines.
> 7) As an interesting side effect, themes could be made to implement
> hook_form_alter, if we coded it that way. There is a value to this, and also an
> argument why this might not be a good thing.
> Overall cons:
> 1) Having to register a callback is less convenient than simply naming a
> function. It's even more inconvenient to have a .register file. However, using
> the existing naming convention, the module_builder.module *could* be made to
> scan a module and produce a .register file or a register function.
> 2) Having to register theme functions is similarly inconvenient but I think
> it's no worse than we have now.
> 3) Having to reregister upon making changes is very inconvenient; a development
> mode would be a must.
More information about the development