So I have a plugin that appends or prepends an enhanced author biography to the content of a page/post/custom post type.
It does this by hooking to either the_content
or the_excerpt
and appending/prepending content according to the plugin's configuration.
I've started getting support queries where the author biography is appearing in the sidebar of a site via a widget, for example via the Category Posts widget. The widget is using the_excerpt()
within a custom query Loop, to pull posts according to a configured category and show the post excerpt within the context of the sidebar.
As a direct effect of this, my plugin's the_excerpt
filter hook is being called. What I'd like to do is be able to detect whether my filter hook is being invoked within the context of the sidebar or a widget and conditionally decide whether to append my plugin's content to the post content passed to the filter hook. The pseudo-code would look something like this ...
add_filter ('the_excerpt', array ($this, 'insert_biography_box'));
function insert_biography_box ($content) {
if (in_sidebar ()) {
return $content;
}
// do code stuff to append/prepend biography content
return $content;
}
... but after a lot of searching through the WordPress core source, forums and here it doesn't look like a function along the lines of is_sidebar
or is_widget
(or some other variation on the name) exists.
Is it even possible to determine whether a filter hook function is being called within the context of the sidebar or within a widget?
EDIT: Based on @toscho's suggestion to use is_main_query
, I modified my filter hook for the_content
and the_excerpt
to look like this ...
add_filter ('the_excerpt', array ($this, 'insert_biography_box'));
add_filter ('the_content', array ($this, 'insert_biography_box'));
function insert_biography_box ($content) {
error_log ('insert_biography_box: current filter=' . current_filter ());
if (!is_main_query ()) {
error_log ('Not main query, baling');
return $content;
}
// do code stuff to append/prepend biography content
$biography = 'some-magic-function-return-value';
return $content . $biography;
}
Based on this, I was expecting to see the message Not main query, baling
in my PHP error log when the Category Posts widget is calling the_excerpt()
in the context of the sidebar. But I don't.
For context, the Category Posts widget is querying for posts within the widget's widget
method like this (severely paraphrased for clarity) ...
$cat_posts = new WP_Query (...);
while ($cat_posts->have_posts ()) {
$cat_posts->the_post ();
the_excerpt ();
}
... am I missing something (very likely) or am I just not getting the context within which I'm using is_main_query()
(just as very likely) ... ?
the_excerpt
filter hook will be fired by a call toapply_filters
from within the context of thethe_excerpt()
API call and the Codex states thatthe_excerpt()
must be called within The Loop. Ditto for thethe_content
filter hook andthe_content()
API call. There is a caveat that someone may be doing some query cleverness which effectively duplicates the Loop environment but that's not the case here. So sadlyin_the_loop()
will always returntrue
in the main Loop and sidebar Loop(s).apply_filters( 'the_excerpt', get_the_title() );
above the loop would work.apply_filters
). To clarify, I'm looking to detect within the hook function itself what context the hook is running in, where the context is either "you're in the sidebar" or "you're not in the sidebar".