问题描述
我正在使用 the_content
过滤器过滤内容。一切都很完美,摘录我的更改也适用于自定义查询。如果小工具使用自定义查询,我的更改也会显示在侧边栏中
为了解决这个问题,我使用 is_main_query()
来定位主查询,但是它不起作用。更改只是依然适用于所有查询。什么是有趣的,但所有其他条件检查,如 is_single()
和 is_category()
是正常工作,如果我定位特定的页面,除了所有更改影响该页面上的任何其他自定义查询,不管我是否使用 is_main_query()
我在这里遗漏了一些东西如何仅使用 the_content
过滤器将更改应用于主查询
add_filter('the_content', 'custom_content');
function custom_content($content){
if(is_main_query()){ // << THIS IS NOT WORKING
// My custom content that I add to the_content()
}
return $content;
}
最佳解决方案
说实话,in_the_loop()
是你正在寻找的功能:
add_filter( 'the_content', 'custom_content' );
function custom_content( $content ) {
if ( in_the_loop() ) {
// My custom content that I add to the_content()
}
return $content;
}
in_the_loop
的作用是检查当前帖子的 $wp_query
(即主查询对象) 的全局是否为-1 < $current_post < $post_count
。
当主查询循环时,因为 before 循环开始,当前的帖子是-1,而循环结束后,当前的帖子将被重新设置为-1 。
所以,如果 in_the_loop()
是真的,这意味着主查询对象是循环的,这就是你在这种情况下需要的 (和 loop_start
上添加操作相同的结果,并且在 loop_end
上删除,就像 @ialocin 写的一样; 事实上它的工作原理相同,得到了我的+1) 。
因为 in_the_loop()
仅适用于主查询,因此 @ ialocin 的方法的优点是当您要定位与主要查询对象不同的查询对象时。
次佳解决方案
这只是 @ Otto 的答案的补充。只是为了使它更好一点可以理解。基本上是什么 @Otto 说,你必须扭转逻辑,这意味着:如果可以可靠地确定主查询,那么你可以添加和删除你的挂钩到 the_content
过滤器。
例如,主查询可以可靠地在 pre_get_posts
操作中被识别,所以这将工作:
function wpse162747_the_content_filter_callback( $content ) {
return $content . 'with something appended';
}
add_action( 'pre_get_posts', 'wpse162747_pre_get_posts_callback' );
function wpse162747_pre_get_posts_callback( $query ) {
if ( $query->is_main_query() ) {
add_filter( 'the_content', 'wpse162747_the_content_filter_callback' );
}
}
由于您在不再需要时删除过滤器,所以我认为 loop_end
操作应该是一个很好的选择,因为它可以使用 loop_start
。这将是这样的:
add_action( 'loop_start', 'wpse162747_loop_start_callback' );
function wpse162747_loop_start_callback( $query ) {
if ( $query->is_main_query() ) {
add_filter( 'the_content', 'wpse162747_the_content_filter_callback' );
}
}
add_action( 'loop_end', 'wpse162747_loop_end_callback' );
function wpse162747_loop_end_callback( $query ) {
if ( $query->is_main_query() ) {
remove_filter( 'the_content', 'wpse162747_the_content_filter_callback' );
}
}
第三种解决方案
您正在使用 is_main_query()
。 global is_main_query() 函数返回 true,除非全局 $ wp_query 变量被重新定义。
从 the_content 筛选器中可以看出,您当前的 Loop 是否是主查询,可能没有 100%可靠的方式。内容过滤器只是过滤内容。它没有任何形式的能力知道它被用于什么循环。
相反,您应该在需要时添加过滤器,然后在不需要时将其删除。
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。