[development] Strip out theme functions into a .theme file

Larry Garfield larry at garfieldtech.com
Thu Aug 3 17:03:09 UTC 2006

On Thu, August 3, 2006 9:27 am, Morbus Iff said:
>> I wrote a little script that uses some regular expressions to remove all
>> theme functions from the .module files and put theme into a .theme file.
>> This .theme file is included at the beginning of all .module files that
>> have a .theme file.
> Wouldn't it make more sense to include the theme only when it's needed?
> That way, we get a slight speedup when we do things that don't 'em (like
> _help, nodeapi calls that only add to node but not modify it, etc.).
> Actually, I'm wondering if we could hook that into theme() - if the
> passed theme isn't in memory, load all theme files to look for it. If
> we demand proper namespaces on the theme's names, we can then only load
> the actual namespace'd file.

I would actually take it a ste further than that.  A few months ago there
was discussion of one-file-per-template, which would make them easier for
themes to override.  In light of that I put together a patch for
manipulating CSS files that does exactly that[1].  Unfortunately another
patch submitted at around the same time [2] just went in instead (I think
it's overly heavy, but Dries apparently disagrees), but I still think the
idea is sound and can work for theme/template files just as well.


- We already have one single namespace for themes, so we needn't worry
about them all being in a single namespace.  Nothing would break that
isn't already broken.
- Most pages views use only a small number of the theme files available in
the system.

So, I'd propose replacing theme_foo() with foo.theme.  Such files would
simply be packaged with their corresponding module, now that we have all
modules in their own directories (yay!).  Upon viewing the admin/modules
page, the system would index not only .module files but .theme files in
the system table.  Then, when theme('foo', $bar, $baz) is called, the
theme system simply looks up the corresponding file and includes it, then
returns the output.  The theme() API remains unchanged.


- Fewer functions to parse that won't actually get used = improved
- Themers can know what theme "functions" they have available to override
simply by looking at the module's directory.  Anything that ends in .theme
is an overridable theme function.
- To override theme "function" foo in a theme, just create foo.theme in
your theme directory.  It automagically replaces the module-provided one,
just as in the CSS patch[1].
- As someone (Adrian?  I don't recall) pointed out to me when the subject
first came up, you can still use PHP-centric code in such files.  If it's
a function that needs to be programmatic (eg, theme_table()), just switch
into PHP mode with <?php on the first line and Bob's your third cousin
twice removed.
- Whether a given theme function is programmatic or template-based can
easily vary depending on the needs of the given function and the
preference of the author.
- Generic theme functions (theme_table(), etc.) can be adopted by
system.module.  The rest of the system won't care.


- I'm not sure what the performance cost would be for including each theme
file, especially those that are included multiple times.  (How many are
there that get included several times?)  The reduced parsing cost could
offset it, or PHP could cache smartly, or something else.  We'd need to
try it and benchmark it.
- I've not worked with template engines other than PHPTemplate, so I'm not
sure how those would be handled.  We'd need to make sure that Smarty,
PHPTal, etc. still worked properly.
- Because this would conceivably do away with the extra layer of callback
function in template.php, there may be needed functionality there that
would need to move elsewhere, either into the .theme file or into the
function that is calling it.


/me dons flame-retardant suit and prepares for his roasting.

[1] http://drupal.org/node/73949
[2] http://drupal.org/node/73961

--Larry Garfield

More information about the development mailing list