wordpress: loading javascript only where shortcode appears

Just read this tutorial over here: http://scribu.net/wordpress/optimal-script-loading.html

Seems to be the best way.

add_action('init', 'register_my_script');
add_action('wp_footer', 'print_my_script');

function register_my_script() {
    wp_register_script('my-script', plugins_url('my-script.js', __FILE__), array('jquery'), '1.0', true);
}

function print_my_script() {
    global $add_my_script;

    if ( ! $add_my_script )
        return;

    wp_print_scripts('my-script');
}

In this case, the script will be enqueued only if the $add_my_script global was set at some point during the rendering of the page.

add_shortcode('myshortcode', 'my_shortcode_handler');

function my_shortcode_handler($atts) {
    global $add_my_script;

    $add_my_script = true;

    // actual shortcode handling here
}

So, the script will be added if [myshortcode ...] was found in any of the posts on the current page.


to answer my own question... I had it write the first time. You have to search each page to check that your shortcode is being used. This has to be done when page data is loaded and before page is displayed. To me it is complete overkill on the system, but unfortunately it is the way it is. I got this information from: get_shortcode_regex and old nabble

So first:

add_action('template_redirect','wp_my_shortcode_head');

then:

function wp_my_shortcode_head(){
  global $posts;
  $pattern = get_shortcode_regex(); 
  preg_match('/'.$pattern.'/s', $posts[0]->post_content, $matches); 
  if (is_array($matches) && $matches[2] == 'YOURSHORTCODE') { 
        //shortcode is being used 
  }
}

replace 'YOURSHORTCODE' with the name of your shortcode and add your wp_enqueue_scripts into where it says //shortcode is being used.


I read a solution in here: http://scribu.net/wordpress/conditional-script-loading-revisited.html Basically if using wordpress 3.3 you can enqueue your scripts in your short code function.

function my_shortcode($atts){
    wp_enqueue_script( 'my-script', plugins_url( 'plugin_name/js/script.js' ), array('jquery'), NULL, true);

    // if you add a css it will be added to the footer
//wp_enqueue_style( 'my-css', plugins_url( 'plugin_name/css/style.css' ) );

    //the rest of shortcode functionality
}

Loading Scripts and Styles Dynamically Per Page Using a Shortcode

Advantages

  • Does not search through all the posts everytime the shortcode is called.
  • Able to add styles as well as scripts dynamically only when shortcode is on the page.
  • Does not use regexes since they tend to be slower than strstr() or strpos(). If you need to pickup args then you should use the shortcode regex mentioned above.
  • Reduces file calls

Explanation of Code

  1. Finds the shortcodes on page using the save_post hook only when the post is not a revision and matches the specified post_type.

  2. Saves the found post ids as an array using add_option() with autoload set to yes unless the entry is already present. Then it will use update_option().

  3. Uses hook wp_enqueue_scripts to call our add_scripts_and_styles() function.

  4. That function then calls get_option() to retrieve our array of page ids. If the current $page_id is in the $option_id_array then it adds the scripts and styles.

Please note: I converted the code from OOP Namespaced classes so I may have missed something. Let me know in the comments if I did.

Code Example: Finding Shortcode Occurences

function find_shortcode_occurences($shortcode, $post_type = 'page')
{
    $found_ids = array();
    $args         = array(
        'post_type'   => $post_type,
        'post_status' => 'publish',
        'posts_per_page' => -1,
    );
    $query_result = new WP_Query($args);
    foreach ($query_result->posts as $post) {
        if (false !== strpos($post->post_content, $shortcode)) {
            $found_ids[] = $post->ID;
        }
    }
    return $found_ids;
}

function save_option_shortcode_post_id_array( $post_id ) 
{
    if ( wp_is_post_revision( $post_id ) OR 'page' != get_post_type( $post_id )) {
        return;
    }
    $option_name = 'yourprefix-yourshortcode';
    $id_array = find_shortcode_occurences($option_name);
    $autoload = 'yes';
    if (false == add_option($option_name, $id_array, '', $autoload)) update_option($option_name, $id_array);
}

add_action('save_post', 'save_option_shortcode_id_array' );

Code Example: Shortcode Dynamically Include Scripts and Styles

function yourshortcode_add_scripts_and_styles() {
    $page_id = get_the_ID();
    $option_id_array = get_option('yourprefix-yourshortcode');
    if (in_array($page_id, $option_id_array)) {
        wp_enqueue_script( $handle, $src, $deps, $ver, $footer = true );
        wp_enqueue_style( $handle, $src , $deps);
    }
}

add_action('wp_enqueue_scripts', 'yourshortcode_add_scripts_and_styles');

Tags:

Php

Wordpress