Codex

Interested in functions, hooks, classes, or methods? Check out the new WordPress Code Reference!

uk:The Loop in Action

Вступ

"Цикл" є основним процесом у WordPress. Використовуйте Цикл у файлах Вашого шаблону для того, аби вивести публікації і показати їх відвідувачам сайту. В принципі можна зробити шаблони без Циклу, але тоді можна показати дані тільки з однієї публікації.

Перед тим як Цикл починає діяти, WordPress перевіряє чи присутні усі необхідні файли. Тоді WordPress вибирає з бази даних типові налаштування, встановлені адміністратором блогу. Це такі налаштування як: скільки публікацій вивести на одній сторінці, чи включене коментування тощо. Як тільки з'ясовано ці налаштування, WordPress перевіряє, що саме попросив користувач. Ця інформація використовується для того, щоби встановити, які публікації потрібно вибрати з бази даних.

Якщо у запиті не вказано конкретну публікацію, категорію, сторінку чи дату, WordPress використовує зібрані раніше типові значення, щоб визначити, які публікації підготувати для виведення. Наприклад, якщо адміністратором блогу було вибрано в Адміністрування > Налаштування > Читання показувати 5 публікацій на одній сторінці, то WordPress вибере п'ять останніх публікацій з бази даних. Якщо конкретна публікація, категорія, сторінка чи дата все-таки були вказані, WordPress використає цю інформацію, щоби вказати, яку публікацію(-ції) вибрати з бази даних.

Після того, як це все вже зроблено, WordPress підключається до бази даних, отримує зазначену інформацію, та зберігає результати в змінну. Цикл використовує значення цієї змінної для відображення в шаблонах.

У випадку, якщо відвідувач не вибрав конкретну публікацію, сторінку, категорію чи дату, WordPress використовує index.php для відображення усього. У першій частині цього обговорення Циклу ми сконцентруємо свою увагу тільки на сторінці index.php і відображенні блогу у типовому випадку. Пізніше, як тільки ви розумієте, як це все працює, ми дослідимо трюки з Циклом в інших файлах шаблону.

Найпростіша головна сторінка шаблону

Нижче наведено функціональну головну сторінку шаблону (index.php), яка відображає вміст (і тільки вміст) кожної публікації, відповідно до умов, які використовуються для підготовки Циклу. Цей приклад демонструє, як мало насправді потрібно для функціонування Циклу.

<?php
get_header();
if (have_posts()) :
   while (have_posts()) :
      the_post();
      the_content();
   endwhile;
endif;
get_sidebar();
get_footer(); 
?>

Цикл у випадку з типовими значеннями

Далі розглянемо покроково використання Циклу у випадку з типовими значеннями як це є у темах default і classic при стандартному встановленню WordPress версії 1.5.

Починаємо Цикл

У верхній частині файлу index.php, який належить до шаблону теми default є код для розпочинання Циклу.

<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
  1. Спочатку відбувається перевірка, чи функцією have_posts() було виявлено хоч якісь публікації.
  2. Якщо публікації наявні, розпочинається PHP'шний цикл while. Цикл while буде виконуватися, доки умова в дужках буде логічно правильною. Таким чином, доки функція have_posts() повертатиме значення true, доти буде повторюватися цикл while. (Функція have_posts() просто перевіряє наявність наступного елемента в наборі можливих публікацій. Якщо інший елемент є, вираз з умовним оператором if знову повертає значення 'true', тому цикл while прокручується ще раз. Якщо наступного елемента нема, вираз з if повертає значення 'false' і Цикл переходить до інструкцій, які є після виразів if та while.)

Утворення публікації

Функція the_post() бере поточний елемент з набору відібраних публікацій і робить його доступним всередині цього повторення Циклу. Без the_post(), багато з Тегів шаблонів, які використовує Ваша тема, не працюватимуть.

Як тільки дані публікації стають наявними, шаблон може починати їх виведення на сторінку.

Заголовок, Дата та Автор

Наступні теги шаблонів отримують заголовок публікації, час, коли вона була випущена і хто її опублікував.

<h2 id="post-<?php the_ID(); ?>">
<a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>">
<?php the_title(); ?></a></h2>
<small><?php the_time('F jS, Y') ?> <!-- by <?php the_author() ?> --></small>

Тіло публікації

Тег шаблонів the_content() дістає вміст публікації, фільтрує її, а тоді виводить її на сторінку. Це найголовніша частина кожного прокручування Циклу:

<div class="entry">
<?php the_content('Read the rest of this entry &raquo;'); ?>
</div>

Як каже документація функції the_content() скорочений тег <!--more--> використовується для вказання функції the_content() уривку тексту, який потрібно вивести на сторінках, на яких є по декілька публікацій. Шматок тексту, переданий функції the_content(), використовується для посилання "Читати далі" після кожного уривку тексту. Щоб дізнатися більше про уривки тексту, швидкий тег<!--more--> чи посилання "Читати далі", дивіться Теги шаблонів/the_content і Налаштування посилання "Читати далі".

Додаткова інформація

Розділ метаданих публікації розміщений під вмістом кожної публікації у файлові шаблону index.php і використовується для виведення на сторінку інформації про публікацію, таку як: категорії, дата, та коментарі. Для авторизованих користувачів з достатніми дозволами (чи для автора публікації) розміщення тегу шаблонів edit_post_link() дає можливість бачити посилання "Редагувати цю сторінку".

<p class="postmetadata">
Posted in <?php the_category(', ') ?> 
<strong>|</strong>
<?php edit_post_link('Edit','','<strong>|</strong>'); ?>  
<?php comments_popup_link('No Comments »', '1 Comment »', '% Comments »'); ?></p>

Якщо коментування увімкнене, або якщо публікація має коментарі тег шаблонів comments_popup_link() буде виводити посилання на коментарі. Якщо Ви користуєтеся виринаючим вікном коментарів, це посилання буде відкривати вікно з коментарями; в іншому випадку воно буде перекидати відвідувача сайту прямісінько до коментарів публікації.

Якщо відвідувач переглядає список публікацій (наприклад: більш, ніж одна публікація в Циклі), посилання comments_popup_link() буде переводити читача на індивідуальну сторінку цієї публікації.

Trackback Auto-Discovery

The trackback_rdf template tag's function is to output machine-readable code used for trackback auto-discovery.

<!--
<?php trackback_rdf(); ?>
-->

Note: The trackback_rdf() tag is intentionally used within an HTML comment; it is not being "turned off". The reason for this is that, otherwise, RDF breaks validation in non-XML documents, and in XHTML documents it is parsed incorrectly by most browsers.

Закінчення Циклу

Далі цикл закінчується. Як і очікувалося після цього, різні теги шаблонів, які мають відношення до публікацій працювати не будуть (а якщо і будуть, то використовуватимуть останню публікацію Циклу). Це означає що, якщо потрібно застосувати тег шаблонів, який працює в межах Циклу, потрібно розмістити його до цього місця.

<?php endwhile; ?>

This section, immediately after the end of The Loop, displays navigation controls to move forward and backward by each web page. More information is available in function reference for posts_nav_link().

 <div class="navigation">
 <div class="alignleft"><?php previous_posts_link('&laquo; Previous Entries') ?></div>
 <div class="alignright"><?php next_posts_link('Next Entries &raquo;','') ?></div>
 </div>

If the blog is set to display 10 posts per page, and the conditions used by The Loop collect 25 posts, there will be three pages to navigate: two pages of 10 posts each, and one page of 5 posts. The navigation links will allow the visitor to move forward and backward through the collection of posts.

The navigation controls are included outside The Loop, but inside the if condition, so that they only show up if there are any posts. The navigation functions themselves also check whether or not there is anything to which they will link, based on the current Loop, and only display links if there's something to link.

<?php else : ?>
 <h2 class="center">Not Found</h2>
 <p class="center">
<?php _e("Sorry, but you are looking for something that isn't here."); ?></p>

The else : clause determines what to do if have_posts() (from way up at the top) is false. That is to say, the stuff after the else will only be executed/displayed if The Loop had zero posts. No posts show up if, for example, the visitor requested a specific day for which no posts were made or a search was performed that produced no results.

  <?php endif; ?>

This ends the conditional test of "if there are posts do this, else if there are no posts, do that". Once the conditional test is finished, the default index.php template next includes the sidebar, and finally the footer.

The Loop In Other Templates

WordPress can use different template files for displaying your blog in different ways. In the default WordPress theme, there are template files for the index view, category view, and archive view, as well as a template for viewing individual posts. Each of these uses The Loop, but does so with slightly different formatting, as well as different uses of the template tags.

For any view which does not have a separate template file, WordPress will use index.php by default. If a visitor requests a single post, WordPress will first look for a file named single.php. If that file exists, it will be used to present the post to the visitor. If that file does not exist, WordPress will use index.php to present the post to the visitor. This is called the Template Hierarchy.

If you are making your own Theme, it's often helpful to look at the template files from the default Theme as a point of reference. It's also helpful to use your theme's index.php as a template for your other template files. Doing so may give you a known and working page from which to begin making changes as you create more template files.

Different Archive Format

An archive is a collection of historical posts. In the default usage, the posts displayed on your main index are recent chronological postings. When a visitor clicks on one of your archive links, or if they manually request a specific date (http://www.example.com/blog/index.php?m=200504 or http://www.example.com/blog/2005/04 to select all posts from April, 2005), WordPress will display an archive view. By default, the archive will use index.php, and thus look the same as your front page, just displaying the posts from April 2005.

When WordPress prepares an archive view for a visitor, it specifically looks for a file named archive.php in your current theme's directory. If you'd like to visually disambiguate archives from your front page, simply copy index.php to archive.php, and edit archive.php as necessary!

For example, if you want to show only post titles, and no post content, for your list of archives, you could use something like this:

<?php get_header(); ?>
 <div id="content" class="narrowcolumn">

  <?php if (have_posts()) : ?>
   <?php while (have_posts()) : the_post(); ?>
     <div class="post">
     <h2 id="post-<?php the_ID(); ?>">
<a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>"><?php the_title(); ?></a></h2>
     <small><?php the_time('F jS, Y') ?> <!-- by <?php the_author() ?> --></small>
      </div>
    <?php endwhile; ?>
<div class="navigation">
<div class="alignleft">
<?php posts_nav_link('','','&laquo; Previous Entries') ?>
</div>
<div class="alignright">
<?php posts_nav_link('','Next Entries &raquo;','') ?>
</div>
  </div>
<?php else : ?>
  <h2 class="center">Not Found</h2>
 <p class="center"><?php _e("Sorry, but you are looking for something that isn't here."); ?></p>
  <?php endif; ?>
</div>
<?php get_sidebar(); ?>
<?php get_footer(); ?>

Different Category Format

Like the archive views, WordPress looks for a separate template file for category views. If a visitor clicks on a link for a category in your blog, they will be taken to the category view. WordPress will prepare The Loop with posts from that category only, limiting the number of posts per the blog's default settings.

To make your category view different from your index view, copy index.php and rename it category.php. For a category view, it's probably not necessary to list the categories to which a post is assigned, so let's remove that portion. Instead, let's announce the category at the top of the page:

<?php get_header(); ?>
 <div id="content" class="narrowcolumn">
 <p>
 <strong>
  <?php single_cat_title('Currently browsing '); ?>
  </strong><br />
 <?php echo category_description(); ?>
 </p>
 <?php if (have_posts()) : ?>
   <?php while (have_posts()) : the_post(); ?>
     <div class="post">
      <h2 id="post-<?php the_ID(); ?>">
<a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>">
<?php the_title(); ?></a></h2>
   <small>
     <?php the_time('F jS, Y') ?> 
        <!-- by <?php the_author() ?> -->
   </small>
 </div>
<?php endwhile; ?>
 <div class="navigation">
   <div class="alignleft">
    <?php posts_nav_link('','','&laquo; Previous Entries') ?>
   </div>
   <div class="alignright">
    <?php posts_nav_link('','Next Entries &raquo;','') ?>
   </div>
 </div>
<?php else : ?>
  <h2 class="center">Not Found</h2>
<p class="center"><?php _e("Sorry, but you are looking for something that isn't here."); ?></p>
 <?php endif; ?>
</div>
<?php get_sidebar(); ?>
<?php get_footer(); ?>

Different Formats for Different Categories

As explained in the Template Hierarchy, it is possible to create separate template files for each category. Simply name the file category-X.php, where X is the numerical ID of the category. Consider carefully whether you need a whole new template for a specific category.

Let's look at two categories, "Plants" and "Flowers", with category IDs 3 and 4, respectively. Next to each post title in the output you want to have picture of either a plant, or a flower, depending on which category is being displayed. You could:

  • Use two separate files, category-3.php and category-4.php, each with a different img tag for each post title.
  • Use a conditional test inside your default category.php file to check whether the current category is "Plants" or "Flowers" (or neither), and display the appropriate image:
<?php if (is_category('3') ):
 // we're in the Plants category, so show a plant ?>
 <img src='/images/plant.png' alt='a plant' />
<?php } elseif (is_category('4') ):
 // we're in the Flowers category, so show a flower ?>
 <img src='/images/flower.png' alt='a pretty flower' />
<?php endif; // end the if, no images for other other categories ?>

If you added another category, "Cars", which you wanted to display in a significantly different way, then a separate category-X.php would be more appropriate.

Different CSS For Different Categories

Many users want to create separate CSS files for a specific category. This, too, can be easily accomplished. It is important to remember that stylesheets are defined and loaded in the <head> section of the HTML document. WordPress uses the header.php file for this. In the default header.php, find this line:

<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />

And change it to something like this:

<?php if ( is_category('5') ) { // Load special CSS for "Cars" category ?>
  <link rel="stylesheet" href="<?php bloginfo('template_url'); ?>/category-5.css" type="text/css" media="screen" />;
<?php } else { ?>
   <link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />
<?php } ?>

Note: The Cars template uses the category-5.css file to override the default layout. In this example the CSS file is named after the category template file to which it will be applied, rather than the actual name of the category. Thus, you know that category-5.css goes with category-5.php.

Different Single Post Format

When viewing any single post (or permalink), WordPress will use single.php, if present.

This portion, from the WordPress default single.php, provides the post meta data information about the current post:

<p class="postmetadata alt">
<small>
This entry was posted on <?php the_time('l, F jS, Y') ?> at <?php the_time() ?> 
and is filed under <?php the_category(', ') ?>.
You can follow any responses to this entry through 
the <?php comments_rss_link('RSS 2.0'); ?> feed.
<?php
if ( comments_open() && pings_open() ) {
// Both Comments and Pings are open
?>
  You can <a href="#respond">leave a response</a>, or 
  <a href="<?php trackback_url(display); ?>">trackback</a> 
from your own site.
<?php 
} elseif ( !comments_open() && pings_open() ) {
// Only Pings are Open 
?>
  Responses are currently closed, but you can 
  <a href="<?php trackback_url(display); ?> ">trackback</a> 
from your own site.
<?php
} elseif ( comments_open() && !pings_open() ) { 
// Comments are open, Pings are not 
?>
  You can skip to the end and leave a response. Pinging is currently not allowed.
<?php
} else { 
// Neither Comments, nor Pings are open 
?>
  Both comments and pings are currently closed.
<?php 
} 
edit_post_link('Edit this entry.','',''); ?>
</small>
</p>

This sort of information -- whether comments are open or closed -- is largely inappropriate on an index, archive, or category view; which is why it's only included in the single.php template file.

Other Loop Tricks

Now that you have a good introduction to the basic uses for the WordPress Loop, let's introduce you to some more Loop effects and tricks.

Static Front Page

How can you display something special only on the front page of your blog? That's right, only on the front page or home page, and have it not be seen anywhere else on your site. Easy! We call this the static front page. The front or first page of your site isn't really static. It's just using the Loop to make it look that way.

To make this Loop trick work, use the is_home() conditional template tag function.

In your index.php, use an if () test to conditionally output additional content:

<?php get_header(); ?>
<?php if (is_home()) {
 // we're on the home page, so let's show a picture of our new kitten!
 echo "<img src='/images/new_kitty.jpg' alt='Our new cat, Rufus!' />";
 // and now back to our regularly scheduled home page
} ?> 

The function is_home() will only produce a true value if the visitor is not requesting a specific post, page, category, or date, so it only shows up on the "home" page.

For more information, see Creating a Static Front Page.

Excerpts Only

The easiest way to display excerpts, instead of the full content, of posts, replace all instances of the_content() with the_excerpt(). If you have not created explicit excerpts for your posts, this function will automatically display the first 55 words of the post.

<div class="entry">
<?php the_excerpt(); ?>
</div>

Showing Excerpts or Full Post Depending Upon Number of Posts

In some circumstances, for example on archive pages, you may want to show the full post if there is only one post or excerpts if there are multiple posts. You can customize the loop to do this.

<?php if (have_posts()) : ?>

  <?php if (($wp_query->post_count) > 1) : ?>
     <?php while (have_posts()) : the_post(); ?>
       <!-- Do your post header stuff here for excerpts-->
          <?php the_excerpt() ?>
       <!-- Do your post footer stuff here for excerpts-->
     <?php endwhile; ?>

  <?php else : ?>

     <?php while (have_posts()) : the_post(); ?>
       <!-- Do your post header stuff here for single post-->
          <?php the_content() ?>
       <!-- Do your post footer stuff here for single post-->
     <?php endwhile; ?>

  <?php endif; ?>

<?php else : ?>
     <!-- Stuff to do if there are no posts-->

<?php endif; ?>

Different Headers/Sidebars/Footers

WordPress offers the get_header(), get_sidebar(), and get_footer() Include Tags for use in your template files. These functions make it easy to define a standard header/sidebar/footer which is easily editable. Any changes made to these files will immediately be made visible to viewers, without any work on your part.

But sometimes you might not want a sidebar. If you don't want a sidebar, simply exclude the call to the get_sidebar() function from your template. For example, the single.php template in the WordPress default theme does not include a sidebar.

To create your own different sidebar, you have two choices:

  1. Include the sidebar contents directly into the template file on which you're working. If you want category-3 to have a different sidebar, edit category-3.php and include the necessary HTML and PHP to generate your distinctive sidebar.
  2. Use the PHP include function, to include another file. The WordPress get_sidebar() function only loads sidebar.php. If you make a file named sideleft.php, you would include it like this:
<?php include(TEMPLATEPATH . '/sideleft.php'); ?>

In WordPress Version 2.5 and above you can also call a sidebar like this:

<?php get_sidebar('right'); ?>

This causes the template TEMPLATEPATH . 'sidebar-right.php' to be included.

Using the WordPress default Template Hierarchy, if you want to use the same elements on multiple or different templates, it's probably best to put them in separate template files and use the PHP include() function. If the element you're adding is specifically for one template file, it's probably best to include it directly in that template file.

Summary

We've just scratched the surface of what can be done with the Loop. As a reminder, the following are resources that will help you customize your own WordPress Loop.