Support » Developing with WordPress » Does a theme really need to hook after_setup_theme in functions.php?

  • Resolved OnePressTech

    (@timhibberd)


    I am in an ongoing process of modernising a legacy abandoned premium theme suite. As part of that upgrade process I am looking to ensure the theme suite conforms to the WordPress theme design requirements and design best practice (WordPress+PHPCS, ThemeCheck plug-in, ThemeSniffer plug-in, namespacing, hooking, filtering, etc).

    Please note that this is not a problem report…the theme suite has been upgraded to support WordPress 5.2 and PHP7.3 and operates without problems. The theme suite in question (MysiteMyWay forked as BackStop Themes…see history if interested) has been in use on 100+ sites for over ten years.

    This is more a theme design question than an issue.

    This theme suite has never hooked after_setup_theme. Having said that, most respected themes (WordPress themes, reputable starter themes) tend to perform some functions such as add_theme_support( 'title-tag' ); within a callback function hooked to the after_setup_theme hook. But nowhere is it documented how to choose what to action from within the functions.php and what to action within an after_setup_theme hooked callback function or why.

    It is my understanding that the actions in an after_setup_theme hooked callback function will be executed after the theme’s functions.php completes execution. So in that sense, putting actions at the end of functions.php in an unhooked state would be equivalent to putting them in an after_setup_theme hooked callback function.

    Is there something that happens between the completion of the functions.php code processing and the start of the after_setup_theme hooked callback function processing that is significant?

    NOTE: One designer stated that this approach enabled flexibility for child themes that needed to override the parent theme…but then the child theme could hook after_setup_theme to do so. Why would a parent theme need to hook after_setup_theme?

    Thanks in advance for your words of wisdom. I could have just added in the after_setup_theme hooked callback function and moved on but I had an intellectual itch I needed to scratch…I needed to know why 🙂

Viewing 10 replies - 1 through 10 (of 10 total)
  • It is as that one designer stated, that making the code run on a hook is much more flexible than just leaving functions straight in the functions.php file.
    Not only being able to unhook from after_setup_theme, but allowing WP to change the order of execution (such as adding another action before calling after_setup_theme) without the theme having to change. Plugins and child themes can use the priority parameter to run before or after the theme code (or remove it).

    Thread Starter OnePressTech

    (@timhibberd)

    Hi @joyously…thanks for your help. Much appreciated 🙂

    I appreciate that everyone believes this practice adds value but no one explains why that is the case for a theme. The plugins and child theme load before the theme and can hook after_setup_theme so they can make adjustments before and after the theme loads whether the theme hooks after_setup_theme or not.

    So the loading sequence is:

    plugins / child theme / theme /

    and the theme hook sequence is:

    setup_theme / theme processing / after_setup_theme

    So you can see that in a sequential processing model there is no after_setup_theme hook value for a theme. There is after_setup_theme hook value for plug-ins and child themes who want to override the theme but there is no value I can see for a theme to hook after_setup_theme.

    Can you think of a use-case that requires the theme to hook after_setup_theme?

    Thanks in advance.

    I already stated the value of it.
    Your description of the loading sequence is valid for today. But tomorrow, it could change, and if the theme isn’t using the hook, it would get different results when the sequence changes.
    And if the theme doesn’t use the hook, the child theme and plugins can’t remove the theme code (remove_action), but have to just endure whatever the code does outside the hook.
    Using the hook makes the theme much more flexible, in both those ways.

    Thread Starter OnePressTech

    (@timhibberd)

    Hi @joyously. Thanks for that.

    Can you clarify your last sentence for me please

    And if the theme doesn’t use the hook, the child theme and plugins can’t remove the theme code

    .

    The child theme and the plugins can always hook after_theme_setup and override anything the theme makes overridable whether the theme uses after_setup_theme or not. As I stated previously the theme loading-process is sequential and all a theme really does is load resources, hooks and filters. Anything that can be overridden…can be overridden whether the theme hooks after_setup_theme or not.

    I’ll give you an example…add_theme_support( 'post-thumbnails' );

    If a plug-in or child-theme wants to override the theme and disable post-thumbnails for some reason then they hook after_setup_theme with a function that calls remove_theme_support( 'post-thumbnails' ); It wouldn’t matter whether the theme invoked add_theme_support( ‘post-thumbnails’ ) in functions.php or a function hooked to after_setup_theme;

    Could you please give me a counter-case…something that can’t be done by a plug-in / child-theme if the theme does-not hook after_theme_setup. I’m not being disingenuous…I can’t find any technical reason for a theme to hook after_theme_setup. The purpose of this post is to double-check find a counter-case if my assumption is faulty.

    Thanks again for your thoughts. Much appreciated.

    If the child theme or plugin wanted to undo the parent theme’s code, wouldn’t it be most future-proof and easier to unhook after_setup_theme than to address each thing individually, not knowing when the theme would update and add something new?
    And regardless of the order of execution (which is one of my points of argument you ignore), it’s the WordPress way to use actions and filters, so that the order can be rearranged without needing to change all the code.

    Have you followed every path through WordPress, to see if the after_setup_theme action is always invoked? I’m referring to switching themes, previewing themes in the Customizer, or any other instance in which a theme’s functions file is loaded. I know there’s a case in the admin when an error occurs in the active theme and the default theme is used instead. Trace every path (which is difficult to do because how do you know what plugins do?).

    Thread Starter OnePressTech

    (@timhibberd)

    Hi @joyously. Thanks for your patience I think we are close to a meeting of minds 🙂

    Your point about

    If the child theme or plugin wanted to undo the parent theme’s code, wouldn’t it be most future-proof and easier to unhook after_setup_theme than to address each thing individually, not knowing when the theme would update and add something new?

    is an interesting question. It is unlikely that a plug-in or child theme would unhook the entire theme callback function because, at present, there is no standardisation in what is included in the theme callback function hooked to after_setup_theme by various themes. For example it would be unlikely that a child theme or plugin would bulk discard the following theme callback function hooked to after_setup_theme (there would be very little left of the theme!):

    	private function load_theme_supports() {
    		add_theme_support( 'load_theme_admin_menus' );
    		add_theme_support( 'widgets' );
    		add_theme_support( 'post-thumbnails' );
    		add_theme_support( 'automatic-feed-links' );
    		add_theme_support( 'align-wide' );
    		add_theme_support( 'wp-block-styles' );
    		add_theme_support( 'responsive-embeds' );
    		add_theme_support( 'post-formats' );
    		add_theme_support( 'html5' );
    		add_theme_support( 'custom-logo' );
    		add_theme_support( 'custom-header-uploads' );
    		add_theme_support( 'custom-header' );
    		add_theme_support( 'title-tag' );
    		add_theme_support( 'custom-background' );
    		add_theme_support( 'starter-content' );
    	}

    But I agree with you this would be useful IF the WP core group standardised on what a theme puts in its after_setup_theme callback function.

    The other aspect of your idea is the “bulk discard” as a future-proofing capability…that’s a can of worms though since each hookable callback function operates in a context (core or theme) so there is a limit to what is reasonably hookable before it becomes impossible for an extended theme to become unsupportable in the field due to the numerous parties and permutations. Having said that, the after_setup_theme hooked callback function is a reasonable place to load specific optional theme feature packages.

    Your point about

    And regardless of the order of execution (which is one of my points of argument you ignore), it’s the WordPress way to use actions and filters, so that the order can be rearranged without needing to change all the code

    is a reasonable one…actions / filters is the WordPress way…but only when needed. I cannot imagine a world where the after_setup_theme does NOT happen immediately after the theme completes its setup. So although the after_setup_theme is of use to plugins and child-themes, it is not necessary for the theme to use it for the plugins and themes to override before or after.

    Summary at this point in our discussion:

    A) It would be useful if there was a core standard for what themes put in an after_setup_theme callback function.

    B) after_setup_theme hooked callback function may be a useful mechanism to modularise optional theme feature packages with the express purpose of being bulk replaced (unhook) or selectively customised (contained functions can be overridden or augmented through hooks an filters).

    Thanks again for your input. It has been most helpful and much appreciated 🙂

    I think you miss part of what I say, but Oh well…

    I do have another thing for you to consider.
    A few years ago I wrote a child theme for a popular parent theme. One of the problems I needed to overcome was the fact that the parent theme registered some header images, which I didn’t want at all. I did want all the other stuff that the theme did in its setup function, however. I’m not sure you are aware, but at the time, the code for header images defined PHP constants, so it was not a matter of just undoing what was done. You can’t redefine a constant. But the first one to execute got to define it. So, while the child theme would execute first, it not having any header images wouldn’t define the constant and so the parent theme would get the define anyway. I needed the child code interleaved with the parent code.

    What I ended up doing was remove_action for the parent after_theme_setup, and in the child setup defining the constant as empty string, then calling the parent function followed by the child’s other setup that needed the parent’s data structures.

    If that code had not been hooked to the action, I could not have solved that problem. As I said, it provides much more flexibility. I can even see it as a way to avoid an error, if the child theme checks for a PHP version or WP version and unhooks the parent setup, which couldn’t happen if it was straight in the functions file.

    By the way, I don’t really agree that your summary points A and B were what I was saying, but I guess if that’s what you got out of it then it’s better than nothing. My theme does hook two separate functions to after_setup_theme, with the comment explaining that one needs a earlier priority and it can more easily be unhooked by the child if it’s separate (it’s where the content width is set). This probably came from my memory of the child theme I mentioned above.

    Thread Starter OnePressTech

    (@timhibberd)

    Thanks again @joyously .

    I appreciate your experience and that you have been patiently trying to get a across some points that for some reason my brain is not recognising. My summary was an attempt to restate in my own words what I thought you were trying to say. Obviously I missed the mark. Sorry for that.

    Let me try again to restate what I think you are trying to get across (and again…feel free to correct me)…

    A modularised alternative to a theme’s functions.php is superior to a monolithic theme’s functions.php in that it allows interleaved customisation. after_setup_themeis a useful standard hook for those theme modules to be attached to.

    Better?

    It is interesting to note though that what I see in most themes is that their after_setup_theme hooked callback functions just include the standard add_theme_support(‘abc’); statements I listed above which can all be overridden whether in a after_setup_theme hooked callback function or in the functions.php.
    That’s part of the reason I opened this post. To get other views like yours on what should be in the functions.php and what should be in one or more after_setup_theme hooked callback functions.

    It sounds like your preferred theme design involves some code in the functions.php, and some in two after_setup_theme hooked callback functions.

    Any wisdom as to what code makes sense to leave in functions.php and what to modularise in the after_setup_theme hooked callback functions?

    Cheers 🙂

    It’s not really about modularity, but flexibility.
    The only thing I put in functions.php is actual functions and calls to add_action. Of course, there are requires for other files, but those are just functions that are separated by whether they are filters or template functions or widgets or for Customizer. In any case, the only code not in a function is add_action and add_filter. This way, WordPress controls when and if everything is called, as it should, and it can rearrange the order and my code doesn’t have to change.

    Thread Starter OnePressTech

    (@timhibberd)

    Thanks @joyously . You’ve helped me to gain a broader perspective of the options. Much appreciated 🙂

Viewing 10 replies - 1 through 10 (of 10 total)
  • The topic ‘Does a theme really need to hook after_setup_theme in functions.php?’ is closed to new replies.