循环是 WordPress 默认的机制,用于通过主题模板文件输出文章。它根据阅读设置中每页显示的文章数量检索文章,并循环处理每个文章以应用主题的格式化指令。
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post();
the_content();
endwhile;
else :
_e( 'Sorry, no posts matched your criteria.', 'textdomain' );
endif;
?>The Loop is the default mechanism WordPress uses for outputting posts through a theme’s template files. How many posts are retrieved is determined by the number of posts to show per page defined in the Reading settings. Within the Loop, WordPress retrieves each post to be displayed on the current page and formats it according to your theme’s instructions.
The Loop extracts the data for each post from the WordPress database and inserts the appropriate information in place of each template tag. Any HTML or PHP code in The Loop will be processed for each post.
To put it simply, the Loop is true to its name: it loops through each post retrieved for the current page one at a time and performs the action specified in your theme.
You can use the Loop for a number of different things, for example to:
You can customize the Loop across your template files to display and manipulate different content.
The basic loop is:
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post();
// Display post content
endwhile;
endif;
?>
This loop says that when there are posts, loop through and display the posts. Broken down into more detail:
<a href="https://developer.wordpress.org/reference/functions/have_posts/">have_posts()</a> function checks whether there are any posts.while loop continues to execute as long as the condition in the parenthesis is logically true. As long as have_posts() continues to be true, the loop will continue.The Loop should be placed in index.php, and in any other templates which are used to display post information. Because you do not want to duplicate your header over and over, the loop should always be placed after the call to <a href="https://developer.wordpress.org/reference/functions/get_header/">get_header()</a>. For example:
<?php
get_header();
if ( have_posts() ) :
while ( have_posts() ) : the_post();
// Display post content
endwhile;
endif;
?>
In the above example, the end of the Loop is shown with an endwhile and endif. The Loop must always begin with the same if and while statements, as mentioned above and must end with the same end statements.
Any template tags that you wish to apply to all posts must exist between the beginning and ending statements.
endwhile and endif statements, as seen in examples below.An extremely simple index.php file would look like:
<?php
get_header();
if ( have_posts() ) :
while ( have_posts() ) : the_post();
the_content();
endwhile;
else :
_e( 'Sorry, no posts matched your criteria.', 'textdomain' );
endif;
get_sidebar();
get_footer();
?>
The Loop can display a number of different elements for each post. For example, some common template tags used in many themes are:
<a href="https://developer.wordpress.org/reference/functions/next_post_link/">next_post_link()</a> – a link to the post published chronologically after the current post<a href="https://developer.wordpress.org/reference/functions/previous_post_link/">previous_post_link()</a> – a link to the post published chronologically before the current post<a href="https://developer.wordpress.org/reference/functions/the_category/">the_category()</a> – the category or categories associated with the post or page being viewed<a href="https://developer.wordpress.org/reference/functions/the_author/">the_author()</a> – the author of the post or page<a href="https://developer.wordpress.org/reference/functions/the_content/">the_content()</a> – the main content for a post or page<a href="https://developer.wordpress.org/reference/functions/the_excerpt/">the_excerpt()</a> – the first 55 words of a post’s main content followed by an ellipsis (…) or read more link that goes to the full post. You may also use the “Excerpt” field of a post to customize the length of a particular excerpt.<a href="https://developer.wordpress.org/reference/functions/the_id/">the_ID()</a> – the ID for the post or page<a href="https://developer.wordpress.org/reference/functions/the_meta/">the_meta()</a> – the custom fields associated with the post or page<a href="https://developer.wordpress.org/reference/functions/the_shortlink/">the_shortlink()</a> – a link to the page or post using the url of the site and the ID of the post or page<a href="https://developer.wordpress.org/reference/functions/the_tags/">the_tags()</a> – the tag or tags associated with the post<a href="https://developer.wordpress.org/reference/functions/the_title/">the_title()</a> – the title of the post or page<a href="https://developer.wordpress.org/reference/functions/the_time/">the_time()</a> – the time or date for the post or page. This can be customized using standard php date function formatting.You can also use conditional tags, such as:
<a href="https://developer.wordpress.org/reference/functions/is_home/">is_home()</a> – Returns true if the current page is the homepage<a href="https://developer.wordpress.org/reference/functions/is_admin/">is_admin()</a> – Returns true if inside Administration Screen, false otherwise<a href="https://developer.wordpress.org/reference/functions/is_single/">is_single()</a> – Returns true if the page is currently displaying a single post<a href="https://developer.wordpress.org/reference/functions/is_page/">is_page()</a> – Returns true if the page is currently displaying a single page<a href="https://developer.wordpress.org/reference/functions/is_page_template/">is_page_template()</a> – Can be used to determine if a page is using a specific template, for example: is_page_template('about-page.php')<a href="https://developer.wordpress.org/reference/functions/is_category/">is_category()</a> – Returns true if page or post has the specified category, for example: is_category('news')<a href="https://developer.wordpress.org/reference/functions/is_tag/">is_tag()</a> – Returns true if a page or post has the specified tag<a href="https://developer.wordpress.org/reference/functions/is_author/">is_author()</a> – Returns true if inside author’s archive page<a href="https://developer.wordpress.org/reference/functions/is_search/">is_search()</a> – Returns true if the current page is a search results page<a href="https://developer.wordpress.org/reference/functions/is_404/">is_404()</a> – Returns true if the current page does not exist<a href="https://developer.wordpress.org/reference/functions/has_excerpt/">has_excerpt()</a> – Returns true if the post or page has an excerptLet’s take a look at some examples of the Loop in action:
Most blogs have a blog archive page, which can show a number of things including the post title, thumbnail, and excerpt. The example below shows a simple loop that checks to see if there are any posts and, if there are, outputs each post’s title, thumbnail, and excerpt. If no posts exists, it displays the message in parentheses.
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post();
the_title( '<h2>', '</h2>' );
the_post_thumbnail();
the_excerpt();
endwhile;
else:
_e( 'Sorry, no posts matched your criteria.', 'textdomain' );
endif;
?>
In WordPress, each post has its own page, which displays the relevant information for that post. Template tags allow you to customize which information you want to display.
In the example below, the loop outputs the post’s title and content. You could use this example in a post or page template file to display the most basic information about the post. You could also customize this template to add more data to the post, for example the category.
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post();
the_title( '<h1>', '</h1>' );
the_content();
endwhile;
else:
_e( 'Sorry, no pages matched your criteria.', 'textdomain' );
endif;
?>
The example below does a couple of things:
<a href="https://developer.wordpress.org/reference/functions/in_category/">in_category()</a> template tag.Code comments in this example provide details throughout each stage of the loop:
<?php
// Start the Loop.
if ( have_posts() ) :
while ( have_posts() ) : the_post();
/* * See if the current post is in category 3.
* If it is, the div is given the CSS class "post-category-three".
* Otherwise, the div is given the CSS class "post".
*/
if ( in_category( 3 ) ) : ?>
<div class="post-category-three">
<?php else : ?>
<div class="post">
<?php endif;
// Display the post's title.
the_title( '<h2>', ';</h2>' );
// Display a link to other posts by this posts author.
printf( __( 'Posted by %s', 'textdomain' ), get_the_author_posts_link() );
// Display the post's content in a div.
?>
<div class="entry">
<?php the_content() ?>
</div>
<?php
// Display a comma separated list of the post's categories.
_e( 'Posted in ', 'textdomain' ); the_category( ', ' );
// closes the first div box with the class of "post" or "post-cat-three"
?>
</div>
<?php
// Stop the Loop, but allow for a "if not posts" situation
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.
*/
_e( 'Sorry, no posts matched your criteria.', 'textdomain' );
// Completely stop the Loop.
endif;
?>
In some situations, you may need to use more than one loop. For example you may want to display the titles of the posts in a table of content list at the top of the page and then display the content further down the page. Since the query isn’t being changed we simply need to rewind the loop when we need to loop through the posts for a second time. For that we will use the function rewind_posts() .
You can use <a href="https://developer.wordpress.org/reference/functions/rewind_posts/">rewind_posts()</a> to loop through the same query a second time. This is useful if you want to display the same query twice in different locations on a page.
Here is an example of rewind_posts() in use:
<?php
// Start the main loop
if ( have_posts() ) :
while ( have_posts() ) : the_post();
the_title();
endwhile;
endif;
// Use rewind_posts() to use the query a second time.
rewind_posts();
// Start a new loop
while ( have_posts() ) : the_post();
the_content();
endwhile;
?>
Using two loops with the same query was relatively easy but not always what you will need. Instead, you will often want to create a secondary query to display different content on the template. For example, you might want to display two groups of posts on the same page, but do different things to each group. A common example of this, as shown below, is displaying a single post with a list of posts from the same category below the single post.
<?php
// The main query.
if ( have_posts() ) :
while ( have_posts() ) : the_post();
the_title();
the_content();
endwhile;
else :
// When no posts are found, output this text.
_e( 'Sorry, no posts matched your criteria.' );
endif;
wp_reset_postdata();
/*
* The secondary query. Note that you can use any category name here. In our example,
* we use "example-category".
*/
$secondary_query = new WP_Query( 'category_name=example-category' );
// The second loop.
if ( $secondary_query->have_posts() )
echo '<ul>';
while ( $secondary_query->have_posts() ) : $secondary_query->the_post();
the_title( '<li>', '</li>' );
endwhile;
echo '</ul>';
endif;
wp_reset_postdata();
?>
As you can see in the example above, we first display a regular loop. Then we define a new variable that uses <a href="https://developer.wordpress.org/reference/classes/wp_query/">WP_Query</a> to query a specific category; in our case, we chose the example-category slug.
Note that the regular loop in the example above has one difference: it calls <a href="https://developer.wordpress.org/reference/functions/wp_reset_postdata/">wp_reset_postdata()</a> to reset the post data. Before you can use a second loop, you need to reset the post data. There are two ways to do this:
<a href="https://developer.wordpress.org/reference/functions/rewind_posts/">rewind_posts()</a> function; orIt’s important when using multiple loops in a template that you reset them. Not doing so can lead to unexpected results due to how data is stored and used within the global $post variable. There are three main ways to reset the loop depending on the way they are called.
<a href="https://developer.wordpress.org/reference/functions/wp_reset_postdata/">wp_reset_postdata()</a><a href="https://developer.wordpress.org/reference/functions/wp_reset_query/">wp_reset_query()</a><a href="https://developer.wordpress.org/reference/functions/rewind_posts/">rewind_posts()</a>Use <a href="https://developer.wordpress.org/reference/functions/wp_reset_postdata/">wp_reset_postdata()</a> when you are running custom or multiple loops with WP_Query. This function restores the global $post variable to the current post in the main query. If you’re following best practices, this is the most common function you will use to reset loops.
To properly use this function, place the following code after any loops with WP_Query:
<?php wp_reset_postdata(); ?>
Here is an example of a loop using WP_Query that is reset with <a href="https://developer.wordpress.org/reference/functions/wp_reset_postdata/">wp_reset_postdata()</a>.
<?php
// Example argument that defines three posts per page.
$args = array( 'posts_per_page' => 3 );
// Variable to call WP_Query.
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
// Start the Loop
while ( $the_query->have_posts() ) : $the_query->the_post();
the_title();
the_excerpt();
// End the Loop
endwhile;
else:
// If no posts match this query, output this text.
_e( 'Sorry, no posts matched your criteria.', 'textdomain' );
endif;
wp_reset_postdata();
?>
Using <a href="https://developer.wordpress.org/reference/functions/wp_reset_query/">wp_reset_query()</a> restores the WP_Query and global $post data to the original main query. You MUST use this function to reset your loop if you use <a href="https://developer.wordpress.org/reference/functions/query_posts/">query_posts()</a> within your loop. You can use it after custom loops with WP_Query because it actually calls <a href="https://developer.wordpress.org/reference/functions/wp_reset_postdata/">wp_reset_postdata()</a> when it runs. However, it’s best practice to use <a href="https://developer.wordpress.org/reference/functions/wp_reset_postdata/">wp_reset_postdata()</a> with any custom loops involving WP_Query.
<a href="https://developer.wordpress.org/reference/functions/query_posts/">query_posts()</a> is not best practice and should be avoided if at all possible. Therefore, you shouldn’t have much use for <a href="https://developer.wordpress.org/reference/functions/wp_reset_query/">wp_reset_query()</a>.To properly use this function, place the following code after any loops with <a href="https://developer.wordpress.org/reference/functions/query_posts/">query_posts()</a>.
<?php wp_reset_query(); ?>