2

I'm working on creating a shortcode which is meant to change the css and js dynamically for that shortcode based on the situation. Now the problem is that I not getting a clue about how to use add_action() inside a add_shortcode(). Let me give you an example snippet code so that you guys can better understand me:

add_shortcode('example', function( $atts ) {
    //extracting the shortcode attributes
    extract( shortcode_atts( array(
        'value1' => null,
        'value2' => null, 
        'value3' => null
    ), $atts ) );

    //Now here I wll do my code for the shortcode
    // But the shortcode needs some js and css to work
    // so, I'm trying like this

    //For the CSS
    add_action('wp_head', function() {
        echo '<style type="text/css">
            .class {
                background-color: '. $value2 .';
            }
        </style>';
    });

    //For the JS
    add_action('wp_footer', function() {
        echo '<script type="text/javascript">
            var a = '. $value3 .'
        </script>';
    });

});

Now obviously it is not working, so I was hoping if any of you can guide me how to the similar thing in the proper way.

If you can, please help instead of negative voting the question.

1

Nope, that won't work. By the time WordPress starts evaluating the shortcode in your content, the head of the site has already been assembled, so you can no longer add an action to it.

Looking at the execution order of hooks gives you a clue how to do this.

First, you must avoid echoing scripts. Rather, wp_enqueue_script (which is the same as wp_enqueue_style) is the method to use if you want to avoid conflicts between scripts. Since the scripts go in the head, you want your action to be declared before wp_head is called. Given that you need to extract information from a post, you must hook in after WP knows which post is on this page. That hook is wp. Here you must pre-evaluate the post content to extract the relevant shortcode using regex. Roughly your function will look like:

add_action ('wp', 'add_shortcode_script');

function add_shortcode_script () {
  global $post;
  ... use regex to scan $post->$post_content for your shortcode
  ... and extract $value2 and $value3
  wp_enqueue_script (...vars based on $value2...);
  wp_enqueue_style (...vars based on $value3...);
}

Above is what you need if the shortcode indicates the addition of a css/js file. In your example you only add a snippet, which supposedly alters the behaviour of a main css/js file. This means you should use wp_add_inline_script and wp_add_inline_style. The latter part of the code then becomes:

  wp_enqueue_script ('my_script','http:/.../main.js');
  wp_enqueue_style ('my_style','http:/.../main.css');
  wp_add_inline_script ('my_script', $string_based_on_value2);
  wp_add_inline_style ('my_style', $string_based_on_value3);
  • Hi @cjbj Thanks a lot of your reply. I've created a short example here: pastebin.com/k9yH28QT based on your reply. But I'm not sure how can I fetch the shortcode variable values inside wp action. Can you please take a look? Thanks a lot for your help. Also there is no main style or js file for this shortcode, both the style and js needed for this shortcode to work will be added inline. – iSaumya Aug 14 '16 at 10:44
  • This question on Stackoverflow shows how to extract the shortcode values: stackoverflow.com/questions/18196159/… – cjbj Aug 14 '16 at 11:00
  • Besides that you don't need to include <script> tags in the string and you can only use wp_add_inline_script AFTER you have enqueued the main script that your snippet relates to. – cjbj Aug 14 '16 at 11:01
  • what if there is no main script the shortcode relates to? Because the value of the js will always gets changed. so should I create a blank js file and then add stuffs via inline? Actually the think I'm trying to do is a bit complicated I wish I could show it to you somehow – iSaumya Aug 14 '16 at 11:09
  • Take a look at this fiddle: jsfiddle.net/jk5Lwp3x This is exactly what I am trying to incorporate in wordpress via a shortcode. Now the problem is if you look at the javascript, you will see that the number of slides, file size, the image links, download buttons etc all gets managed by the javascript. So, even if I take those things via shortcode parameter, I still need to incorporate them inside javascript. – iSaumya Aug 14 '16 at 11:14
1

If you think about it, wp_head is already fired at the time your shortcode gets parsed (the post content comes much later than the <head> of the page). So that won't work.

(See this question for the WordPress loading process)

You could either directly print the JS & CSS there (not allowed per the HTML spec, but the browser understands it just fine) or move everything to the footer.

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.