我是WP_Query
类的WP_Query
:我在许多客户端站点中都使用它来以自定义方式查询和输出内容。
如果要在页面上运行多个循环,最简单的方法是每次需要运行循环时都运行WP_Query
。 但是有一个缺点:每次WordPress运行查询时,它都会向数据库发送请求,这需要时间,并且可能会使您的网站变慢。 而且,如果您使用WP_Query
而不是主查询来输出内容,那么它将使主查询变得多余,这是浪费资源。
因此,在这里我将向您展示如何使用一个查询来运行多个循环。 您可以对主查询执行此操作(这是我将做的,因为它效率更高),也可以对WP_Query
使用相同的技术。
这包括三个部分:
- 创建一个子主题和一个模板文件。
- 为循环内容创建一个模板部分。
- 创建我们的循环。
因此,让我们开始吧!
您需要什么
要继续进行,您需要:
- WordPress的开发安装。
- 代码编辑器。
- 您网站中分配了多个类别的帖子-我正在使用WordPress主题单元测试数据 。
- 在您的网站上安装了二十六个主题。
- 已安装并激活了一个二十一岁的儿童主题-我将在此处简要介绍如何设置该儿童主题。
您不必使用带有子主题的26个主题,您可以针对自己的主题修改此技术。 但是我要用一个二十一岁的孩子。
创建儿童主题
首先,让我们创建二十十六岁的孩子主题。 我这样做是因为我不想编辑二十十六个主题本身。
在wp-content/themes
目录中,创建一个新的空文件夹。 我正在打电话给我tutsplus-one-query-two-loops
。
在该文件夹中,创建一个名为style.css
的文件并将其添加到其中:
/*
Theme Name: Tutsplus One Query Multiple Loops
Theme URI: http://.tutsplus.com/tutorials/how-to-code-multiple-loops-while-only-querying-the-database-once--cms-25703
Description: Theme to support Tutorial on running multiple loops while querying the database just once. Child theme for the Twenty Sixteen theme.
Author: Rachel McCollin
Author URI: http://rachelmccollin.co.uk/
Template: twentysixteen
Version: 1.0
*/
@import url("../twentysixteen/style.css");
现在保存该文件并激活您的新主题。
下一步是为类别创建一个模板文件,这就是我们将要使用的模板文件。
在您的新主题中,从26开始制作archive.php
文件的副本。 不要移动它,但要复制它。 将其重命名为category.php
。 现在,这是您网站上类别的模板文件。
创建一个新的模板零件文件
第一步是在我们的主题中设置一个新的模板零件文件,其中将包含二十六个循环的编辑版本。
在主题文件夹中,创建一个名为includes
的子文件夹。 在其中创建一个名为loop-category.php
的新文件。
现在,从第二十六个文件中打开template-parts/content.php
文件,并找到以下代码(这是文件的大部分):
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<header class="entry-header">
<?php if ( is_sticky() && is_home() && ! is_paged() ) : ?>
<span class="sticky-post"><?php _e( 'Featured', 'twentysixteen' ); ?></span>
<?php endif; ?>
<?php the_title( sprintf( '<h2 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>' ); ?>
</header><!-- .entry-header -->
<?php twentysixteen_excerpt(); ?>
<?php twentysixteen_post_thumbnail(); ?>
<div class="entry-content">
<?php
/* translators: %s: Name of current post */
the_content( sprintf(
__( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'twentysixteen' ),
get_the_title()
) );
wp_link_pages( array(
'before' => '<div class="page-links"><span class="page-links-title">' . __( 'Pages:', 'twentysixteen' ) . '</span>',
'after' => '</div>',
'link_before' => '<span>',
'link_after' => '</span>',
'pagelink' => '<span class="screen-reader-text">' . __( 'Page', 'twentysixteen' ) . ' </span>%',
'separator' => '<span class="screen-reader-text">, </span>',
) );
?>
</div><!-- .entry-content -->
<footer class="entry-footer">
<?php twentysixteen_entry_meta(); ?>
<?php
edit_post_link(
sprintf(
/* translators: %s: Name of current post */
__( 'Edit<span class="screen-reader-text"> "%s"</span>', 'twentysixteen' ),
get_the_title()
),
'<span class="edit-link">',
'</span>'
);
?>
</footer><!-- .entry-footer -->
</article><!-- #post-## -->
将其复制到您的新文件。
编辑模板零件
从此十六个循环开始,显示的内容超出了我对该档案的需要,因此我将对其进行编辑。 我只想显示摘录而不是内容,因此我们将其删除。
在新的loop-category.php
文件中,找到以下代码并将其删除:
<div class="entry-content">
<?php
/* translators: %s: Name of current post */
the_content( sprintf(
__( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'twentysixteen' ),
get_the_title()
) );
wp_link_pages( array(
'before' => '<div class="page-links"><span class="page-links-title">' . __( 'Pages:', 'twentysixteen' ) . '</span>',
'after' => '</div>',
'link_before' => '<span>',
'link_after' => '</span>',
'pagelink' => '<span class="screen-reader-text">' . __( 'Page', 'twentysixteen' ) . ' </span>%',
'separator' => '<span class="screen-reader-text">, </span>',
) );
?>
</div><!-- .entry-content -->
另一步是更换twenty_sixteen_excerpt()
与标准功能the_excerpt()
函数,作为二十16版本不包括一个链接到完整的文章。
找到这一行:
<?php twenty_sixteen_excerpt(); ?>
替换为:
<?php the_excerpt(); ?>
我们还需要对标题标签进行一些调整。
在模板部分中,编辑以下行:
<?php the_title( sprintf( '<h2 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>' ); ?>
将h2
标签更改为h3
:
<?php the_title( sprintf( '<h3 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h3>' ); ?>
保存您的模板零件文件。 现在回到您的category.php
文件并继续进行操作。
创建循环
首先,让我们从category.php文件中删除对二十六个模板部分的调用,因为我们需要使用新文件。
在您的category.php
文件中找到以下代码:
get_template_part( 'template-parts/content', get_post_format() );
删除它。
现在,我们将创建循环。
在此示例中,我将首先使用has_tag()
条件标签列出所有带有“ content”标签的has_tag()
。
这意味着我将必须运行三个循环:
- 第一个检查查询是否返回了带有此标记的任何帖子。
- 如果是这样,第二个输出将带有此标签。
- 第三个输出没有此标签的帖子。
在这rewind_posts()
之间,我将使用rewind_posts()
在不重置查询的情况下倒退帖子:我们仍然每次都在处理主查询。
第一个循环:检查帖子
在您的category.php
文件中,找到循环的开始:
while ( have_posts() ) : the_post();
在该行上方,定义一个新变量$count
:
$count = 0;
现在在该循环中,添加以下代码:
// check if there are any posts with the '' tag
$tag = 'content';
if ( has_tag( $tag ) ) {
$count +=1;
}
这将检查帖子是否具有“内容”标签,然后将计数加1
。
您的循环现在将如下所示:
// Check for posts in the first loop.
$count = 0;
while ( have_posts() ) : the_post();
// check if there are any posts with the '' tag
$tag = 'content';
if ( has_tag( $tag ) ) {
$count +=1;
}
endwhile;
第二个循环:输出带有标签的帖子
下一步是运行一个循环以输出带有该标签的帖子,但前提是有任何标签,即$count
的值大于0
。
将其添加到您的第一个循环下面:
if ( $count > 0 ) {
rewind_posts();
echo '<h2>Posts tagged with ' . $tag . '</h2>';
while ( have_posts() ) : the_post();
if ( has_tag( $tag ) ) {
get_template_part( 'includes/loop', 'category');
}
// End the loop.
endwhile;
}
这将检查$count
大于零,如果大于零,则倒回帖子并再次运行循环。 对于每个帖子,它都会检查该帖子是否具有我们的标签,如果是,它将调用我们刚刚创建的模板部分。
第三循环:输出其余帖子
最后的循环将输出其余帖子。 如果此类别没有任何带有'content'标签的帖子,则它将输出该类别中的所有帖子。
在第二个循环下面,添加以下内容:
rewind_posts();
// Second Loop - posts not with the 'content' tag
while ( have_posts() ) : the_post();
if ( !has_tag( $tag ) ) {
get_template_part( 'includes/loop', 'category');
}
// End the loop.
endwhile; ?>
倒带帖子(如果没有带标签的帖子,则是第一次,如果有标签,则第二次,),然后再次运行循环。 这次,它会检查帖子中是否没有 'content'标签,然后使用我们的模板部分将其输出。
成品档案
现在,在您的网站上测试类别存档页面。
如果您像我一样使用WordPress测试单元数据,则会发现“标记”类别中的帖子带有“内容”标签。 这是我网站上“标记”类别的类别存档页面:
摘要
从一个查询运行多个循环并不复杂。 不用重置查询并创建一个新查询,而是使用rewind_posts()
函数来回滚查询并再次运行它。 而不是定义新的查询参数,而是使用条件标签来指定输出哪些帖子。
重要说明:执行此操作时,请勿尝试使用query_posts()
更改主查询。 与使用多个查询相比,这会使您的网站速度降低更多。
在此示例中,我们基于主查询运行了两个循环,使用WP_Query
节省了运行两个附加查询的时间,这将减少服务器负载。 通过编辑适当的模板文件,可以将这种技术应用于使用WP_Query
定义的查询或其他归档页面上的主查询。