4

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.)

  • The original author may have perfectly valid reasons for all of the functionality called at the after_theme_setup hook. Considering that this is the first hook available to themes, it's common to initialize and register literally everything that the theme needs on this action. If the theme in question functions as intended as it is and you yourself don't see anything peculiar, why fix what isn't broke? Without actually seeing the content of that function, it's hard to get much more specific... – bosco Jul 9 '14 at 15:47
  • 2
    Some things frequently done at after_theme_setup: shortcode registrations, script and style registrations/enqueing, post type registrations, taxonomy registrations, theme support configuration, navigation menu registrations, theme environment configuration, adding theme-relevant actions, theme option initialization, admin dashboard modifications, localization domain setup, etc. etc.. In my mind, after_theme_setup is basically the primary entry point for theme functionality. – bosco Jul 9 '14 at 15:56
  • On a final note, off the top of my head I can think of no reasons why "hooking absolutely everything [...] on the same hook is a train wreck waiting to happen," could you elaborate on this? If you're bothered by it all being in once place, you could break it up into multiple functions hooked to the after_theme_setup action, but doing so is a purely cosmetic change. – bosco Jul 9 '14 at 16:06
  • @boscho Thanks for your feedback. Perhaps it's not so much of a train wreck as it appears to be. But having everything crammed into a single theme_setup() function sure makes it look like a train wreck, and is devilishly hard to follow, so I guess cosmetic counts for something. In addition, it seems like some things might be better hooked in other places (registering sidebars on widgits_init comes to mind, for example) but perhaps this, too - but perhaps this is also just a matter of preference. – Caspar Jul 9 '14 at 16:12
  • It certainly does - code organization is choice ;) . In my experience, some theme authors like to create a single hooked function and use it as an authority for that event, acting to invoke all of the functionality that needs to execute at that time rather than providing any functionality itself. In a more WordPress traditional manner, others like to ignore the authoritative hooked function and create individual hooks for each function that would otherwise be invoked... The latter provides more flexibility as other code - a plugin for instance - has finer control over what functions execute. – bosco Jul 9 '14 at 16:18
5

Nothing. A theme_name_setup() function should not even exist.

  1. 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.

  2. 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.

  3. 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.

  • Yes! Yes! Yes! My inherited theme's theme_name_setup() starts off almost identically with what you have in your code anti-sample in point 3 -- and then goes on and on from there! Separating all the bits out into separate functions was the way I was leaning on this (as may have been implied in the question), but having the example of the bundled themes using the theme_setup() function was giving me pause. "If THEY do it, there must be some good reason." – Caspar Jul 16 '14 at 10:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.