求助:实现返回指定数量含内容/摘要的文章,自定义SQL过滤失效
解决WordPress筛选含内容/摘要文章的最优方案
嘿,我来帮你搞定这个WordPress查询的问题!你之前遇到的问题主要有两个原因:一是条件运算符用错了,二是直接拼接$where的方式容易和原有查询逻辑冲突。咱们一步步来解决:
问题分析
- 运算符错误:你用了
AND,这要求文章必须同时有内容和摘要才会被筛选出来,但你实际需要的是有内容或者有摘要其中一个就行,所以应该用OR。 - 查询逻辑冲突:直接硬拼接
$where很容易打乱WordPress原有查询的结构(比如自定义文章类型的过滤条件),导致原本应该被排除的页面(Pages)又被包含进来了。 - 遗漏空字符串检查:WordPress里有时候会把空的内容/摘要存为
''(空字符串)而不是NULL,只检查IS NOT NULL会漏掉这些情况。
最优解决方案:使用posts_where钩子(推荐)
这个方法能安全地在原有查询基础上追加过滤条件,不会破坏自定义文章类型、分页等原有逻辑,而且直接在SQL层面过滤,效率比查完再筛选高得多。
场景1:修改全局主查询
如果你想让网站的主文章列表都应用这个过滤,可以添加以下代码到主题的functions.php里:
add_filter('posts_where', 'filter_posts_by_content_or_excerpt', 10, 2); function filter_posts_by_content_or_excerpt($where, $query) { // 只在前台主查询生效,避免影响后台或其他查询 if (!is_admin() && $query->is_main_query()) { global $wpdb; // 追加条件:内容不为空 或者 摘要不为空 $where .= " AND ({$wpdb->posts}.post_content != '' OR {$wpdb->posts}.post_excerpt != '')"; } return $where; }
如果只需要对特定自定义文章类型生效,可以在判断里加个条件:
// 比如只对名为"news"的自定义文章类型生效 if (!is_admin() && $query->is_main_query() && $query->get('post_type') === 'news') {
场景2:自定义查询(比如循环里的WP_Query)
如果是你自己写的自定义查询,不想影响全局,可以临时添加钩子,用完就移除:
// 临时注册过滤钩子 add_filter('posts_where', 'temp_filter_content_or_excerpt'); // 你的自定义查询参数 $args = array( 'post_type' => 'your_custom_type', // 指定你的自定义文章类型 'posts_per_page' => 10, // 你需要的数量 // 其他参数... ); $custom_query = new WP_Query($args); // 查询完成后移除钩子,避免影响其他查询 remove_filter('posts_where', 'temp_filter_content_or_excerpt'); // 钩子函数 function temp_filter_content_or_excerpt($where) { global $wpdb; $where .= " AND ({$wpdb->posts}.post_content != '' OR {$wpdb->posts}.post_excerpt != '')"; return $where; }
为什么这个方案更好?
- 效率更高:直接在SQL层面过滤,不需要查询多余的文章再逐个检查,节省数据库资源。
- 不破坏原有逻辑:钩子是在WordPress生成的原有查询条件基础上追加,不会覆盖自定义文章类型、分类、分页等设置。
- 更严谨:同时检查了空字符串和NULL,避免漏掉内容为空但字段不是NULL的情况。
内容的提问来源于stack exchange,提问作者Jake
相关产品推荐
相关产品推荐

