'&showposts=6'; 4.1.5 Excluding Specific Categories One of the most common customization requests for WordPress is, “how do I prevent posts in a certain category from displaying on my ho
Trang 14.1.1 Customizing the Loop
As we mentioned in the previous chapter, if there is one thing that you need to
understand to be a true badass theme developer, it is how the loop works and
what you can do with it With this as our mantra, let’s spend the first part of this
chapter looking at how to do lots of different stuff with the Loop
To set the stage, a customized loop is going to have this structure:
<?php
// The Query - Customize!
query_posts('showposts=5');
// The Loop
if (have_posts()) : while (have_posts()) : the_post();
endwhile; else:
endif;
// Reset Query
wp_reset_query();
?>
Theme Design and Development
4
Trang 24.1.2 The Loop Doesn’t Care About Markup
It’s true Here is a pretty “normal” loop:
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<div class="post" id="post-<?php the_ID(); ?>">
<h2><a href="<?php the_permalink(); ?>" rel="bookmark"
title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_
title(); ?></a></h2>
<p class="meta">Posted on <?php the_time('F jS, Y'); ?></p>
<?php the_content('Read More'); ?>
<p><?php the_tags('Tags: ', ', ', '<br />'); ?> Posted in <?php the_category(', '); ?> | <?php edit_post_link('Edit', '', ' | '); ?> <?php comments_popup_link('No Comments »', '1 Comment »', '% Comments
»'); ?></p>
</div>
<?php endwhile; ?>
<?php next_posts_link('« Older Entries') ?>
<?php previous_posts_link('Newer Entries »') ?>
<?php else : ?>
<h2>No Posts Found</h2>
<?php endif; ?>
And here is the same exact loop, only marked up as a simple ordered list:
<?php if (have_posts()) : ?>
<ol>
<?php while (have_posts()) : the_post(); ?>
Trang 3<li id="post-<?php the_ID(); ?>">
<strong><a href="<?php the_permalink(); ?>" rel="bookmark"
title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_
title(); ?></a></strong>
<?php the_content('Read More'); ?>
</li>
<?php endwhile; ?>
</ol>
<?php else : ?>
<h2>No Posts Found</h2>
<?php endif; ?>
And here it is again as a definition list:
<?php if (have_posts()) : ?>
<dl>
<?php while (have_posts()) : the_post(); ?>
<dt id="post-<?php the_ID(); ?>">
<a href="<?php the_permalink(); ?>" rel="bookmark"
title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_
title(); ?></a>
</dt>
<dd>
<?php the_excerpt(); ?>
</dd>
<?php endwhile; ?>
</dl>
Trang 4<?php next_posts_link('« Older Entries'); ?>
<?php previous_posts_link('Newer Entries »'); ?>
<?php else : ?>
<h2>No Posts Found</h2>
<?php endif; ?>
Notice that not only is the markup different in each of these different examples, but the functions we use are different as well For example, the definition list example uses the_excerpt() instead of the_content(), which only displays a small portion of the entire content (assuming the main content of the Post is longer than
55 words, the default excerpt length) This might be more appropriate for, say, a loop in the sidebar showing recent posts
4.1.3 The Power of query_posts
A lot of the magic ahead is accomplished by using the query_posts function, which is definitely worth getting to know! To use it properly, you call it before the beginning of the loop, and specify the parameters you need to customize the perfect loop for your scenario
As we learned in section 3.4.3, every execution of the loop is based on a default query that changes according to the type of page being viewed, your settings, and
so on This default query is not set in stone, however, and may be overridden or modified by specifying your own query using the query_posts function
In many cases, you might want to preserve the original query and adjust only certain parts of it To do so, simply call the function using the $query_string
variable and then append additional parameters to the query string, like so:
query_posts($query_string '&showposts=6');
Trang 5Let’s look through some more tasty “recipes” for common things you might want
to do with the loop
4.1.4 Displaying Different Numbers of Posts
There is a global setting in the Admin area for setting the number of Posts to
display On page 48, we talk about a plugin that allows more fine-grained control
for this setting, but you can also control it directly through the loop itself For
example, here we are overriding the default number of posts to display:
query_posts($query_string '&showposts=6');
4.1.5 Excluding Specific Categories
One of the most common customization requests for WordPress is, “how do I
prevent posts in a certain category from displaying on my home page?” Say you
have a category about hamsters that, for whatever reason, you want to omit from
the post loop on your home page You still want hamsters content in your feeds,
just not on your website How would we do something like this?
Although there are multiple ways to handle this request, the simplest solution is to
be found in… yep, you guessed it, the query_posts function:
query_posts($query_string '&cat=-3');
In general, a dash (or minus sign, “-”) appearing before a parameter value signifies
exclusion Thus, here we are excluding category number three, which happens to
be our hamsters category When this code is placed before our loop, posts about
hamsters will not be displayed.
Other possible ways to exclude a category include using PHP’s “continue” function
to advance the loop prematurely, hiding content with CSS or JavaScript, hacking
Overriding Parameters
If the $query_string already contains a parameter (e.g year) you can override it by passing that parameter again after it.
NOT
…on the Home Page.
Trang 64.1.6 Changing the Sort Order
WordPress is sort of a LIFO application by default That is, Last In First Out It’s a smart default, because most blog-like sites like to show off their newest content first This gives people a reason to return since they know the new stuff will be displayed up front and center However, that might not be the ideal configuration for every site
Say you were using WordPress to write and present a novel You were writing it and releasing it chronologically chapter by chapter So when visitors came to your site, you want to show them Chapter One, but that is actually your oldest post, so it will be buried beneath the newer chapters No problem, just reverse the sort order:
query_posts('orderby=date&order=ASC');
4.1.7 Show Specific Pages, Embed a Page within a Page
Another interesting and useful loop trick is to use the query_posts function
to display only one specific Page This could be useful for a variety of reasons, including a situation where you needed to embed the contents of one Page within another Page Here is how to do it:
<?php query_posts('pagename=about'); // retrieves the about page only ?>
4.1.8 Using Multiple Loops
There is nothing holding you to using only one loop You can have as many loops
as you’d like! In fact, it’s fairly common to have multiple loops going in a theme A simple example would be a homepage that shows the full content of the newest three posts But then in the sidebar, there is second loop which shows the title and
date of the next seven posts after that Nothing wrong with it, works just fine.
Let’s look at a more complex example Let’s say we have some fancy four-column
pagename=about
Note that the pagename value
used here refers to the actual
slug for the page See Chapter
2.3.5 for help with slugs.
Trang 7'cat': 7,
'posts_per_page': 3
));
Give me three posts
from category seven
query_posts(array(
'cat': -7, 'posts_per_page': 5 ));
Give me five posts not from
category seven
query_posts(array(
'cat': -7, 'offset': 5, 'posts_per_page': 5 ));
Five more posts not from
category seven (skip five)
query_posts(array(
'cat': -7, 'offset': 10, 'posts_per_page': 10 ));
Ten more posts not from
category seven (skip ten)
“events” category Then we have a main column, split into two, where we display
the ten most recent posts in two columns of five each Then in the right sidebar, we
show another ten posts, beginning after the posts featured in the main column
For this setup, we are going to include four loops within the theme file(s) required
to generate our fancy four-column page For the sake of simplicity, we will say that
all of these loops are contained within our index.php file, even though in practice
the loops could be located in any combination of theme files
Now that our four loops are in place, we need to ensure they are going to deliver
our carefully planned display of posts If we were to simply plop down four default
WordPress loops, our web page would display four columns, each containing
the exact same posts So, to massage our loops into shape, we turn again to the
powerful query_posts function
As shown in the diagram at the top of this page, we add two or three (depending
on the loop) parameters to each of our four query_posts functions These
parameters cause the following behavior:
• The “cat” parameter
Loop 1 - display posts only from category seven
Loop 2 - display posts not from category seven
Loop 3 - display posts not from category seven
Loop 4 - display posts not from category seven
Trang 8• The “posts_per_page” parameter
Loop 1 - display only three posts Loop 2 - display only five posts Loop 3 - display only five posts Loop 4 - display only ten posts
• The “offset” parameter
Loop 1 - (not used) Loop 2 - (not used) Loop 3 - skip the first five posts Loop 4 - skip the first ten posts
At this point, the loops have each been modified to display the desired posts The only other thing to consider before calling it a night is whether or not we want
to display post navigation links for one of our loops In a single-loop setup, we can use the posts_nav_link() template tag to display post navigation links on our home, index, category, and archive pages Such navigation links would enable visitors to check out previous or more recent posts, depending on page view
If we don’t need to display the post-navigation links, such as would be the case in a
“magazine-style” theme, then our work here is finished If, on the other hand, we
do want the navigation links for one of our loops, the query_posts function will be insufficient to get the job done In our current loop setup, query_posts will override the default posts object query, making it impossible for posts_nav_link to show the next series of posts
The key to restoring proper post pagination when using multiple loops is to preserve the paged offset parameter of our default posts query There are several ways to do this, but the easiest is to simply redefine the $posts variable by
appending our custom parameters onto the original query This is done as follows:
<?php $posts = query_posts($query_string.'&cat=-7&posts_per_page=5'); ?>
Now we can restore post pagination by using this new query to replace one of the four query_posts functions currently in place The loop that will be modified by this
WP Page Navigation
For a definitive guide to
WordPress page navigation,
check out Digging into
WordPress:
http://digwp.com/u/401
Multiple & Custom Loops
At Perishable Press, one of my specialties is the WordPress Loop If you are looking for more in-depth information on creating and using multiple & custom loops, scan through the library of articles in the “loop" tag archive:
http://digwp.com/u/402
Trang 9new query is the one that will be equipped to use the navigation links generated
by the posts_nav_link function Because our new query is already set up for our
second, main-left loop, we will go ahead and choose that loop for our navigation
links Thus, after implementing our new query for the second loop, our fancy
four-loop functionality will employ the following code (simplified for clarity):
<?php query_posts('cat=7&posts_per_page=3');
if (have_posts()) : while (have_posts()) : the_post();
the_content();
endwhile; endif; ?>
<?php $posts = query_posts($query_string.'&cat=-7&posts_per_page=5');
if (have_posts()) : while (have_posts()) : the_post();
the_content();
endwhile;
posts_nav_link();
endif; ?>
<?php query_posts('cat=-7&posts_per_page=5&offset=5');
if (have_posts()) : while (have_posts()) : the_post();
the_content();
endwhile; endif; ?>
<?php query_posts('cat=-7&posts_per_page=10&offset=10');
if (have_posts()) : while (have_posts()) : the_post();
the_content();
endwhile; endif; ?>
Now that is a thing of beauty If using this PHP template to implement your own
loops, you will need to use some (X)HMTL and additional template tags to flesh
Loop 1 - Left Sidebar
Normal loop using query_posts
to display only three posts from category seven.
Loop 2 - Main Left
Normal loop using a custom query_posts for the value of the $posts variable Here we are displaying five posts not from category seven, and then including some post navigation using the posts_nav_link tag.
Loop 3 - Right Main
Normal loop using query_ posts to display five more posts not from category seven We also use an offset parameter to avoid post duplication.
Loop 4 - Right Sidebar
Normal loop using query_ posts to display ten more posts not from category seven Again, the offset parameter is used to avoid duplication of posts.
Trang 10things out and display the relevant post information, such as the title, date, author, and so on The key thing is getting the multiple-loop functionality working with page navigation, and this template will take care of you in that department
4.2.1 Sidebars and Footers
Sidebars and footers are such ubiquitous design elements that there are special functions for calling them, just like the header Let’s take an example like this:
Ah, notice the two sidebars? That is an excellent way of presenting lots of information to your visitors Here’s how it’s done…
4.2.2 Multiple Sidebars
The code for creating a layout like the one shown above would look something
Header
Footer
Main Content Left