[development] Eliminate hooks entirely in Drupal 6
Earl Miles
merlin at logrus.com
Tue Jan 23 22:21:25 UTC 2007
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.
Thoughts?
More information about the development
mailing list