前言:为何要避免使用插件?
在 WordPress 开发中,我们经常需要实现一些特定功能,例如在首页不显示某个分类的文章。虽然插件可以快速实现,但过度依赖插件会带来以下问题:
- 影响系统性能:插件会增加 PHP 代码执行时间,拖慢网站速度。
- 降低稳定性:插件之间可能存在冲突,或自身存在漏洞,影响网站稳定运行。
- 增加数据库负担:部分插件会频繁查询数据库,加重服务器负载。
因此,对于此类常见的功能需求,通过代码实现是更优的选择。在修改主题文件前,请务必备份原文件,并记录所做的修改,以便在主题升级或出现问题时能够快速恢复。
方法一:在文章循环中直接排除
此方法在文章循环(Loop)内部进行判断,遇到指定分类的文章则跳过。
操作步骤:
- 打开主题的
index.php文件。 - 找到
if (have_posts())或while (have_posts())语句。 - 在循环内部的开头位置(通常在
the_post();调用之后)添加以下代码:
<?php
// 如果当前文章属于分类ID为12的文章,并且在首页,则跳过此文章,继续下一轮循环。
if (in_category(12) && is_home()) {
continue;
}
?>
注意事项:
- 数字
12需要替换为你想要排除的分类ID。 - 此方法逻辑简单,但有一个潜在问题:如果被排除分类的文章数量较多,而其他分类文章不足,可能导致首页显示的文章数量少于你设定的“每页显示文章数”,甚至出现空白。它是在循环中“跳过”,而非在查询时“排除”。
方法二:使用 query_posts 函数(推荐)
此方法通过修改主查询参数,在获取文章列表时就直接排除指定分类,更为高效。
操作步骤:
- 打开主题的
index.php文件。 - 在
if (have_posts())或while (have_posts())语句之前,添加以下代码:
<?php
// 获取当前页码,用于分页
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
// 设置查询参数
$args = array(
// 在此数组中指定要排除的分类ID,多个ID用英文逗号分隔,例如:array(12, 5, 8)
'category__not_in' => array(12),
'paged' => $paged // 保留分页功能
);
// 应用新的查询参数
query_posts($args);
?>
代码说明:
category__not_in:WordPress 查询参数,用于排除一个或多个分类ID。paged:确保分页功能正常工作。- 此方法直接修改了首页的主查询,从源头上排除了指定分类,因此首页显示的文章数量是准确的。
方法三:修改主查询字符串
这是另一种使用 query_posts 的简洁写法,直接修改查询字符串。
操作步骤:
- 打开主题的
index.php文件。 - 找到类似
if (have_posts()) : while (have_posts()) : the_post();的代码行。 - 将其整体替换为以下代码:
<?php if (have_posts()) : query_posts($query_string . '&cat=-12'); while (have_posts()) : the_post(); ?>
代码说明:
$query_string:包含了当前的查询参数。&cat=-12:这是 WordPress 的经典查询语法,cat=-12表示排除分类ID为 12 的文章。多个分类可以写成&cat=-12,-5,-8。- 此方法同样修改了主查询,效果与方法二类似,但语法更紧凑。
重要提醒与最佳实践
1. 获取分类ID:进入 WordPress 后台的“文章”->“分类目录”,将鼠标悬停在目标分类名称上,浏览器状态栏会显示类似 .../tag_ID=12 的链接,其中的数字就是分类ID。
2. 关于 query_posts 的警告:虽然本文介绍了 query_posts,但官方文档并不推荐直接使用它,因为它会完全覆盖主查询对象,可能干扰分页、条件标签等。更现代、更推荐的做法是使用 pre_get_posts 钩子。
3. 最佳实践:使用 pre_get_posts 钩子(推荐):将以下代码添加到主题的 functions.php 文件中,这是最专业且不影响其他查询的方法:
<?php
function exclude_category_from_home($query) {
// 仅修改主站点的前台主查询
if ($query->is_home() && $query->is_main_query()) {
// 排除分类ID为 12 的文章
$query->set('category__not_in', array(12));
}
}
add_action('pre_get_posts', 'exclude_category_from_home');
?>
使用 pre_get_posts 钩子,你无需修改任何模板文件(如 index.php),所有修改通过函数文件完成,更加安全、易于维护,且与分页、插件等兼容性更好。
请根据你的具体需求和 WordPress 知识水平,选择最适合的方法。对于新项目或希望代码更健壮的情况,强烈建议采用“最佳实践”中的 pre_get_posts 方法。