WordPress 主题模板的核心是令人敬佩的 WordPress 循环。例如,当您查看 index.php 文件时,循环是通常以 if (have_posts()) 开头并包含用于生成页面的所有标记和网页标签的那个部分。默认循环适用于大多数只需要单个循环的主题,但对于具有多个或自定义循环等内容的更高级的主题设计,需要更强大的循环功能。幸运的是,WordPress 为循环提供了足够的灵活性,有四种或五种循环的方式:
- 默认循环
- query_posts() 循环
- WP_Query() 循环
- get_posts() 循环
- pre_get_posts 自定义循环
这些循环方法中的每一种在各种情况下都是有用的。它们共享许多相同的底层功能,并且各自的查询参数也基本相同。总的来说,这四种技术可以在 WordPress 主题模板中实现简单循环,多循环和自定义循环。
例如,找到默认循环的好地方是在主题的 index.php 文件中。其目的是遍历存储在数据库中的文章并将其内容输出到浏览器。使用 WordPress 的模板标签,可以轻松显示文章的标题,内容,元数据信息等等。接下来,让我们来看看使用 WordPress 循环的四种方法。
默认循环
默认的 WordPress 循环看起来像这样:
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<div <?php post_class(); ?> id="post-<?php the_ID(); ?>">
<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
<?php the_content(); ?>
</div>
<?php endwhile; ?>
<div class="navigation">
<div class="next-posts"><?php next_posts_link(); ?></div>
<div class="prev-posts"><?php previous_posts_link(); ?></div>
</div>
<?php else : ?>
<div <?php post_class(); ?> id="post-<?php the_ID(); ?>">
<h1>Not Found</h1>
</div>
<?php endif; ?>
那么是什么让它被称为 “默认循环”?主要是因为它使用默认查询来循环遍历文章,使其成为大多数主题 99% 的时候都在使用的循环。它告诉 WordPress 根据一定的条件查询和遍历文章,并由各种模板标签(the_title,the_content 等)进行调用。这些标签几乎可以调用一切存在数据库中的信息。
根据发送的查询条件,默认循环将显示从特定日期以来某个类别的特定数量的文章,并依此类推。例如,每次显示的文章数量在系统设置中进行指定,因此,如果有人请求 “Awesome” 类别的第二页,则通过查询发送此条件 信息,并附加上文章数量等条件。
因此,如果您对发送的查询条件感到满意,则默认循环是完美的,当然您也可以自定义查询并生成不同的文章集结果。
query_posts() 循环
query_posts 函数使我们能够修改查询参数并显示我们想要的结果。我们可以覆盖整个查询或保留它,但是修改一些参数。下面是一个示例,在默认循环之前调用 query_posts 以排除特定分类的文章:
<?php global $query_string; // required
$posts = query_posts($query_string.'&cat=-9'); // exclude category 9 ?>
<?php // DEFAULT LOOP GOES HERE ?>
<?php wp_reset_query(); // reset the query ?>
假设您主题模板中的 index.php 有一个默认循环,但您想要更改文章数,排除两个类别,并按升序显示结果。很简单,只需在默认循环之前添加一些 query_posts 的操作,然后立即添加 wp_reset_query,如下所示:
<?php global $query_string; // required
$posts = query_posts($query_string.'&posts_per_page=3&cat=-6,-9&order=ASC'); ?>
<?php // DEFAULT LOOP GOES HERE ?>
<?php wp_reset_query(); // reset the query ?>
在这里,我们保持原始查询而仅仅覆盖一些参数。除此以外,还有许多参数可用,因此可以非常轻松地自定义任何默认循环。如果我们想要完全覆盖原始查询,我们可以使用以下内容替换第二行:
$posts = query_posts('posts_per_page=3&cat=-6,-9&order=ASC');
请注意,我们从 query_posts 的参数中删除了 $ query_string。这就移除了默认查询,并将其替换为仅包含 query_posts 中包含的那些变量的查询。这也意味着没有可用的分页信息,所以只有在您知道自己在做什么时才删除原始查询。
如何使用
可以使用 query_posts 修改单个循环返回的文章类型。它非常适用于限制文章数量,排除特定类别的文章,等等。如果需要多个循环,多个 query_posts 循环也可以工作,但有一个更好的方法,比如使用 WP_Query。实际上,现在大多数情况下已经不推荐使用 query_posts () 。
WP_Query() 循环
对于需要完全控制任意数量的定制循环时,WP_Query 非常适用。当其用于修改默认循环时,它看起来类似于 query_posts。例如,让我们使用 WP_Query 排除特定类别:
<?php $custom_query = new WP_Query('cat=-9'); // exclude category 9
while($custom_query->have_posts()) : $custom_query->the_post(); ?>
<div <?php post_class(); ?> id="post-<?php the_ID(); ?>">
<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
<?php the_content(); ?>
</div>
<?php endwhile; ?>
<?php wp_reset_postdata(); // reset the query ?>
它还接受与 query_posts 相同的参数,因此修改文章数量,包含 / 排除类别和显示顺序等看代码起来也都非常熟悉。如以下示例所示,通过简单地更改参数,WP_Query 可以轻松自定义循环:
$custom_query = new WP_Query('cat=-7,-8,-9'); // exclude any categories
$custom_query = new WP_Query('posts_per_page=3'); // limit number of posts
$custom_query = new WP_Query('order=ASC'); // reverse the post order
正如所料,我们也可以像 query_posts 和 get_posts 一样,使用相同的语法将参数组合起来,用到 WP_Query 中。以下为示例:
$custom_query = new WP_Query('posts_per_page=3&cat=-6,-9&order=ASC');
但请注意,使用 WP_Query 时,我们不需要 $query_string 变量。除了可以使用 WP_Query 自定义默认循环外,我们还可以使用它来创建和自定义多个循环。这是一个基本的例子:
<?php // Loop 1
$first_query = new WP_Query('cat=-1'); // exclude category
while($first_query->have_posts()) : $first_query->the_post();
...
endwhile;
wp_reset_postdata();
// Loop 2
$second_query = new WP_Query('cat=-2'); // exclude category
while($second_query->have_posts()) : $second_query->the_post();
...
endwhile;
wp_reset_postdata();
// Loop 3
$third_query = new WP_Query('cat=-3'); // exclude category
while($third_query->have_posts()) : $third_query->the_post();
...
endwhile;
wp_reset_postdata();
?>
这些附加的循环中的每一个都可以放置在主题模板中的任何位置 – 无需按顺序排列它们。例如,一个循环可以放在侧边栏中,另一个循环放在页脚中,依此类推。并且可以通过修改参数轻松定义每个循环的输出,任何循环的配置都是可能的。
如何使用
可以使用 WP_Query 创建多个自定义循环。通过在主题中添加 WP_Query 的其他实例,您可以创建任意数量的多个循环,并自定义每个循环的输出。
即便如此,我们并不总是需要使用这个相对复杂的功能,有时我们只需要在页面周围显示一些额外的循环。所以,让我们放下它,来看看 get_posts 的使用。
get_posts() 循环
在主题中创建多个循环最简单,最安全的方法是使用 get_posts()。在任何需要静态快速显示文章的地方,get_posts 都是最佳选择。例如在侧边栏中添加 10 个最近文章,或者页脚中添加 10 个随机文章,get_posts 都让它变得尤其简单。以下依然是一个排除特定类别的查询:
<?php global $post; // required
$args = array('category' => -9); // exclude category 9
$custom_posts = get_posts($args);
foreach($custom_posts as $post) : setup_postdata($post);
...
endforeach;
?>
此代码创建显示排除特定类别以外的所有文章的循环。当然,排除特定类别只是定制额外循环的一种方法。通过使用 WP_Query 和 query_posts 接受的任何参数,可以创建循环显示几乎任何内容。
但请注意,get_posts 需要使用数组作为参数。多个参数的格式如下所示(还是使用前面的示例):
$args = array('numberposts'=>3, 'category'=>-6,-9, 'order'=>'ASC');
另请注意,我们使用 numberposts 而不是 posts_per_page 来限制文章数量。根据 WP Codex 文档,posts_per_page 应该与 get_posts 一起使用,但如果没有,则应该与 numberposts 一起使用。此外还有一个 showposts 参数,也适用于 get_posts。
如何使用
使用 get_posts() 函数可以在主题中的任何位置轻松创建额外的静态循环。get_posts 接受与 query_posts 相同的参数,非常适合在侧边栏,页脚或其他任何位置添加静态自定义循环。
pre_get_posts 自定义循环
最后但同样重要的是 pre_get_posts 这个过滤器钩子。此钩子使开发人员能够自定义 $query 对象并自定义默认的 WordPress 循环。以下是它如何工作的简单示例:
function digwp_pre_get_posts($query) {
if (!is_admin() && $query->is_main_query()) {
$query->set('posts_per_page', 1);
}
}
add_action('pre_get_posts', 'digwp_pre_get_posts');
这里我们通过一个函数附加到 pre_get_posts 的钩子上。在函数的第一行,我们使用条件标记函数和方法来检查请求是否是在前台页面以及是否是主循环(通过is_main_query())。如果满足该条件,我们将 posts_per_page 的数量设置为1。但这只是一个最基本的例子。通过 $ query 对象可以使用许多方法和属性,从而实现更高级的自定义循环。
如何使用
当您想要自定义 WordPress 主循环时,pre_get_posts 过滤器钩子很有用。查看 WP_Query 提供的方法和属性,以便更好地了解所有的可能。
最后的小结
自定义默认循环和创建多个循环的准则:
- 修改默认循环,请使用 query_posts()
- 修改循环和/或创建多个循环,请使用 WP_Query()
- 创建额外的静态循环,请使用 get_posts()
- 自定义默认循环,请使用 pre_get_posts
关于 WordPress 的循环介绍就到这里,欢迎大家留言讨论。
原文出自:https://digwp.com/2011/05/loops/
由 Ethan 全文翻译。