Watkins Web 3: Blog

Cheat Sheet: Wordpress Loops

The default Loop

Most of the built-in Wordpress templates are set up so that they automatically retrieve and prepare a particular group of posts for output: For example, tag.php will retrieve all posts tagged as “nashville” when the user visits http://example.com/tag/nashville. To access and output these posts, you put your post functions (the_title(), the_content(), etc.) inside a series of nested if/while/the_post statements that look like this:

<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
	<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
	<?php the_content(); ?>
	<?php endwhile; else: ?>
		<p>Sorry, no posts found.</p>
	<?php endif; ?>

When the page loads, Wordpress retrieves all the posts tagged as “nashville”, then outputs the post content according to your formatting inside the loop statement above. This exact code can be used on all of the common templates (index.php, page.php, category.php, tag.php, and single.php).

The key thing to remember is that when you use the default Loop, you can’t see the database query. Wordpress has already made the query based on information in the URL. This makes some intuitive sense: since the if/while/the_post() conditions are accessing a database query that has already occurred, it must have come from the template type itself, not from any particular PHP in your template.

Using get_posts()

In anything but the simplest site, you’ll occasionally want to display post content or links outside of the default Loops. To do so, you need to (1) store your query preferences in an array, (2) run a database query function called get_posts() to retreive the posts, and (3) access the results with an additional loop.

Let’s suppose we have a regular template set up, but we want to add an unordered list of links that contains the 5 most recent posts in the “News” category. Since this will go in our home page sidebar, we open up index.php and add our code in the appropriate <div> or <section> there.

To review, we’ll use get_posts() outside of the default loop using these three steps:

  1. Store our database query preferences in an array called $args
  2. Pass $args into get_posts() and store the returned result in $myposts
  3. Run a foreach loop on $myposts to access the content of each post in turn.
<h2>Recent News</h2>
		<ul id="recent-news">
		<?php 
		// 1. store our loop preferences in an array
		$args = array(
		'numberposts'     => 5, // notice this has to be "numberposts", not "posts_per_page"
		'category'        => '4', // FEATURES category
		'orderby'         => 'post_date', 
		'order'           => 'DESC', // the other option is ASC
		'post_type'       => 'post',
		'post_status'     => 'publish' 
		);
		// 2. Run get_posts() on the $args array and store the result in $myposts  
		$myposts = get_posts( $args );
		// 3. Run a foreach loop on $myposts to access our content, combined with the annoying-but-necessary setup_postdata function.
		foreach( $myposts as $post ) :	setup_postdata($post); ?>
			<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
		<?php endforeach; ?>
		</ul>

Using wp_query()

This is the nuclear option, useful for those occasions where you need to create multiple loops and control every aspect of them. It requires some object-oriented syntax (notice the resreed keyword “new” used before wp_query), which we haven’t covered, but you can often get far by copying and pasting examples from the web.

Here’s an example:

<?php
		// Create two queries and store them in different variables
		$featured_query_ = new wp_query('category_name=featured', 'posts_per_page=5','order=DESC');
		$news_query = new wp_query('category_name=news', 'posts_per_page=5','order=DESC');
		?>
		<h2>Recent Featured Posts</h2>
		<ul>
		<?php while ( $featured_query_->have_posts() ) : $featured_query_->the_post();
		?> 
			<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
		<?php endwhile;	?>
		</ul>
		<h2>Recent News</h2>
		<ul>
		<?php while ( $news_query->have_posts() ) : $news_query->the_post();
		?> 
			<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
		<?php endwhile;	?>
		</ul>

Further Reading

Cheat Sheet: Wordpress link-listing functions

One of the benefits of using a CMS like Wordpress is the ability to build navigation links dynamically in addition to displaying content (like blog posts) dynamically. With dynamic navigation, adding something like a page or category in your Wordpress control panel will do two things: (1) as expected, it will publish that new content and make it available at a URL, and (2) it will add a hyperlink to your navigation that links to that new URL.

wp_list_pages()

The Starter Kit theme is already using wp_list_pages() (look inside nav.php). Like many PHP functions, wp_list_pages() accepts a number of arguments that you can specify to control the output. What may be new to you is that rather than accept these paramaters as a series of comma-separated values, the function requires an associative array. Often we store this array in a variable called $args, then pass it in when we run the function. Here’s the canonical example showing some of the most common options:

<?php
// store our options in an associative array called $args
// this is a regular associative array -- the line breaks just make it easier to read
 $args = array(
 	'depth'        => 0,
	'show_date'    => '',
	'date_format'  => get_option('date_format'),
	'child_of'     => 0,
	'exclude'      => '3,5' // don't list pages with IDs 3 and 5
	'include'      => '',
	'title_li'     => '', // you must specify an empty string like this to keep Wordpress from inseting "Pages: " before your list. annyoing. 
	'echo'         => 1,
	'authors'      => '',
	'sort_column'  => 'menu_order, post_title', //we can control the output order by editing Page Attributes > Order in each page. Or we could just set this as post_title and have it sort alphabetically
	'link_before'  => '',
	'link_after'   => '',
	'walker'       => '' ); 
	// now run the function, passing in $args as the argument
	// Wordpress will wrap each link in an <li> tag and attach a bunch of classes (which it thinks might be useful to each <li>)
	wp_list_pages($args);
	?>

Note that all of these values have defaults set, and so you can safely leave them out of your arguments array if you don’t need to alter them (this is the advantage of collecting all the options in an associative array). Check out the defaults by reading about wp_list_pages in the Wordpress Codex.

Here’s some example output that wp_list_pages() might produce:

<li class="page_item page-item-126"><a href="http://example.com/new-page/">New page</a></li>
<li class="page_item page-item-5"><a href="http://example.com/about/">About</a></li>
<li class="page_item page-item-7"><a href="http://example.com/contact/">Contact</a></li>
<li class="page_item page-item-30"><a href="http://example.com/colophon/">Colophon</a></li>

Since this is just a series of <li> tasg with links inside them, it’s up to you to make sure you wrap them in a <ul> and perhaps a <nav> tag in your template.

wp_list_categories()

As we reviewed last class, category pages are those pages that looks omething like http://example.com/category/news and are controlled by the category.php file.

Like wp_list_pages(), wp_list_categories() simply outputs links. It’s without having to write them manually. If in the future you add a category to your blog, wp_list_categories() will update accordingly.

Here’s an example with some of the common options in use:

			$args = array(
			   'show_option_all'    => '',
		       'orderby'            => 'name',
		       'order'              => 'ASC',
		       'show_last_update'   => 0,
		       'style'              => 'list', // setting to 'none' would list them without li tags but with <br /> tags  after each one
		       'show_count'         => 1, // lets show the number of posts in each category
		       'hide_empty'         => 1,
		       'use_desc_for_title' => 1,
		       'child_of'           => 0,
		       'exclude'            => '',
		       'include'            => '',
		       'hierarchical'       => false, // don't list sub-categories
		       'title_li'           => '', // no heading please
		       'show_option_none'   => '',
		       'echo'               => 1,
		       'depth'              => 0,
		       'current_category'   => 0,
		       'pad_counts'         => 0 );
			   // no run the function
			   wp_list_categories( $args );

This might produce output like this:

<li class="cat-item cat-item-8"><a href="http://watkinswebdev.com/jmuspratt/demo/category/essays/" title="Longer format writing on design, the web, and pineapples.">Essays</a> (2)</li>
<li class="cat-item cat-item-1"><a href="http://watkinswebdev.com/jmuspratt/demo/category/news/" title="Short updates on current events.">News</a> (12)</li>
<li class="cat-item cat-item-10"><a href="http://watkinswebdev.com/jmuspratt/demo/category/quick-links/" title="View all posts filed under Quick Links">Quick Links</a> (2)</li>

Once again, make sure that this output is wrapped in <ul> tags to keep your HTML valid.

Further Reading

Cheat Sheet: Wordpress excerpts

It’s common on blogs that post long articles to store a shorter or excerpted portion of the post in the database — this excerpt can then be used where many posts are listed on a page. If a viewer wants to read the whole post, they can click into the permalink version to see it. There are at least two ways to do this kind of thing in Wordpress:

Using Excerpts

Create a new post and make sure the Excerpt field is visible (check Screen Options if you don’t see it). Try writing a long post in the main Content field and a shorter summary in the Excerpt field.

Now you can insert the_excerpt into your template. However, you may want to combine it with a conditional to control which pages show excerpts and which show the full content. Here’s an example

<?php 
if ( is_single() ) { 	// test to see if we're on a permalink page
	the_content();		// show the post content
		} else {		// but otherwise (home page, category page, tag page, archive page)
		the_excerpt(); 	// just show the excerpt
	} ?>

But sometimes you’re using the Excerpt field in your post for some other purpose. In this case, the default usage can backfire.

Using the more divider

more icon Try another test: leave your Excerpt empty but write a longish post in the Content area. Now put your cursor between two paragraphs. Find the more button in the editing toolbar (shown at left) and click it to insert the more divider.

This now divides your post: the part above more is the excerpt, while the entire post is your content.

The Excerpt Gotcha

Wordpress tries to be a little too helpful sometimes. If you leave the Excerpt field empty, and your template calls the_excerpt() function, Wordpress will auto-generate an excerpt from the first 55 words of your Content and tack on an ellipsis (…) at the end.

So if you don’t want this behavior, and you literally want to grab the contents of the Excerpt field (even if it’s empty), use the object-oriented version like this:

echo $post->post_excerpt; // like the_excerpt() except it will (logically) output nothing if the Excerpt field is empty.

Further Reading

Kelsey Show & Tell

The first site We Heart was done in HTML 5. I really liked the format of the different sized boxes across the page and the clean typefaces.

This second site Gallery of Mo, intrigued me because of all the illustration used and how it was executed really well without being too busy.

Nathan Ford's portfolio, is one I mainly like because of the hand done navigation and headlines. It's something similar that I want for my own blog for project 1.

Jill's Show and Tell

The first site I shared is a site that is a combo blog and work projects site by a design group calling themselves The Church of London. It was created using wordpress and I really like the clean, well-organized layout. The next site that I shared, I was not too crazy about but I did like the way that the navigation to the next and previous posts are being handled. They are over to the top right and have images as the buttons. This is the site was created by a group that gathers up all the latest developments in design, fashion, etc. and posts it all on one site as a reference for other designers and is called Cool Hunting. The third site that I shared I really like. It si very clean and well-organized with a definite hierarchy of information. Unfortunately it uses flash to accomplish the dynamic pieces of the site. It is the site of an architectural firm called Gensler.