My plugin uses wp_enqueue_style() and wp_enqueue_script() to load resources, but I have kept in mind not to degrade the performance for the user and only load these when the current set of posts contain the shortcode for my plugin. I do this by using:
add_filter('the_posts', 'CrayonWP::the_posts');
the_posts is called before wp_head, but it is also called a few times afterwards (probably for recent posts in the widgets etc).
The problem here is that when I am searching the post contents for my shortcode and signalling the enqueuing process, there are times when:
- the_post is called before wp_head (what I want)
- but that set of posts does not have my shortcode and I don’t enqueue.
- later on, another call to the_posts tries to enqueue but it’s too late.
Is there a definite way to check what will appear on a page before wp_head is called so that I can be confident that I will enqueue only when needed but not miss the opportunity?
EDIT:
But it doesn’t take into account multiple calls to the_posts in a single page request 🙁
EDIT 2:
What I’ve tried is to use:
add_action('wp', 'CrayonWP::queue');
Since the wp
action is only used once right after the request is finalised.
And inside this function:
global $wp_query;
$posts = $wp_query->posts;
I’m not sure how the $wp_query variable changes over the loop however. If the_posts filter is being called again and again, would it imply the original query may be changing as the widgets send across their own requests? Obviously I don’t really want to check for shortcodes in the posts of “recent posts”, since they may not be displaying on the page at the moment. So will using the wp
action hook instead of the_posts
filter contain the posts requested for that given page, whether it were a single or the home page?
I have not tested it, but could is_main_query() (appeared in 3.3) be used here to test that the query being run is the query used to populate ‘the Loop’. (I’m not sure how it handles new
WP_Query
instances, though).The Codex says that it can be used on the
pre_get_posts
, but looking at the code I can’t see why it can’t be called on a later hook (i.e.the_posts
)- all it does is check the global$wp_the_query
against the current query.