Wordpress - How to add stylesheets only to pages with specific shortcode?
Loading Scripts and Styles Dynamically Using Shortcode
Advantages
- Does not search through all the posts every time 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()
orstrpos()
. You could switch to regex if you need to accept args. - Reduces file calls
Explanation of Code
Finds the shortcodes on page using the
save_post
hook only when the post is not a revision and matches the specifiedpost_type
.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 useupdate_option()
.Uses hook
wp_enqueue_scripts
to call ouradd_scripts_and_styles()
function.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, '', 'yes')) 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');
This works for me:
function register_my_css () {
wp_register_style('my-style', plugins_url('styles.css', __FILE__));
}
function register_my_scripts () {
wp_register_script('my-script', plugins_url('scripts.js', __FILE__));
}
// only enqueue the scripts / styles when the short code is called
function do_my_shortcode () {
wp_enqueue_style('my-style');
wp_enqueue_script('my-script');
// do short code stuff...
}
// register css
add_action('wp_enqueue_scripts', 'register_my_css');
// register javascript
add_action('wp_enqueue_scripts', 'register_my_scripts');
// register shortcode
add_shortcode('my-shortcode', 'do_my_shortcode');
More info here: http://mikejolley.com/2013/12/sensible-script-enqueuing-shortcodes/