- A+
The Loop(循环)是 WordPress 用来显示文章的 PHP 代码。使用 The Loop,WordPress 可以在当前页面处理每一篇要显示的文章,在 Loop 内的任何 HTML 或者 PHP 代码将会针对每篇文章执行一次。
当 WordPress 文档说”该标签必须用在循环内”(例如一些特定的模板标签)时,那该标签将会针对每篇文章都重复执行一次。例如,The Loop 默认针对每篇文章都重复执行下面的这些信息:
- 标题 (the_title())
- 时间 (the_time())
- 分类 (the_category()).
通过使用合适的模板标签,或者使用 $post 变量(Loop 运行时与当前文章信息相同),你也可以显示关于文章的其他信息。
对于初学者来说,请参看 使用 The Loop。
使用 Loop
The Loop 应该放置于 index.php
中或者任何其他用来显示文章信息的模板之中。
The loop 开始于:
- <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
结束于:
- <?php endwhile; else : ?>
- <p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
- <?php endif; ?>
也可是使用如下的语法结构:
- <?php
- if ( have_posts() ) {
- while ( have_posts() ) {
- the_post();
- //
- // Post Content here
- //
- } // end while
- } // end if
- ?>
Loop 例子
某些分类的文章显示不同样式
下面的例子显示每篇文章的标题,分类及内容。如果文章属于 ID 为 ‘3’ 的分类,则赋予它不同的样式。为了达成此目的,使用了 in_category() 函数。请仔细阅读注释以明确每段代码的作用。
- <!-- 开始循环 -->
- <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
- <!-- 判断当前文章是否属于分类 3 -->
- <!-- If it is, the div box is given the CSS class "post-cat-three". -->
- <!-- Otherwise, the div box is given the CSS class "post". -->
- <?php if ( in_category( '3' ) ) : ?>
- <div class="post-cat-three">
- <?php else : ?>
- <div class="post">
- <?php endif; ?>
- <!-- 显示标题,并赋予文章的链接 -->
- <h2><a href="<?php the_permalink(); ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
- <!-- 显示日期(November 16th, 2009 format)以及该作者其他文章的链接 -->
- <small><?php the_time('F jS, Y'); ?> by <?php the_author_posts_link(); ?></small>
- <!-- 显示该文章的内容 -->
- <div class="entry">
- <?php the_content(); ?>
- </div>
- <!-- 以逗号为分隔显示文章所属多个分类 -->
- <p class="postmetadata"><?php _e( 'Posted in' ); ?> <?php the_category( ', ' ); ?></p>
- </div> <!-- closes the first div box -->
- <!-- Stop The Loop (but note the "else:" - see next line). -->
- <?php endwhile; else : ?>
- <!-- The very first "if" tested to see if there were any Posts to -->
- <!-- display. This "else" part tells what do if there weren't any. -->
- <p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
- <!-- REALLY stop The Loop. -->
- <?php endif; ?>
排除某些分类的文章
这个例子展示了如何隐藏某个或某几个分类的文章。在这个例子中,分类 3 和分类 8 的文章被排除。
- <?php $query = new WP_Query( 'cat=-3,-8' ); ?>
- <?php if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post(); ?>
- <div class="post">
- <!-- Display the Title as a link to the Post's permalink. -->
- <h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
- <!-- Display the date (November 16th, 2009 format) and a link to other posts by this posts author. -->
- <small><?php the_time( 'F jS, Y' ); ?> by <?php the_author_posts_link(); ?></small>
- <div class="entry">
- <?php the_content(); ?>
- </div>
- <p class="postmetadata"><?php _e( 'Posted in' ); ?> <?php the_category( ', ' ); ?></p>
- </div> <!-- closes the first div box -->
- <?php endwhile;
- wp_reset_postdata();
- else : ?>
- <p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>
- <?php endif; ?>
多重 Loops
本节内容讲述 Loop 的高级应用。这有一点难度,但是不要被吓到,我们将从一个简单的例子开始,用一点推理、耐心以及乐观的态度,你也可以掌握多重 loops。
首先,为什么要使用多重循环?一般来说,答案是你想对一组文章做一些事情,然后对另一组文章做不同的事情,但将两组文章显示在同一页面上。”一些事情”可以是任何事情,只受限与你的 PHP 水平及你的想象力。
下面我们将举一些例子,但首先我们来看一下基本的 Loop,它包含:
- <?php if ( have_posts() ) : ?>
- <?php while ( have_posts() ) : the_post(); ?>
- <!-- do stuff ... -->
- <?php endwhile; ?>
- <?php endif; ?>
上面代码的意思是:如果要显示文章,则取出它们,一次一篇。对于每篇文章,根据 <!– do stuff … –> 的内容显示它。当获取到最后一篇文章时,停止。
关于 Do stuff:在上面的例子中,它代表一大推代码,决定如何显示每篇文章。这些代码可以根据你的喜好改变。
Loop 例子
下面是三个使用多重循环的例子。使用多重循环的关键是 $wp_query 只能调用一次。为了解决这个问题,我们可以通过调用 rewind_posts() 重复使用冲讯,或者可以创建一个新的查询对象。这在例子1中得到体现。而在例子2中,是使用一个变量存储一个查询。最后,”应用多重循环”将多种方法结合在一起。
多重循环示例1
调用 rewind_posts() 可以重复使用同一个查询。这将重置 loop 计数器,允许你再循环一次。
- <?php rewind_posts(); ?>
- <?php while ( have_posts() ) : the_post(); ?>
- <!-- Do stuff... -->
- <?php endwhile; ?>
如果你使用完了原始查询,然后你想使用另一个查询,你可以通过调用 query_posts() 重复使用 $wp_query 对象。query_posts() 将执行一个新的查询,建立一个新的文章数组,重置 loop 计数器。
- // 获取 special_cat 分类下的最新10篇文章
- <?php query_posts( 'category_name=special_cat&posts_per_page=10' ); ?>
- <?php while ( have_posts() ) : the_post(); ?>
- <!-- Do special_cat stuff... -->
- <?php endwhile; ?>
如果你不想改变原始查询,你可以创建一个新的查询对象。
- <?php $my_query = new WP_Query( 'category_name=special_cat&posts_per_page=10' ); ?>
- <?php while ( $my_query->have_posts() ) : $my_query->the_post(); ?>
- <!-- Do special_cat stuff... -->
- <?php endwhile; ?>
上面的循环中不能使用全局函数 have_posts() 及 the_post(),因为它们使用的是 $wp_query 对象。作为替代,你可以调用 $my_query 对象内的方法。
多重循环示例2
这是另一个绕开 have_posts() 及 the_post() 使用多重循环的方法。你可以先把原始查询存储在一个变量里,然后把它分配给另一个循环。这样,你就可以使用所有依赖全局变量的标准函数了。
比如:
- // going off on my own here
- <?php $temp_query = $wp_query; ?>
- <!-- Do stuff... -->
- <?php query_posts( 'category_name=special_cat&posts_per_page=10' ); ?>
- <?php while ( have_posts() ) : the_post(); ?>
- <!-- Do special_cat stuff... -->
- <?php endwhile; ?>
- // now back to our regularly scheduled programming
- <?php $wp_query = $temp_query; ?>
应用多重循环
理解如何使用多重循环的最佳方法是展示一个完整的例子,或许多重循环最常见的例子就是在同一页面展示两组(或更多)文章列表。这常常出现在网站管理员不仅想要展示最新文章,也想展示某一分类文章的情况下。
步骤1. 从 ‘featured’ 分类中获取一篇文章
- <?php $my_query = new WP_Query( 'category_name=featured&posts_per_page=1' );
- while ( $my_query->have_posts() ) : $my_query->the_post();
- $do_not_duplicate = $post->ID; ?>
- <!-- Do stuff... -->
- <?php endwhile; ?>
这段代码的意思:
将 $my_query 的值设置为查询出来(根据名称”featured”)的所有文章(这里只查询一篇)。同时,将变量 $do_not_duplicate 设置成返回文章的 ID。
我们将在下一步用到 $do_not_duplicate 的值,以确保不会在两个列表中出现相同的文章。
步骤2. 第二个循环,获取最新 X 篇文章(除了步骤1中的那篇)
下面的代码获取最新 X 篇(WordPress 后台可以设置)文章(除了步骤1中那篇文章之外),并把它们根据 Do stuff 显示出来:
- <?php if ( have_posts() ) : while ( have_posts() ) : the_post();
- if ( $post->ID == $do_not_duplicate ) continue;?>
- <!-- Do stuff... -->
- <?php endwhile; endif; ?>
这段代码的意思:
获取所有文章,如果某篇文章等值于 $do_not_duplicate,什么都不做(继续循环),否则执行 Do stuff 的代码。
最终代码
下面是全部的代码:
- <?php $my_query = new WP_Query( 'category_name=featured&posts_per_page=1' );
- while ( $my_query->have_posts() ) : $my_query->the_post();
- $do_not_duplicate = $post->ID; ?>
- <!-- Do stuff... -->
- <?php endwhile; ?>
- <!-- Do other stuff... -->
- <?php if ( have_posts() ) : while ( have_posts() ) : the_post();
- if ( $post->ID == $do_not_duplicate ) continue; ?>
- <!-- Do stuff... -->
- <?php endwhile; endif; ?>
该代码将在一个页面生成两个列表。第一个列表只包含一篇文章—— ‘feature’ 分类下的最新一篇。第二个列表包含除了第一个列表外的,最新的 X 篇(WordPress 后台设置的数字)文章。
如果第一个分类下有多篇文章
如果 posts_per_page =2 或者更多,你需要稍微改变一下代码。变量 $do_not_duplicate 需要由一个值变成一个数组。将下面的代码:
- <?php $my_query = new WP_Query( 'category_name=featured&posts_per_page=1' );
- while ( $my_query->have_posts() ) : $my_query->the_post();
- $do_not_duplicate = $post->ID; ?>
替换为:
- <?php $my_query = new WP_Query( 'category_name=featured&posts_per_page=2' );
- while ( $my_query->have_posts() ) : $my_query->the_post();
- $do_not_duplicate[] = $post->ID; ?>
“posts_per_page” 可以是任何数字,上面的代码将 $do_not_duplicate 改变成数组。然后将
- <?php if ( have_posts() ) : while ( have_posts() ) : the_post();
- if ( $post->ID == $do_not_duplicate ) continue; ?>
替换为:
- <?php if ( have_posts() ) : while ( have_posts() ) : the_post();
- if ( in_array( $post->ID, $do_not_duplicate ) ) continue; ?>
还有一种方法,你可以把整个 $do_not_duplicate 数组传递给 $wp_query,这样只有满足你需要的文章才会被查询到:
- <?php query_posts( array( 'post__not_in' => $do_not_duplicate ) );
- if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
应注意到查询参数不再是一个字符串,而是一个数组,设置了 post__not_in 选项。
嵌套循环
嵌套循环的意思是在第一个循环尚未结束,又开始第二个循环。
- $my_query = new WP_Query( 'cat=3' );
- if ( $my_query->have_posts() ) {
- while ( $my_query->have_posts() ) {
- $my_query->the_post();
- the_content();
- }
- }
- wp_reset_postdata();
嵌套循环结束后应该重置主循环数据,这样一些全局变量又存储了正确的数值。
相关
更多关于 Loop 及 Loop 内有效的模板标签的资源:
More About The Loop
- Article: The Loop in Action
- Article: Template Tags
- Article: Using the Loop in Template Files
Articles
- Article: The Loop – A basic overview of its use of query within the WordPress loop.
- Article: Query Overview – Explanation of how to determine which queries generate WordPress.
- Article: Customizing Queries via Hook
- Article: View Articles MYSQL query using custom
- Article: Build advanced queries on Taxonomies
- Article: Build custom query using Offset and pagination
Code Documentation
- Class: WP_Query – Detailed Overview of class WP_Query
- Class: WP_Comment_Query – Class for comment-related queries
- Class: WP_User_Query – Class for user-related queries
- Object: $wpdb – Overview on the use of the $wpdb object
- Function: set_query_var()
- Function: get_query_var()
- Function: query_posts() – Create additional custom query
- Function: get_post() – Take an ID of an item and return the records in the database for that article
- Function: get_posts() – A specialized function that returns an array of items
- Function: get_pages() – A specialized function that returns an array of pages
- Function: have_posts() – A condition that determines whether the query returned an article
- Function: the_post() – Used to automatically set the loop after a query
- Function: rewind_posts() – Clears the current loop
- Function: setup_postdata() – Sets the data for a single query result within a loop
- Function: wp_reset_postdata() – Restores the previous query (usually after a loop within another loop)
- Function: wp_reset_query()
- Function: is_main_query() – Ensures that the query that is being changed is only the main query
- Action Hook: pre_get_posts – Change WordPress queries before they are executed
- Action Hook: the_post – Modify the post object after query
- Filter Hook: found_posts – Changes the value of the object found_posts WP_Query
http://codex.wordpress.org/The_Loop