0

I am trying to add a style to the header, using this method the style only loads on single posts but if I use a shortcode to load the post content that style does not load in the header:

add_action( 'wp_head', 'output_styles')
function output_styles($base_ID){
   $global post;
     echo '<style type="text/css">'. get_post_meta($post->ID, 'append_css') .'</style>';
}

in my shortcode I am passing the ID of the post, if I call the ouput_styles functions from shortcode function :

output_styles($pass_id);

then the content of output_style is printed but it is not in the header. It is right before the shortcode output.

How can I output the style in the header when using shortcodes?

1
  • Where are you putting the add_action code? If it's not in the functions.php inside the active theme you should transfer it there. Apr 3, 2017 at 21:53

2 Answers 2

1

In this case, has_shortcode() is your friend.

First, we hook into wp_print_styles, instead of wp_head. In the func we hook we check if the post contains our shortcode. If it does, we get the CSS we want and output it as an inlined <style>.

add_action ('wp_print_styles', 'wpse_enqueue_shortcode_css') ;

function
wpse_enqueue_shortcode_css ()
{
    global $post ;

    if (is_single () && has_shortcode ($post->post_content, 'my_shortcode')) {
        $append_css = get_post_meta ($post->ID, 'append_css', true) ;

        echo <<<EOF
        <style type='text/css'>
            $append_css
        </style>
EOF;
        }

    return ;
}
4
  • but get_post_meta ($post->ID, 'append_css', true) gets the meta for current post and not the one set using shortcode so wrong style will be loaded
    – Alen
    Apr 3, 2017 at 21:56
  • in this case, the current post is the post using the shortcode. Apr 3, 2017 at 21:58
  • @Paul'SparrowHawk'Biron Alen wants to add the style if the post indicated in the shortcode's attributes contains the meta-data - not if the post containing the shortcode has the meta-data. By the time the shortcode retrieves the post which might have the meta-data, the wp_head/wp_print_styles actions will have already fired with global $post referencing the post containing the shortcode.
    – bosco
    Apr 3, 2017 at 22:09
  • Does't work on the home page archive as it uses the same color for every post. @paul-sparrow-hawk-biron Jan 10, 2022 at 7:34
0

@bosco, thanx for the comment...I misunderstood what @Alen was trying to accomplish (the global $post in the code included in the question threw me off).

If my understanding is now correct, the following should do the trick (altho, it's a bit ugly). It works by hooking into wp_print_styles within the function that processes the shortcode.

add_shortcode ('my_shortcode', 'my_shortcode') ;

function
my_shortcode ($atts)
{
    $defaults = array (
        'id' => '',
        // other atts for the shortcode
        ) ;
    $atts = shortcode_atts ($defaults, $atts) ;

    if (!empty ($atts['id'])) {
        global $my_shortcode_css ;

        // grab the CSS from the post whose ID was passed in the 'id' attribute of
        // my_shortcode, e.g., [my_shortcode id='123']
        // and store it in a global
        $my_shortcode_css = get_post_meta ($atts['id'], 'append_css', true) ;

        // no need to hook into wp_print_styles IF we don't have any CSS to output
        if (!empty ($my_shortcode_css)) {
            // hook into wp_print_styles with an anonymous func
            add_action ('wp_print_styles', function () {
                global $my_shortcode_css ;

                if (empty ($my_shortcode_css)) {
                    return ;
                    }

                echo <<<EOF
    <style type='text/css'>
        $my_shortcode_css
    </style>
EOF;

                // clean up, since we no longer need this global
                unset ($my_shortcode_css) ;
                }) ;
            }
        }

    // insert code to produce the output of the shortcode
    $output = ... ;

    return ($output) ;
}

Note: If you can conceive of [my_shortcode] being used more than once within a given post, it would probably be a good idea to add logic to the above to check whether CSS has already been output for a given post ID. I'll leave that as an "exercise for the reader" :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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