Watkins Web 3: Blog

Posts tagged with “wordpress”

Starter Kit Structure

I should have posted something like this a few weeks ago, but anyway here’s a chart of the primary templates you’re using for your blog, and the way the includes get pulled in. Remember that there’s no requirement to use PHP includes in this particular way — the code in them could have been inserted directly into their parent templates. It’s just that since the code for “output a post” or “output a link to a post” is the kind of thing you tend to do on multiple templates, it makes sense to consolidate them into the files I’ve called “snippets.”

Finally, you’re of course free to tinker with any and all of the files; this just shows how Starter Kit was structured when you installed it:

Starter Kit diagram

Download Starter Kit

Cheat Sheet: a Wordpress archive page

Here’s a demo of a relatively simple archive page. (You might want to delete the page-archive.php file that came with your theme, since it uses a different function than the one we’ve discussed.

This method uses the function called get_posts(), described in the post about Wordpress Loops to work, you would do the following:

  1. In your theme folder, find page.php, duplicate it, and rename the copy to page-archive.php.
  2. Open the new page.archive.php file in Textwrangler and change the comment at the top to read exactly as it does in the example below. The crucial part is “Template Name: Archive page”, which Wordpress will use to recognize this file as a new page template.
  3. Copy the loop portion of the code below into your page-archge.php, save it, and upload it to your theme directory.
  4. In Wordpress, choose Pages > Add New. Title the new page “Archive” or something similar. In the Page Attributes pane, click the Template pop-up and choose your new template name (“Archive page” or similar). If you don’t see it listed, make sure you matched the comment syntax exactly as in the example below.
  5. Click Publish (or Update) and then View Page to view your archive.

Here’s an example of a straightforward archive template that lists all your posts in reverse chronological order. You can of course use different arguments for get_posts(). Refer to the Wordpress Codex to see how.

<?php
/**
 * Template Name: Archive Page
 *
 * @package WordPress
 * @subpackage My Theme
 */
include('header.php'); ?>
<body id="page">
	<?php include('nav.php'); ?>
	<section id="main" role="main" class="cf">
	<h1>Awesome Archive Page</h1>
	<ul class="post-list">
     <?php 
        // 1. store our loop preferences in an array
        $args = array('numberposts'     => 999, // notice this has to be "numberposts", not "posts_per_page"
       'order'           => 'DESC', // the other option is ASC
       'orderby'         => 'post_date', 
	   '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); ?>    
      <?php include('snippet-post-link.php'); ?>
        <?php endforeach; ?>
        </ul>
<?php include('footer.php'); ?>

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

Cheat Sheet: Wordpress Conditional Functions

As we’ve discussed, Wordpress templates control every page of that template type. For example, if you have three categories — News, Features, and Quick Links — the template category.php is going to control the HTML output that results when visiting all three URLs: http://example.com/category/news/, http://example.com/category/features/, and http://example.com/category/quick-links/. Most likely the only difference between those pages will be the text at the top (<h1>Posts categorized as News</h1> vs. <h1>Posts categorized as Features</h1>) and of course the particular posts that get listed as belonging to the category.

This rigid logic is the default for almost every template including single.php, tag.php, category.php, and search.php. However, Wordpress provides a host of conditional functions that let you check to see whether a particular category/tag/page (etc.) is being displayed. You can therefore output additional content, hide content, alter styling by adding classes, etc. It’s up to you.

Category Conditional

Lets use our “Quick Links” category as an example. Suppose we have written our category.php to display our list of posts in the standard way: we just link each post name to its corresponding permalink page (using the_permalink()) so that visitors can read the whole post by clicking on any of those links.

But suppose our “Quick Links” posts consist only of a post title and custom field called link_url that stores the URL of the external page we are linking to; in other words, Quick Links don’t use the main content field at all, so there’s no particular need to view their permalink pages. For Quick Links, we might want the titles to be linked directly to those external websites. Here’s how we might use the is_category() function inside category.php to alter our code:

<?php  
	<h2>Posts categorized as <strong><?php single_cat_title( '', true ); ?></strong></h2>
	<ul class="post-list">
		<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
			if ( is_category( 'Quick Links' ) ) {
				$link_url = get_post_meta($post->ID, 'link_url', true); ?>
				<li><a href="<?php echo $link_url; ?>"><?php the_title(); ?></a></li>
			<?php }
			else { ?>
				<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
			<?php }
			endwhile; else: ?>
		<p>Sorry, no posts matched your criteria.</p>
		<?php endif; ?>
	</ul> <-- /.post-list -->
?>

More Functions

Here are some other common conditional functions along with some examples:

is_page()

Detects whether the URL being displayed is using the page.php template or shows a particular page:

<?php  	
	if ( is_page( 'About' ) ) {
		echo ("This is the about page.");
	 }
	else {
		echo ("This is not the about page.");
	}
?>

is_single()

Detects whether the URL being displayed is using the single.php template or shows a particular post:

<?php  	
	if ( is_single( '12' ) ) {
		echo ("This is the post that has ID 12.");
	 }
	if ( is_single( 'I love Design' ) ) {
		echo ("This is the post that has the title I Love Design.");
	 }
?>

has_tag()

Detects whether the current post has a particular tag. So probably most useful on single.php.

<?php  	
	if ( has_tag( 'web' ) ) {
		echo ("This post is tagged as web.");
	 }
?>

is_tag()

Detects whether the URL being displayed is using the tag.php template, or is a particular tag page:

<?php  	
	if ( is_tag( 'web' ) ) {
		echo ("Now listing posts tagged as web.");
	 }
?>

Further Reading

Cheat Sheet: Wordpress Custom Fields

Wordpress is primarily for blogging, and so the primary fields associated with a post make sense for blogging: title, date, content, excerpt, featured image, categories, and tags.

But very often we are using Wordpress posts for non-blog purposes, such as a design portfolio, a staff directory, or a calendar. In these cases we have to decide how to make use of the standard blog fields. In a design portfolio, we’d probably use title for the name of the project, content for the project description, featured image for the project photo/screenshot, and perhaps tags for the project media type (print, web, animation, etc.), so that visitors could see all the projects of a certain type. But what if we implement a system like this and find we have additional information that don’t neatly fit into the available fields? This is where custom fields come in.

In Wordpress, choose Posts > Add New and click on Screen Options. Tick the Custom Fields checkbox, close Screen Options, and scroll to the bottom of the Post editing screen. Here you’ll see the Custom Fields pane. This pane allows you to add any number of custom fields, each of which must consist of a field Name and a field Value.

Lets say you’re constructing your web design portfolio and in addition to showing the project screenshot and description, you also want to (a) link to the live URL of the project and (b) credit the people you collaborated with. For each project post, you could just add a new paragraph in your project description that contained the link and credit info. But the problem with this technique is that it embeds this information inside a field where it doesn’t really belong. Suppose you wanted to output this “metadata” into a different <div> than the_content(), or if you change your mind and want to insert it before the description. In both those cases you’d have to edit every post in your Wordpress database in order to update all your markup.

Adding a Custom Field So instead, it makes more sense to store your credits and project URL in individual custom fields. This ensures maximum flexibility: if you redesign your site in a few years and alter your theme files to output different markup, you won’t have to manually edit the contents of every project post.

Outputting all custom fields at once

Wordpress provides a simple function called the_meta() which outputs all of your custom fields names and values, with each field wrapped in a list item of an unordered list:

<?php 
	 the_meta();   
?>

which outputs:

<ul class='post-meta'>
<li><span class='post-meta-key'>project_url:</span> http://joescoffeeshop.com</li>
<li><span class='post-meta-key'>project_credits:</span> Collaboration with Cindy Sherman</li>
</ul>

This is fine if you just want to display the names and contents of your custom fields.

Outputting a particular custom field

Sometimes you need more control over your ouput than the_meta() offers. Lets suppose we want to wrap differnt markup around our two custom fields. First we’ll use we’ll use the get_post_meta() function. to output our project credits into an HTML paragraph with a class attached. (Notice that we first check to see if $project_credits exists — this prevents outputting empty <p> tags if a particular post doesn’t have any content in project_credits.)

<?php 
	$project_credits = get_post_meta($post->ID, 'project_credits', true); // pass in project_credits as a string to retrieve the correct custom value
	if ($project_credits) { 
		echo ("<p class=\"credits\">$project_credits</p>";)
	}
?>

which outputs:

<p class="credits">Collaboration with Cindy Sherman.</p>

We want to treat our project_url field differently: lets wrap it in a <a> tag with the link text “View Project” so that visitors can just click those words to be taken to the live URL. As above, we’ll run get_post_meta() and store the returned value, but this time we’ll wrap different HTML around it. Notice also how we turn PHP off and on (inside the if conditional) to make writing our HTML easier:

<?php 
	$project_url = get_post_meta($post->ID, 'project_url', true); // pass in project_credits as a string to retrieve the correct custom value
	if ($project_url) {
		?>
	<p class="project-link"><a href="<?php echo $project_url; ?>"> Visit Project</a><p>
<?php
	} 
?>

which outputs:

<p class="project-link"<a href="http://joescoffeeshop.com">Visit Project</p>

Further Reading

Cheat Sheet: Wordpress Templates

As discussed in class, the PHP files that make up a Wordpress theme do not represent particular URLs or Posts in your database. Instead, they are templates for various page types. For example, single.php controls all permalink pages. Through the use of the Loop and PHP variables, each permalink page contains different content (pulled from the database), but they are formatted and laid out the same way.

Template Overview

Here’s a quick overview are the most important templates that control your site.

single.php

Controls the layout and content of a single post or “permalink” page like http://example.com/blog/i-love-garamond.

index.php

Controls the home page, but only if you visit Settings > Reading and set Front Page Displays to Your Latest Posts. If instead you set the front page to display a static page, index.php will not be used at all.

category.php

Controls category pages like http://example.com/blog/category/essays-about-design.

tag.php

Controls tag pages like http://example.com/blog/tag/typography.

page.php

Controls Wordpress Pages like http://example.com/blog/about/.

search.php

Controls search results pages like http://example.com/blog/?s=paul+rand.

archive.php

Controls date-based pages (usually) like http://example.com/blog/2012/02. This particular behavior is dependent on your URL choices under Settings > Permalinks.

author.php

Controls author pages like http://example.com/blog/author/jsmith.
Most useful for multi-author sites. Note: “authors” are just the public-facing word for “users” in Wordpress.

Custom Templates and Template Hierarchy

You don’t have to make use of every one of the templates listed above. Wordpress has a built-in feature called the “Template Hierarchy” which means that when certain templates are missing from the theme, others will take over to display your content. A good example is archive.php. While archive.php controls date-based browsing of posts, it will be used for category and tag pages if you are missing a category.php or tag.php file.

A related feature enables you to create additional templates that control a specific Page, Category, Tag, etc. I’m calling these “custom templates.”

Let’s use a custom Page template as an example. Suppose we’ve created a few Wordpress pages that are being displayed on our site: About, Contact, and Colophon. The content for each page is of course determined by the content fields in Wordpress, and the layout and HTML is determined by our page.php template. Suppose page.php is designed with a main column and sidebar to match our blog and portfolio. Now suppose we want to post a new page called Birthday Party that has a single main column and no navigation links. The best method would be to duplicate page.php, rename it to page-birthday.php, and edit it. The first change should be to give it a logical Template Name at the top (this also informs Wordpress that this is different from the regular page.php template):

<?php
	/**
	 * Template Name: My Birthday Page
	 *
	 * @package WordPress
	 * @subpackage Starter Kit
	 */ 
 ?>

Page templates Once we’ve added this new file and uploaded it our theme, it becomes available in the Page Attributes pane for any Page. Once we choose it from the Template pop-up and re-publish the Page, our Birthday Party page will use the new template.

Here’s another example. Suppose we have created blog categories called Features, Essays, and Quick Links. As discussed above, category.php will by default control the category listing pages located at http://example.com/blog/category/features/, http://example.com/blog/category/essays/, and http://example.com/blog/category/quick-links/.

But suppose we want to present Quick Links a little differently. First, we figure out the ID number of the Quick Links category (in Wordpress, click Posts > Categories, hover over the category name and look in your browser’s status bar for the ID). If Quick Links turns out to be Category ID number 3, we could then create a new category template called category-3.php. Once uploaded, http://example.com/blog/category/quick-links/ will immediately start using that template. Unlike pages you don’t need to choose the template from within the Wordpress inteface.

Further Reading

Cheat Sheet: Wordpress Image Handling

As we’ve discussed, Wordpress provides two primary ways to use images on your site. First is the Insert into Post method, where your image becomes part of the flow of the content field: you could conceivably use this method dozens of times in a long post, interspersing your text with images wherever they are most relevant.

The second option is using the Featured Image pane, also known as the Post Thumbnail. By assigning an image to the post as the Featured Image, it becomes a post “attachment”. The disadvantage of this method is that you only get to use one image per post, and you can’t insert it into the middle of your content. But the advantage is you have more flexibility when it comes to layout and image customization. For instance, on an archive page you could show that featured image as a small thumbnail image alongside each post title, but on the permalink page that same image could be output at full size at the top of the content area. You can think of the Featured Image as another database field, like the Post’s Title and Category, that happens to contain an image file.

Custom Sizes: Insert Into Post

When you click Upload/Insert in a Post, you can either upload a new image or choose one from the existing Media Library. Once you’ve uploaded/selected your image, you’ll see the various image settings available to you. (Note: in general you’ll want to set Link URL to “None”, unless you particularly want the image to be linked to its full-size version. The other fields are fairly self-explanatory.)

Scroll down to the four Size options: Thumbnail, Medium, Large, and Full Size:

Insert into Post Sizes

When you upload an image, Wordpress automatically generates these three sizes of thumbnails in addition to storing the original image, and before you click Insert Into Post you can decide which image size is most appropriate.

To change these sizes globally, visit Settings > Media and type in new numbers for Thumbnail Size, Medium Size, and Large Size. Note that only Thumbnail allows for the option to crop the image to exact dimensions — Medium and Large preserve the aspect ratio of the original. When you next use Insert into Post, you’ll find your sizes have been updated.

Custom Sizes: Featured Image

It’s important to understand that the Thumbnail/Medium/Large sizes only affect images inserted into the post content. If you click the Medium size option but then click Set as Featured Image, that does not mean the Medium sized image will be used in your template.

Instead, featured image sizes are controlled by settings stored in your functions.php file. Open functions.php and you’ll how it works. The first two lines just set up the ability to add custom sizes, and you can leave them as they are. But the add_image_size settings allow you to create (and give names to) any number of image sizes, and you can choose whether or not they should be cropped. I recommend avoiding the words “Thumbnail”, “Medium”, and “Large” to avoid confusing them with the standardized names used by Insert Into Post.

<?php	// Images, Thumbnails, Thumbnail sizes
	add_theme_support( 'post-thumbnails' );
    set_post_thumbnail_size( 300, 200 ); // default Post Thumbnail dimensions   
	// Add custom sizes
if ( function_exists( 'add_image_size' ) ) {
	add_image_size( 'huge', 1600, 9999 );
	add_image_size( 'normal', 600, 9999);
	add_image_size( 'mini', 50, 50, true );      // true means cropped
	}
?>

This now means you can run the the_post_thumbnail() function and pass in any of your size keywords as the function paramater (though you probably wouldn’t use them all in a series like this):

<?php 
	the_post_thumbnail('normal');	// outputs normal image size (1600 px wide)
	the_post_thumbnail('huge');		// outputs huge image size (600 px wide)
	the_post_thumbnail('mini'); 	// outputs mini image size (50 px by 50px)
?>

So if you want to change these or add an additional size, just add another line to your functions.php file, upload it to your theme, and that new size should now work in your theme templates.

Regenerating Thumbnails

Remember that Wordpress only generates it’s various image sizes and thumbnails at the moment you upload them. If you upload many images and then later change your custom sizes in Settings > Media or functions.php, you will probably have to regenerate your thumbnail images. Fortunately there’s a plugin, called Regenerate Thumbnails, that lets you do this all in one step. Try installing it and running it from Tools > Regen. Thumbnails.

Further Reading

Cheat Sheet: Wordpress URLs

In non-CMS-powered websites, it’s common to create a bunch of HTML or PHP files that link to each other. To keep things organized, we usually name our files descriptively and bundle them into folders (aka directories). Once we upload them to our web server, they then become available at addresses that reflect these file and folder names.

So depending on the complexity of our site, we might end up with URLs that look like these:

http://example.com/about.html
http://example.com/tutorials/making-a-web-page/
http://example.com/crazy-stuff/interactive-projects/project4/step2.php

The only tricky rule here is that when a URL ends in a slash (like the second example above), most web servers will load index.php or index.html if either exists.

It’s important to recognize that these human-readable (or “clean”) URLs carry important information:

  1. Clean URLs can tell the user the name of the page they are on (e.g. about.html). If a user bookmarks the URL, emails it to a friend, or saves it in a text file for later, they will still have a good idea of what the page contains without having to click on it.
  2. Clean URLs help the user understand the structure of the site: in the second and third examples of the site, the user might even try the shortcut of deleting part of the URL and hitting return, in order to view pages at http://example.com/tutorials/ or http://example.com/crazy-stuff/interactive-projects/.
  3. Clean URLs give search engines like Google a better chance of understanding what content is located at each URL, and probably raising those pages’s rankings for given set of search keywords.

Ugly URLs

On big, database-driven sites, it’s common to see URLs that use unusual characters, coded language, and long strings of characters and numbers:

http://example.com/kb/index.php?cat=8&id=41
http://example.com/?articleID=45434341

Here are some pretty bad real-world examples (my personal favorite is the LinkedIn one, which is what you get when you click on Joe Smith’s name after doing a search).

http://www.amazon.com/Making-Mirrors/dp/B006ZDU7QI/ref=sr_1_1?ie=UTF8&qid=1329151184&sr=8-1 
http://search.yahoo.com/search;_ylt=A0oG7klsOzlPFWYApwBXNyoA;_ylc=X1MDMjc2NjY3OQRfcgMyBGFvAzAEZnIDeWZwLXQtNzAxBGhvc3RwdmlkA3Z3N3ZZa29HN3Y3dlVxbmNUczc3T3dBRFl5MHl2azg1TzJ3QUN4RXUEbl9ncHMDMTAEbl92cHMDMARvcmlnaW4Dc3JwBHF1ZXJ5A2pvZSBzbWl0aARzYW8DMQR2dGVzdGlkA0g0NjU-?p=joe+smith&fr2=sb-top&fr=yfp-t-701
http://www.linkedin.com/profile/view?id=34735695&authType=NAME_SEARCH&authToken=9hD5&locale=en_US&srchid=7a0a9838-fb41-4cf8-9a67-1d74433f4c37-0&srchindex=2&srchtotal=10883&goback=%2Efps_PBCK_joe+smith_*1_*1_*1_*1_*1_*1_*2_*1_Y_*1_*1_*1_false_1_R_*1_*51_*1_*51_true_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2&pvs=ps&trk=pp_profile_name_link

URLs like these are optimized for the databases that control the websites, not for the actual people who need to use those sites. They suffer from poorer Google rankings and aggravate users who have to work with them through common tasks like reading, storing, collecting, bookmarking, copying/pasting, etc.

There’s a reason for the ugliness

Wordpress uses a MYSQL database for storage and displays database content through PHP templates. This means that every time a post or page is displayed, Wordpress is assembling the HTML “on the fly.” There is no collection of static HTML files whose filenames would appear in the URLs — instead, page contents are retrieved through the same GET requests that we used when developing forms last semester.

The URL for a GET request begins with the address of a normal PHP file and is followed by a question mark, a variable name, the equals sign, and the variable contents. For example, a weather page might show different data for different zip codes, and the corresponding URLs might look like this:

http://example.com/showweather.php?location=37204
http://example.com/showweather.php?location=37206

As we saw with PHP forms, this is the way that a single PHP file (showweather.php) can display different outputs. It receives the location variable as part of the URL, uses it in some what to retrieve weather data, and then outputs HTML that is appropriate for that URL.

Wordpress Defaults

The default (and “true” in some sense) URL of a typical Wordpress post looks like one of these:

http://mysite.com/index.php?p=27
http://mysite.com/?p=27

This is in fact very similar to the weather example above: index.php is the PHP file that can access a database and is set up to display different content depending on the variable it receives, while p (which stands for Post) is the variable that will contain the ID number for each post. Because index.php is always the default file shown in a directory, Wordpress usually drops it and just uses the http://mysite.com/?p=27 format.

Clean URLs with Dynamic URL Rewriting

Whenever possible, we want to get rid of the ugly and noninformative default URLs and use “clean” URLs that look more like the simple, old-school, directory-path-leading-to-a-filename format.

Even though we won’t actually be creating directories and files, the web server software Apache has a module called mod_rewrite. The mod_rewrite module is installed on most (but not all) web servers, and it enables the server to generate and recognize human-readable URLS and map them to the correct posts in the Wordpress database.

Wordpress gives us a number of clean URL structures out of the box. Choose Settings > Permalinks and you’ll see them:

Permalink Settings

All except the first count as “clean”. On watkinswebdev.com, which is hosted by Dreamhost, security settings require that once we’ve chosen our structure, we need to edit or create our .htaccess file in the root folder of our Wordpress installation. We’ll go over this in class, but note that if you ever change your Permalink Settings, you’ll need to update the .htaccess file with the new code as well.

The Custom Structure option enables you might to choose your own format. One that I have used often is /%category%/%postname%/. This would result in permalink URLs that looked something like this:

http://watwkinswebdev.com/jschmoe/blog/features/how-i-came-to-love-garamond

If you want to explore other possibilities, take a look at the Wordpress Codex’s page Using Permalinks for the rundown on all the possible variables.

Cheat Sheet: Wordpress Core Functions

Wordpress provides a host of PHP functions that output information store in your database. Here are some of the most common functions and some examples. Much of the information is taken from the Wordpress Codex’s article Stepping Into Template Tags, which you should take a look at.

Functions that Can Go Anywhere

Some of Wordpress’s functions can be used anywhere on the page: in the header or footer, inside a Wordpress loop or outside of it. The function bloginfo() is probably the most common:

bloginfo()

This is a function that takes a keyword as an argument and outputs info about your site, most of which are controlled by the settings under Settings > General. This is best shown through examples:

<?php 
	bloginfo('name'); 					// echoes "James's Blog"
	bloginfo('description');			// echoes "A Website about Design"
	bloginfo('url'); 					// echoes "http://watkinswebdev.com/jmuspratt/demo/"
	bloginfo('template_directory'); 	// echoes "http://watkinswebdev.com/jmuspratt/demo/wp-content/themes/starterkit/"
?>

It’s important to note that in the last two examples, the function outputs a raw URL. If you want to link to the page at that URL, it’s up to you to wrap that URL in a link tag and open and close PHP correctly. So if we want to construct a link that goes to the home page, think about it as three logical steps, working backwards from the output you want to create with PHP:

  1. If you were manually writing a link to the home page, it would look like <a href="http://watkinswebdev.com/jmuspratt/demo/">Visit the home page.</a>
  2. Since bloginfo('url'); only outputs the URL of the blog, you’re going to have to turn PHP on and off inside the quotation marks of the href attribute. In other words, you’ll do something like this: <a href="PHP_GOES_HERE">Visit the home page.</a>
  3. Since you’re starting in HTML, you’ll need to open PHP, output the URL, and then close PHP inside the quotation marks. So the final code should look like this:
<a href="<?php bloginfo('url'); ?>">Visit the home page.</a>

For the complete list of options, visit Wordpress Codex: bloginfo().

Inside the Loop

bloginfo() works outside the loop because its information is consistent no matter what post or page the user is viewing. Since the functions that output the contents of a post obviously do differ from post to post, they must be used inside the Loop. In Starter Kit, you can open single.php and the file snippet-post.php for a good example of what follows below.

the_title()

To echo the title of each post, use the_title(). Note that Wordpress provides a few optional parameters illustrated by the examples below. The first two parameters represent opening and closing HTML tags that Wordpress can add to the title, while the third is a boolean value called “display” which controls whether to echo or return the title. If you override the default TRUE value by specifying FALSE, you can use the function to store the returned value instead of echoing it.

<?php 
	the_title(); 				// echoes "My Blog Post"
	the_title('<h3>', '</h3>'); // echoes "<h3>My Blog Post</h3>"
	the_title('', '', FALSE);	// doesn't echo anything, but RETURNS "My Blog Post"
?>

See also: Wordpress Codex: the_title().

the_permalink()

The permalink is the unique URL given to every post so that it can be bookmarked, emailed, and linked to even if that post falls off the home page’s display of recent posts. Note that the particular style/formatting of the permalink can be globally altered under Settings > Permalinks.

<?php 
	the_permalink(); 	// echoes "http://example.com/news/my-post"
?>

Like bloginfo(), the_permalink() outputs a URL, not a complete hyperlink. It’s therefore common to combine it with the_title() so that you get a meaningful link text linked to each URL:

<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>

which would output:

<a href="http://example.com/news/my-blog-post">My Blog Post</a>

See also: Wordpress Codex: the_permalink().

the_content()

The main editing window in a Wordpress post editing screen isn’t labeled, but it is referred to as the “content” field throughout Wordpress. Remember that Wordpress automatically wraps paragraphs in <p> tags, inserts <br /> tags for soft returns, and may add classes to images that appears in the content field.

<?php 
	the_content(); 			// echoes "<p>Today I had a chicken sandwich.</p>"
?>

If you’re interested in automatically splitting your posts into shorter and longer versions, read up on the “Read More” option in the codex: Wordpress Codex: the_content().

the_date() and the_time()

These two functions are a lot like the native PHP date() and time() functions, but they refer to the date/time that each post was published. You have extensive control over the syntax and formatting by using different letters for the function parameters.

<?php 
	the_date('Y-m-d', '<h2>', '</h2>');		// echoes "<h2>2011-10-12</h2>"
	the_date('F j, Y');						// echoes "October 12, 2011"
	the_date('F j, Y', '<h2>', '</h2>');	// echoes "<h2>October 12, 2011</h2>"
	the_date('F j, Y', '<h2>', '</h2>', FALSE);	// returns "<h2>October 12, 2011</h2>"
	the_time('d/m/Y \a\t g:i A');			// echoes "10/12/2011 at 10:43 AM"
?>

Note: In Starter Kit, I used the_time() instead of the_date() to output the date of each post. The reason: the_date() is designed to be used in long lists of posts (as on an archive page) where multiple posts might have the same date. The default behavior in this situation is to output the date just once for each group of posts that share that date (this way, dates can be used more logically as headings). This can be useful for that particular kind of archive page, but if you really want to output the date for each and every post, you’re forced to use the_time(), which doesn’t have that bug/feature.

See also: Wordpress Codex: the_date(), Wordpress Codex: the_time() and Wordpress Code: Formatting Date and Time.

Bringing It All Together

If you look at the snippet-post.php file, you’ll see something similar to the code below (which is simplified a bit). It illustrates how these core functions can be used inside HTML to output (with PHP) and structure (with HTML tags) a blog post.

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
			<h3><?php the_time('F j, Y');?></h3>
			<h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1>
			<?php the_content(); ?>
		<?php endwhile; ?>
		<?php endif; ?>

For each post, then, this will output something like this:

<h3>October 12, 2011</h3>
<h1><a href="http://example.com/news/my-blog-post">My Blog Post</a></h1>
<p>Today I had a chicken sandwich.</p>

Starter Kit 1.0

Ok, here’s the bare-bones Wordpress theme you’ll be working from.

  1. Download the zip to your machine’s desktop
  2. Log into your Wordpress installation and choose Plugins > Add New
  3. Choose Upload and then Choose File and navigate to the zip on your desktop
  4. Upload the zip file and activate the theme

Download Starter Kit

And here’s a “map” of the way the primary templates use includes:

Starter Kit diagram