I’ve “inherited” the development of an old theme that I’m now bringing up to speed for WP 3.9.
The theme code comes with a functions.php
that has a function theme_name_setup() that hooks into after_theme_setup. So far, so good.
However, it appears that just about everything under the sun has been thrown into the theme_name_setup() function, and all the other theme files for admin pages, templating functions, styling functions, custom headers, widgets, etc — all this is called (via require_once
) from within this theme_name_setup(), and is thus all loaded, willy-nilly, on the after_theme_setup hook.
I’ve looked at other themes (the default 2012, -13, -14 and underscores) which have a much cleaner theme_setup() function, and I know enough to know that hooking absolutely everything — functions within functions — on the same hook is a train wreck waiting to happen (though the theme does seem to operate alright this way for now). I have the examples of the default themes to go by, but what I want to know (and can’t seem to find via almighty Google) is specifically:
Beyond add_theme_support(), textdomain/localization considerations, register_nav_menus(), and thumbnail support, what if anything, should be specifically included into the theme_name_setup() function, hooked as described above? (And, by extension, everything else should be defined/hooked somewhere else.)
Nothing. A theme_name_setup()
function should not even exist.
-
The name is too vague. What does setup mean? This is also the root of your question, because such a name tells us nothing about what the function does. Could be anything or nothing at all. Technically, themes don’t even need a functions.php
. But they work, the setup happens by WordPress.
-
It violates the principle of single responsibility. This term comes from object-oriented programming, but the idea applies to all good code, it is even the core of the UNIX philosophy: Do one thing and do it well.
This leads us to the next problem.
-
It impairs interoperability. Consider the following function:
add_action( 'after_setup_theme', 'theme_name_setup' );
function theme_name_setup() {
require 'widgets.php';
require 'comment-enhancements.php';
require 'javascript.php';
}
What do I have to do to load only widgets.php
and javascript.php
in my child theme? I have to unhook the broad function and repeat parts of your code. And then I pray you will never rename, combine or split files in an update of your parent theme.
To express this in a more positive way:
-
Give each class and function a name that tells the reader what it does. If you cannot come up with a good, precise name, this code does probably too much.
-
You can use the same hook with multiple callbacks. This is the point of the action/filter API. Use it.
-
Try to let each function return an useful value, so you can test and debug it separately. load_theme_textdomain()
for example returns TRUE
when a file was found, FALSE
otherwise. If you are using a separate function to load the translation, you can use that return value.