How can I let templates choose which stylesheets are enqueued?

My theme’s functions.php hooks into wp_enqueue_scripts to register a couple of stylesheets that are used by various site pages. Here’s a simplified version of my configuration:

add_action("wp_enqueue_scripts", function() {       
    // This stylesheet is used on *every* page
    wp_register_style("sitewide", get_template_directory_uri() . "/assets/sitewide.css");
    wp_enqueue_style("sitewide");

    // These stylesheets are used by *some* pages
    wp_register_style("pagetype1", get_template_directory_uri() . "/assets/pagetype1.css", array("sitewide"));
    wp_register_style("pagetype2", get_template_directory_uri() . "/assets/pagetype2.css", array("sitewide"));
});

Every tutorial I’ve found so far enqueues every stylesheet from the callback itself, but I don’t want to do this. I assume that this would cause all my stylesheets to be included on every page, which is not what I want. I only want to enqueue pagetype1.css if the underlying template for a certain page uses it.

Read More

Let’s say that I want my front page to use the page type 1 stylesheet. My intuition would be to call wp_enqueue_style("pagetype1"); in front_page.php right before including the header, which contains the wp_head() call. This doesn’t do anything. The sitewide CSS on the other hand was included like I expected. What am I doing wrong?

I know that there is a workaround out there, but I’d prefer that front-page.php retains control over which additional stylesheets are loaded.


Edit: This is what I ended up with after some discussion with toscho. I added this to functions.php:

// Enqueues a stylesheet handle or an array of stylesheet handles.
function mytheme_enqueueStyle($handles) {
    if (is_array($handles)) {
        add_action("wp_enqueue_scripts", function() use ($handles) {
            foreach ($handles as $handle) {
                wp_enqueue_style($handle);
            }
        });
    } else if (is_string($handles)) {
        add_action("wp_enqueue_scripts", function() use ($handles) {
            wp_enqueue_style($handles);
        });
    } else {
        wp_die("Unsupported parameter type.");
    }
}

Then I called mytheme_enqueueStyle("pagetype1") from front-page.php to enqueue the stylesheet. This way of doing things ended up being incompatible with WP Minify, though.

Related posts

Leave a Reply

1 comment

  1. Check the current template in your callback. This is a post meta field named _wp_page_template.

    add_action("wp_enqueue_scripts", function() 
    {
        // This stylesheet is used on *every* page
        wp_register_style("sitewide", get_template_directory_uri() . "/assets/sitewide.css");
        wp_enqueue_style("sitewide");
    
        if ( ! is_singular() )
            return;
    
        $template = get_post_meta( get_the_ID(), '_wp_page_template', TRUE );
    
        // now enqueue further stylesheets depending on the current template
    });