How to add stylesheets only to pages with specific shortcode?

I’m running a function on pages where the shortcode [make-me-a-map] is used. It enqueues javascript to the page and makes a map. That part works fine (woot!) but I’m having trouble with adding the stylesheets to only those pages in a similar fashion.

functions.php (Current)

add_shortcode("make-me-a-map", "create_new_map");
add_action("wp_head", "style_my_new_map");

function create_new_map () {
    global $new_map_called_for;
    $map_called_for = true;

    wp_register_script('make-a-new-map', get_template_directory_uri() . '/js/new-map.js', array('jquery'), '0.1', true);
    wp_enqueue_script('make-a-new-map');
    }

function style_my_new_map() {
    global $new_map_called_for;
    if ($new_map_called_for == true) {
        $tDir = get_template_directory_uri();

        // Echo stylesheets because wp_register_style & wp_enqueue_style don't work atm
        // And add_action('wp_enqueue_script', 'style_my_new_maps') with those functions would add style to all pages
        // Not just the ones with [make-me-a-map] shortcode
        echo "<link rel="stylesheet" href="", $tDir, "/css/new-map.css" />", PHP_EOL;

        // Echo Javascript straight to page (couldn't do it with wp_enqueue_script) to let js code know the template directory
        echo '<script type="text/javascript">var templateDir = "', get_template_directory_uri(), '";</script>', PHP_EOL;
        $map_called_for = false;
    }
}

This doesn’t seem to be working unfortunately. The styles are being added to all pages.

I didn’t use wp_register_style & wp_enqueue_style because this bug is still adding <Link /> tags to the footer from those functions.

I could have used add_action("wp_enqueue_scripts", "style_my_new_map") instead of add_action('wp-head', "style_my_new_map") but as far as I can see and have checked, there’s no difference? Still adds the stylesheets to all pages.

So my question is actually in two parts: 🙂

  1. Why is the current functions.php not working and adding styles to all pages? I’m not sure if it’s the global call or the if statement…
  2. What’s the best way for me to add the stylesheets to the header of only the pages that the above shortcode is used on, assuming I will not know the page ids, etc?

Thanks in advance!
P

8 s
8

2 questions so 2 answers 🙂

Why is the current functions.php not working and adding styles to all
pages? I’m not sure if it’s the global call or the if statement…

It doesn’t work because of the order in which these functions are called. Your shortcode callback is called during rendering post content (most probably the_content function call).

Both wp_enqueue_scripts and wp_head are called much earlier: wp_head somewhere in your themes header.php file and wp_enqueue_scripts during wp_head call.

What’s the best way for me to add the stylesheets to the header of
only the pages that the above shortcode is used on, assuming I will
not know the page ids, etc?

I don’t think there is such “best” way. It’s not a good idea at all. Browsers cache CSS files. So if you have the same CSS on all pages, browser will get it only once. If there are many CSS files for different pages, browser will have to get all of them. So I wouldn’t do it at all, and include these CSS styles in global css file.

Although if you have to include it only on pages that use this shortcode, then (2 solutions, the choice which is better is yours; I think 2nd one is nicer)…

  1. You can add these styles as inline styles. Just be careful to not include them many times. So output them with your shortcode and assure they will be printed only once.
  2. Since posts are already selected, when wp_head/wp_enqueue_scripts is called, you can add some function to this hook, loop through selected posts, check if they’re containing your shortcode and enqueue your CSS if it’s needed. (Of course it won’t be very efficient).

Leave a Comment