I See get_template_part in my WordPress Theme. What’s it For? How Do I Use It?

I have seen quite a few searches come through lately for get_template_part.  Seems like a lot of folks don’t know what it’s for, what it does, or how to use it in their WordPress theme.  When it was introduced with WordPress version 3.0 I wasn’t all that excited.  I didn’t see a need for it.  I was kind of set in my ways.  I liked how I did things.  But after looking into it for a while, I discovered it’s a powerful and useful tool.  Let’s take a look at what it does for you.

First off, what is it?  Simply put, get_template_part is just a way to include another file.  But it’s more powerful than a php include statement, because of its flexibility.  It’s amazingly useful, especially for anyone trying to build a child theme.  So let’s take a look at how it could work for you if you are trying to make a child theme for twentyten first.  If we look at index.php in twentyten, we see:

get_template_part( 'loop', 'index' );

What’s that do?  Well let’s take a look at the structure.  Get template part follows the format of:

get_template_part( $slug, $name );

Where the slug is the generic name of the template being called, and name is the specialized name of the template being called.  So there is an order that WordPress would use to try to find the template to use.  Properly named files in your child theme come first, then files in your parent theme are used.  So using the example above with the generic name ‘loop’ and the specialized name ‘index’ here is the order WordPress would look for files.

  1. wp-content/themes/twentytenchild/loop-index.php
  2. wp-content/themes/twentytenchild/loop.php
  3. wp-content/themes/twentyten/loop-index.php
  4. wp-content/themes/twentyten/loop.php

See how that works?  We look for the specialized template in your child theme.  Then the generic.  Then the specialized name in the parent template.  Finally the generic name in the parent theme.

Now sticking with the twentyten theme. We already know we have this in index.php:

get_template_part( 'loop', 'index' );

And we also can see we have this in archive.php:

get_template_part( 'loop', 'archive' );

So what does it all do?  Well, in a basic twentyten install, there are no specialized templates, nothing named loop-index.php or loop-archive.php, so WordPress simply uses loop.php.  But the power comes in here for you, the child themer!  You could overwrite the loop for the index page or the archive page by creating the specialized named file loop-index.php or loop-archive.php.  For instance, if you only made a loop-index.php, then your file would be used for the main index page.  But since you didn’t make a loop-archive.php, twentyten’s original loop.php file would be used.  You see, you can override either template, without affecting the other.  Now if you made a file called just loop.php in your child theme, with no specialized template, then your loop.php would override twentyten’s for both situations.

Hopefully now you can see the naming conventions. How it all works, and how you can override templates in themes which use get_template_part. It gives you a lot of power when making a child theme. But what if you are making your own theme? How can you use it? Well you could a couple of routes here. In all your files (index.php, archive.php, category.php, etc) You could make a call to get_template_part, and make an individual file for each loop. So index.php would have:

get_template_part( 'loop', 'index' );

And then you would make a file called loop-index.php with the loop in it. You could do that for each file. This now gives anyone trying to make a child theme for your theme a way to override your loops. Or you can do what I like. Use get template part in your theme, but just make a loop.php file and code it to account for everything. I have a giant loop.php which uses a variety of conditional statements to cover all my templates. It handles index, archive, my shop, pages, single view, custom post types, etc. I just built the file up as I added everything. So now I have one big loop, but have given users of my theme the ability to use their own loops with get_template_part.

You can also use get_template_part to call in things besides the loop. For instance I use:

get_template_part( 'icons', 'social' );

to call in a file called icons.php. It’s a big block of code that I use to display social icons under member profiles on my blog. Rather than repeat the code on various templates I just included it. This is nice for me as it allows me to reuse the block of code without actually typing it into each template. Keeps things neat and organized. But it also allows child themers to override it with their own code if they feel the need.

That’s it for this article. Hopefully it helped you understand what that bit of code is doing, and why get_template_part is so useful. Now get to building your own child theme, and have some fun with it!

Additional Post Formats For TwentyTen Child Theme, And Post Formats in General

EDIT: I recently found out a better way to add post formats to a Twenty-Ten child theme, scroll to the bottom of the post to check it out!

As we announced yesterday, WordPress 3.1 was released. Hopefully you have all upgraded by now. If not, get to it. Remember to always keep your install up to date with the latest release. Not just for the cool new features, but for security too. Anyway, if you recently upgraded to 3.1, you may be asking yourself the same question as I see others asking. Where are my post formats? WordPress 3.1 promised lots of different post formats, where are they? Let’s answer that question and tell you how to get them going if you don’t have them.

First thing to realize, post formats are a theme feature. Your theme needs to activate theme. So if you are using the TwentyTen theme, the only post formats available to you are Aside and Gallery (and Standard). But this isn’t too hard to remedy. We’re going to add in post format support for themes in general first. Then we will cover adding additional post formats to a twentyten child theme.

First up, the general stuff. Adding post formats to a theme is very easy to do. First visit the codex entry and decide which ones you would like to add from the available list. It’s simply one line of code added to you functions.php file:

//THEME SUPPORT FOR POST FORMATS
add_theme_support( 'post-formats', array( 'aside', 'chat', 'gallery', 'image', 'link', 'quote', 'status', 'video', 'audio' ) );

You may not need or want them all. Here’s my line of thinking. I activate them all. I can assign posts to them if I want. I don’t have to style them all. But this way they are available. Down the road if I want to style them, my appropriate posts are already assigned to the formats. If I don’t style them, they look like normal posts, so nothing changes. And if I switch to a new theme that has these formats activated and styled, it’s like I planned ahead! Really the ones you activate and use are up to you.

OK, so that was the easy part. Now lets move on to adding additional formats to the twentyten theme by way of a child theme. If you’ve been following along with our customization tutorials so far for twentyten child themes, you know we already have a function set up to customize the header. Mine is called voodoochild_setup in the example, and it runs on after_setup_theme. For some reason just adding in additional post formats to this function doesn’t work. I tried and tried. So we have to do some copying from the twentyten theme here. We need to grab the entire twentyten_setup function from twentyten’s functions.php and copy it to our child theme. So take all this:

function twentyten_setup() {

	// This theme styles the visual editor with editor-style.css to match the theme style.
	add_editor_style();

	// Post Format support. You can also use the legacy "gallery" or "asides" (note the plural) categories.
	add_theme_support( 'post-formats', array( 'aside', 'gallery' ) );

	// This theme uses post thumbnails
	add_theme_support( 'post-thumbnails' );

	// Add default posts and comments RSS feed links to head
	add_theme_support( 'automatic-feed-links' );

	// Make theme available for translation
	// Translations can be filed in the /languages/ directory
	load_theme_textdomain( 'twentyten', TEMPLATEPATH . '/languages' );

	$locale = get_locale();
	$locale_file = TEMPLATEPATH . "/languages/$locale.php";
	if ( is_readable( $locale_file ) )
		require_once( $locale_file );

	// This theme uses wp_nav_menu() in one location.
	register_nav_menus( array(
		'primary' => __( 'Primary Navigation', 'twentyten' ),
	) );

	// This theme allows users to set a custom background
	add_custom_background();

	// Your changeable header business starts here
	if ( ! defined( 'HEADER_TEXTCOLOR' ) )
		define( 'HEADER_TEXTCOLOR', '' );

	// No CSS, just IMG call. The %s is a placeholder for the theme template directory URI.
	if ( ! defined( 'HEADER_IMAGE' ) )
		define( 'HEADER_IMAGE', '%s/images/headers/path.jpg' );

	// The height and width of your custom header. You can hook into the theme's own filters to change these values.
	// Add a filter to twentyten_header_image_width and twentyten_header_image_height to change these values.
	define( 'HEADER_IMAGE_WIDTH', apply_filters( 'twentyten_header_image_width', 940 ) );
	define( 'HEADER_IMAGE_HEIGHT', apply_filters( 'twentyten_header_image_height', 198 ) );

	// We'll be using post thumbnails for custom header images on posts and pages.
	// We want them to be 940 pixels wide by 198 pixels tall.
	// Larger images will be auto-cropped to fit, smaller ones will be ignored. See header.php.
	set_post_thumbnail_size( HEADER_IMAGE_WIDTH, HEADER_IMAGE_HEIGHT, true );

	// Don't support text inside the header image.
	if ( ! defined( 'NO_HEADER_TEXT' ) )
		define( 'NO_HEADER_TEXT', true );

	// Add a way for the custom header to be styled in the admin panel that controls
	// custom headers. See twentyten_admin_header_style(), below.
	add_custom_image_header( '', 'twentyten_admin_header_style' );

	// ... and thus ends the changeable header business.

	// Default custom headers packaged with the theme. %s is a placeholder for the theme template directory URI.
	register_default_headers( array(
		'berries' => array(
			'url' => '%s/images/headers/berries.jpg',
			'thumbnail_url' => '%s/images/headers/berries-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Berries', 'twentyten' )
		),
		'cherryblossom' => array(
			'url' => '%s/images/headers/cherryblossoms.jpg',
			'thumbnail_url' => '%s/images/headers/cherryblossoms-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Cherry Blossoms', 'twentyten' )
		),
		'concave' => array(
			'url' => '%s/images/headers/concave.jpg',
			'thumbnail_url' => '%s/images/headers/concave-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Concave', 'twentyten' )
		),
		'fern' => array(
			'url' => '%s/images/headers/fern.jpg',
			'thumbnail_url' => '%s/images/headers/fern-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Fern', 'twentyten' )
		),
		'forestfloor' => array(
			'url' => '%s/images/headers/forestfloor.jpg',
			'thumbnail_url' => '%s/images/headers/forestfloor-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Forest Floor', 'twentyten' )
		),
		'inkwell' => array(
			'url' => '%s/images/headers/inkwell.jpg',
			'thumbnail_url' => '%s/images/headers/inkwell-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Inkwell', 'twentyten' )
		),
		'path' => array(
			'url' => '%s/images/headers/path.jpg',
			'thumbnail_url' => '%s/images/headers/path-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Path', 'twentyten' )
		),
		'sunset' => array(
			'url' => '%s/images/headers/sunset.jpg',
			'thumbnail_url' => '%s/images/headers/sunset-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Sunset', 'twentyten' )
		)
	) );
}

And paste it into your functions.php in your child theme. I put it above my customized function for modifying the header. I recommend you do the same. Now here’s the thing. This is kind of a pain, since we made our custom function to override portions of this very function we are now placing into our child theme. But, this does give you options. Let’s talk about them.

You can just paste this twentyten_setup function in your child functions.php and edit the post formats portion and leave it at that. Your override custom function you made earlier will continue to work. That’s the route I took. Or you can delete your custom function and make those edits directly in the twentyten_setup now that it is in your child theme. You are able to add your default header image and tweak the sizes directly here. It’s up to you. Like I said I kept my custom function and just tweaked the format line.

To add new post formats, just edit line 7 to add in your own. I’m just going to add in a link post format. Here is my final code in my functions.php with twentyten_setup in place, with my post format added to it, and also with my custom voodoochild_setup in place with our previous customizations.

function twentyten_setup() {

	// This theme styles the visual editor with editor-style.css to match the theme style.
	add_editor_style();

	// Post Format support. You can also use the legacy "gallery" or "asides" (note the plural) categories.
	add_theme_support( 'post-formats', array( 'aside', 'gallery', 'link' ) );

	// This theme uses post thumbnails
	add_theme_support( 'post-thumbnails' );

	// Add default posts and comments RSS feed links to head
	add_theme_support( 'automatic-feed-links' );

	// Make theme available for translation
	// Translations can be filed in the /languages/ directory
	load_theme_textdomain( 'twentyten', TEMPLATEPATH . '/languages' );

	$locale = get_locale();
	$locale_file = TEMPLATEPATH . "/languages/$locale.php";
	if ( is_readable( $locale_file ) )
		require_once( $locale_file );

	// This theme uses wp_nav_menu() in one location.
	register_nav_menus( array(
		'primary' => __( 'Primary Navigation', 'twentyten' ),
	) );

	// This theme allows users to set a custom background
	add_custom_background();

	// Your changeable header business starts here
	if ( ! defined( 'HEADER_TEXTCOLOR' ) )
		define( 'HEADER_TEXTCOLOR', '' );

	// No CSS, just IMG call. The %s is a placeholder for the theme template directory URI.
	if ( ! defined( 'HEADER_IMAGE' ) )
		define( 'HEADER_IMAGE', '%s/images/headers/path.jpg' );

	// The height and width of your custom header. You can hook into the theme's own filters to change these values.
	// Add a filter to twentyten_header_image_width and twentyten_header_image_height to change these values.
	define( 'HEADER_IMAGE_WIDTH', apply_filters( 'twentyten_header_image_width', 940 ) );
	define( 'HEADER_IMAGE_HEIGHT', apply_filters( 'twentyten_header_image_height', 198 ) );

	// We'll be using post thumbnails for custom header images on posts and pages.
	// We want them to be 940 pixels wide by 198 pixels tall.
	// Larger images will be auto-cropped to fit, smaller ones will be ignored. See header.php.
	set_post_thumbnail_size( HEADER_IMAGE_WIDTH, HEADER_IMAGE_HEIGHT, true );

	// Don't support text inside the header image.
	if ( ! defined( 'NO_HEADER_TEXT' ) )
		define( 'NO_HEADER_TEXT', true );

	// Add a way for the custom header to be styled in the admin panel that controls
	// custom headers. See twentyten_admin_header_style(), below.
	add_custom_image_header( '', 'twentyten_admin_header_style' );

	// ... and thus ends the changeable header business.

	// Default custom headers packaged with the theme. %s is a placeholder for the theme template directory URI.
	register_default_headers( array(
		'berries' => array(
			'url' => '%s/images/headers/berries.jpg',
			'thumbnail_url' => '%s/images/headers/berries-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Berries', 'twentyten' )
		),
		'cherryblossom' => array(
			'url' => '%s/images/headers/cherryblossoms.jpg',
			'thumbnail_url' => '%s/images/headers/cherryblossoms-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Cherry Blossoms', 'twentyten' )
		),
		'concave' => array(
			'url' => '%s/images/headers/concave.jpg',
			'thumbnail_url' => '%s/images/headers/concave-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Concave', 'twentyten' )
		),
		'fern' => array(
			'url' => '%s/images/headers/fern.jpg',
			'thumbnail_url' => '%s/images/headers/fern-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Fern', 'twentyten' )
		),
		'forestfloor' => array(
			'url' => '%s/images/headers/forestfloor.jpg',
			'thumbnail_url' => '%s/images/headers/forestfloor-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Forest Floor', 'twentyten' )
		),
		'inkwell' => array(
			'url' => '%s/images/headers/inkwell.jpg',
			'thumbnail_url' => '%s/images/headers/inkwell-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Inkwell', 'twentyten' )
		),
		'path' => array(
			'url' => '%s/images/headers/path.jpg',
			'thumbnail_url' => '%s/images/headers/path-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Path', 'twentyten' )
		),
		'sunset' => array(
			'url' => '%s/images/headers/sunset.jpg',
			'thumbnail_url' => '%s/images/headers/sunset-thumbnail.jpg',
			/* translators: header image description */
			'description' => __( 'Sunset', 'twentyten' )
		)
	) );
}


// VOODOOCHILD SETUP FUNCTION FOR ADJUSTING HEADER STUFF
function voodoochild_setup(){

// OVERRIDE TWENTYTEN HEADER SIZE
define( 'HEADER_IMAGE_WIDTH', apply_filters( 'twentyten_header_image_width', 1010 ) );
define( 'HEADER_IMAGE_HEIGHT', apply_filters( 'twentyten_header_image_height', 228 ) );

// ADD IN OUR CUSTOM HEADER IMAGES TO DEFAULT
    $voodoochild_dir =    get_bloginfo('stylesheet_directory');
    register_default_headers( array (
        'voodoopress' => array (
            'url' => "$voodoochild_dir/images/voodoopress.jpg",
            'thumbnail_url' => "$voodoochild_dir/images/voodoopressthumb.jpg",
            'description' => __( 'VoodooPress Default', 'voodoochild' )
        )

    ));

}

add_action( 'after_setup_theme', 'voodoochild_setup' );

And that’s it. Our customized headers still work, and we have the link post format added. This is the only way I’ve found so far to make this work. If I find something better in the future, we will revisit this issue. Like I’ve stated before, I want to keep my copying and pasting from the parent theme to a minimum and just use actions, filters, or whatever wherever possible.

Don’t forget our article from a while back about organizing your functions.php. One thing you may want to do with that twentyten_setup is put it in its own file, and just include it near the top of your child functions.php.

Of course this only activates the formats. You still have tonnes of options for using/styling them. I have an article on my blog I wrote before starting VoodooPress explaining what I did. But here on this site, I reall only have edited style.css of my child theme to lend some styling to the formats. You have tonnes of options available which are beyond the scope of this particular article.

Whatever you do, play around, have fun, and we’ll tweak some more real soon!

UPDATE: I asked the question over on stack exchange, and I was right. There is a better and less code intensive way to do this. Let’s check it out. First off, we will leave our existing voodoochild_setup function alone. I have experimented with trying to adjust the priority of it, and that makes the existing code fail. So we will leave that alone and make a new code for functions.php:

add_action( 'after_setup_theme', 'voodoochild_formats', 11 );
function voodoochild_formats(){
     add_theme_support( 'post-formats', array( 'aside', 'gallery', 'link' ) );
}

You can see it looks just like the action we added earlier for voodoochild_setup. The only difference is the addition of the number 11. This changes the priority of our function to run after twentyten’s own twentyten_setup, so it overrides it. We can’t change the priority of voodoochild_setup to 11 and have it work though. So we simply have two different actions. But it’s far less code than bringing the entire twentyten_setup on board!

Add a Meta Box to Use Custom Fields on Front End Post Form

So far this week, we have learned how to post from the front end. And we’ve expanded on that by allowing image uploads from the front end. We are going to go one step further today and add a meta box to our form. This way we can use the meta box to gather data and feed it into a custom field so we can use that data. The data can be just about anything, really use your imagination here. I’ll give some examples of stuff I’m thinking of, let’s get into it!

So I’m still going to be working on my wine rating form. My idea is to set up a 5 star type system. I’m going to offer radio checkboxes where the user picks 1-5 stars. The value of that selection will be fed into the custom field, and then depending on what is picked, an image depicting 1-5 stars will be displayed on the rating post. But that is coming soon. Today I will just use a text field that will take a standard text input. You could use this to gather a site url, a sub-title, anything you can think of. Time to get into some code.

The first thing we need to do is set up the text box. Like I said, mine will be to collect a rating. Here’s my form field:

                            <!-- wine Rating -->
                            <fieldset class="winerating">
                                      <label for="winerating">Your Rating</label>
                                      <input type="text" value="" id="winerating" size="60" tabindex="20" name="winerating">
                            </fieldset>

Obviously you can customize this however you want. The main part here is that I’m calling this winerating. We will be using that in the rest of the code to gather our data and feed it into a custom field. Next up we need to tweak our existing processing code to handle the custom field. Remember I’m working on the form we set up here and here, if your’s is different, you’ll have to accomodate that.

So back on our form, the top bit of code looks like:

// Do some minor form validation to make sure there is content
if (isset ($_POST['title'])) {
        $title =  $_POST['title'];
	} else {
        echo 'Please enter the wine name';
	}
if (isset ($_POST['description'])) {
        $description = $_POST['description'];
	} else {
        echo 'Please enter some notes';
	}
$tags = $_POST['post_tags'];

And I added in my new form field to a variable, which you’ll recall is winerating. I just added it after the last line above, like this:

$tags = $_POST['post_tags'];
$winerating = $_POST['winerating'];

Next up, I tweaked our existing array which looked like this:

// Add the content of the form to $post as an array
$new_post = array(
        'post_title'    => $title,
        'post_content'  => $description,
        'post_category' => array($_POST['cat']),  // Usable for custom taxonomies too
        'tags_input'    => array($tags),
        'post_status'   => 'publish',           // Choose: publish, preview, future, draft, etc.
        'post_type' => 'post'  //'post',page' or use a custom post type if you want to
);

Again right at the bottom I added my code. Don’t forget to add a comma to ‘post’ when adding a new line. So the bottom of that now looks like: This step is not necessary, I’ll explain after the code.

        'post_type' => 'post',  //'post',page' or use a custom post type if you want to
	'winerating' => $winerating
);

When I wrote this tutorial, I didn’t have a full understanding of how everything fit together. I got it working and was happy with that. But here’s one update. This particular step is unnecessary, it doesn’t do a thing! What we can add into the array are parameters used by wp_insert_post. Anything else doesn’t do anything! The rest of this tut works great, I just wanted to update this one misunderstanding I had.

And finally, just after the wp_insert_post line we add some code. If you followed yesterdays tutorial about adding images, I put this line of code after the wp_insert_post and above the foreach loop for the images. Here’s the existing code with the new line added for our meta box.

//save the new post
$pid = wp_insert_post($new_post);

add_post_meta($pid, 'rating', $winerating, true);

And that is all the code you need! Notice in the add_post_meta line above, the second parameter is rating. That is what we call to display our meta box/custom field value. So to display the value in your theme somewhere you just use:

<div class="wineRating">
<?php if( get_post_meta($post->ID, "rating", true) ): ?>
<?php echo get_post_meta($post->ID, "rating", true); ?>
<?php endif; ?>
</div>

There you have it. Now that you have the basics all figured out, you can make a front-end post form, you can allow image uploads, and now you can use meta boxes to gather and display all sorts of other information. Time to go make some sort of fancy post form. Let me know what you come up with!

Tomorrow I will do a quick recap of the past three tutorials, and display my full code for this post form page template from top to bottom for review.

Working With Featured Image in WordPress

I had a request from a reader here on VoodooPress to look into featured image sizes. Recently we had a series of posts on here about posting from the front end, and allowing users to upload their own picture. We even showed you how to set the user uploaded picture as a featured image. Let’s take a deeper look at using the featured images. Maybe assign different sizes to different templates. You don’t have to use this just for user uploaded photos of course. This information is useful for the featured image in general, whether you let users upload them, or you set them in the back end.

You can see an example of this in action on my blog, www.rvoodoo.com. On standard format posts, I use the featured image in a variety of ways. Once it is set, it is used as a small icon next to the post title. It is also used as a larger thumbnail in the body of the post. And if you click through to the single post view, we use a much larger featured image in the post. So let’s go over a variety of things that can be done with the thumbnails.

One thing to note, you may notice when I talk about the featured image, I sometimes also call it just the thumbnail. Please don’t get confused. When the feature was first added to WordPress in version 2.9, it was called the thumbnail. The code for the image refers to it as the thumbnail. Later on the name was changed to featured image. So I am really referring to the same thing. Featured image/thumbnail, whatever you call it, let’s do some work.

If you haven’t read this excellent article, give it a read. It pretty much covers everything I’m going to cover here. That is the article I used to learn how to work with the featured images.

Anyway, the first thing to know is how to turn them on. Featured images don’t just work out of the box on WordPress, the theme must support them. Hopefully by now, pretty much every theme has them. But if yours doesn’t here’s how to fix that:

add_theme_support( 'post-thumbnails' );

That’s it. Add that line to functions.php, and you have thumbnail support! Easy right? Now let’s look at adding the default size. This is the size that will be used if you just call the_post_thumbnail (we’ll get into that in a moment) with no image name.

set_post_thumbnail_size( 75, 75, true );

That right there defines my default thumbnail size as 75 x 75 pixels. The true refers to the crop mode. It can basically be set to true, or left off (which makes it false). To understand the cropping mode a bit better, you can check out what Mark Jaquith has to say on this post, another excellent resource for using featured images.

So now we have turned on the featured image, and we’ve set the default thumbnail size. What if we want more image sizes? Let’s add one:

add_image_size( 'title-image', 50, 27 );

That’s all you need to do. You are now able to call that image size by ‘title-image’ in your theme. You can repeat that as much as you need with different names to add a variety of image sizes to use all over your theme. Here’s what I have over on www.rvoodoo.com for featured images:

	add_theme_support( 'post-thumbnails' );
	set_post_thumbnail_size( 75, 75, true ); // default post thumbnails
	add_image_size( 'index-post-thumb', 75, 75 );
	add_image_size( 'single-post-thumbnail', 150, 150, true ); // Permalink thumbnail size
	add_image_size( 'title-image', 50, 27 ); // Title mini photo
	add_image_size( 'shop-single-image', 700, 999 ); //Shop Single Product Image
	add_image_size( 'member-thumb', 205, 100, true ); // Member Page Image

You can see I have the featured images turned on. I set the default at 75 x 75. I then added on five additional image sizes to use all over my theme. Pretty handy I say!

Now, for a lot of my VoodooPress readers, you are probably using a child theme of twentyten. What then? Featured images are already turned on, and the default image size is set, and being used for a header. What if you want to add more image sizes to a child theme? Well I just add them onto theme setup. If you recall this post, we made our own function called voodoochild_setup which runs on after setup theme. If you have that function, you can drop your add image size in there. That’s how I’ve done it on VoodooPress. If you didn’t follow that, here’s a function for your twentyten child theme that will add image sizes.

// VOODOOCHILD FUNCTION FOR ADDING IMAGE SIZES
function voodoochild_image_sizes(){

add_image_size ( 'admin-thumb', 100, 60, true );
add_image_size( 'single-post-thumbnail', 150, 150, true ); // Permalink thumbnail size
add_image_size( 'title-image', 50, 27 ); // Title mini photo

}

add_action( 'after_setup_theme', 'voodoochild_image_sizes' );

And you just keep on adding whatever sizes you need to that. OK, there’s all the info you should need for adding image sizes. If you followed along earlier and are allowing user uploaded images, now when an image is uploaded, all the sizes you define in functions.php are available for use throughout your theme. Same thing even if you aren’t allowing user uploads. You can set a featured image in the backend, and all the sizes you define are available. Let’s take a look at how to use the images now to actually display them.

The most basic code is this:

<?php the_post_thumbnail(); ?>

How easy is that? That bit of code will call your default thumbnail size. So if you added your own thumbnail support, it’s whatever is defined here:

set_post_thumbnail_size( 75, 75, true );

OK, that’s the default size, lets use our other sizes. You simply drop in whatever you named the image in your add image size code above. So if we have:

add_image_size( 'archive-image', 150, 150, true );

then to display that image size we use:

<?php the_post_thumbnail( 'archive-image' ); ?>

And we just do that over and over for any image size. The code works in pairs. You use add_image_size in functions.php with an image name to define the image size, and then in your template where you want to use the image, you use the_post_thumbnail with the same image name. Pretty simple right? You can use a variety of sizes all over the place now. Just define them in your functions.php, and the call them in your templates.

Let’s look at a few more tricks just for fun.

Maybe we want to display a default image if no thumbnail is set. We can use a conditional for that. Here’s a sample:

	<?php if( has_post_thumbnail() ) : ?>
		<?php the_post_thumbnail(); ?>

	<?php else : ?>
		<img src="<?php bloginfo( 'stylesheet_directory' );?>/images/sample.jpg" alt="Default Icon" title="Default Icon" />
	<?php endif; ?>

That says if there is a thumbnail, use it. If not display the image named sample.jpg in the images directory of my theme.

What if we want the image to link to the article? I use this on any thumbnail I have on my index.php to link to the article.

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

You can also add classes to the image of course for styling and whatnot:

<!-- DISPLAY IMAGE WITH CLASS AND ALT -->
<?php the_post_thumbnail( 'thumbnail', array( 'class' => 'class', 'alt' => 'Title' ) ); ?>

And here is another neat trick, good for single.php. I use a lightbox plugin, which needs the rel=”lightbox” added to my images to be able to display them. And I need to link the image to it’s large version. This code does both:

					<a rel="lightbox" href="<?php $image_id = get_post_thumbnail_id();
					$image_url = wp_get_attachment_image_src($image_id,'large', true);
					echo $image_url[0];  ?>">
					<?php the_post_thumbnail('thumbnail'); ?>
					</a>

Even if you don’t use a light box plugin, you may want the image linked to a certain version of the original image. Line 2 here, where I have ‘large’ is the size of the link target image you want the link to go to. Line 4 is the displayed featured image size, you could swap out ‘thumbnail’ for whatever image size you want to use which you have defined in your functions.php with add_image_size.

So that’s a whole bunch of information about working with the_post_thumbnail. I hope this helps some of you. If I forgot anything, or you want to know even more, I’m always open to comments!

How to Post From Your Front End With No Plugin

Lately I’ve been working on another side project. A wine rating site that we hope to launch soon. But one of the requirements for the site was that once a wine rater logged in, they should have access to a form to rate wines. I didn’t want anyone to have to fuss with the back end of WordPress. I just wanted to present them with a simple form to fill out. Let’s look into how that’s done.

The first thing you need to figure out is the details. Sketch out your form, what types of data do you need? Is it just normal post stuff (title, post, categories, keywords), or do you need more? You can use custom fields/meta boxes from the front end. You can also allow thumbnail uploads to set as the featured image, or multiple image uploads. Today we will just look at the basic stuff. Tomorrow we will add image uploads.

After you have your form all filled out you need to figure out some more details. Since the main focus of my site is going to be wine rating, I want to use the standard post as wine rating. I will also use the standard categories to present a dropdown of wine types. And I will use the normal tagging system to allow for keywords. You can follow the same setup, or you can register a new post type, and use custom taxonomies, these things would only require some simple changes in the code I’ll give you, and I’ll point them out.

Now that we have all the details figured out, we need to get into the code. I set up a simple page template first. Now since this is just another form really, I borrowed heavily from my own article here about Contact Form 7. You’ll see a few blocks of code down a setup for a simple page template, it looks like:

<?php
/*
Template Name: Wine Rating Form
*/
get_header(); ?>

        <div id="container">
            <div id="content" role="main">

<?php if ( have_posts() ) while ( have_posts() ) : the_post(); ?>

                <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                    <?php if ( is_front_page() ) { ?>
                        <h2 class="entry-title"><?php the_title(); ?></h2>
                    <?php } else { ?>
                        <h1 class="entry-title"><?php the_title(); ?></h1>
                    <?php } ?>

                    <div class="form-content">
                        <?php the_content(); ?>
                        <?php wp_link_pages( array( 'before' => '<div class="page-link">' . __( 'Pages:', 'twentyten' ), 'after' => '</div>' ) ); ?>
                        <?php edit_post_link( __( 'Edit', 'twentyten' ), '<span class="edit-link">', '</span>' ); ?>
                    </div><!-- .entry-content -->
                </div><!-- #post-## -->

                <?php comments_template( '', true ); ?>

<?php endwhile; // end of the loop. ?>

            </div><!-- #content -->
        </div><!-- #container -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>

You’ll see that the template is the same as on the example in the previous post, except I change the name to Wine Rating Form in the header of the code. So save that as whatever you like, I called it ratewine.php. You’ll see a call to the_content on line 20. I’m going to put my new form directly under that. You can do the same, or you can delete the_content, it’s up to you. I left it in as I may decide later to add some instructions through the normal WP page interface.

You’ll also notice that on line 19, I have div class=form-content rather than the normal entry-content from twenty ten. That is just to avoid having twenty ten’s css play too much on our form. That is explained in this article as well.

Let’s add in our form now! Again looking at the article from before you can see how I like to lay out my forms. I’m going to follow the same format here:

		<!-- WINE RATING FORM -->

		<div class="wpcf7">
		<form id="new_post" name="new_post" method="post" action="" class="wpcf7-form" enctype="multipart/form-data">
			<!-- post name -->
			<fieldset name="name">
				<label for="title">Wine Name:</label>
				<input type="text" id="title" value="" tabindex="5" name="title" />
			</fieldset>

			<!-- post Category -->
			<fieldset class="category">
				<label for="cat">Type:</label>
				<?php wp_dropdown_categories( 'tab_index=10&taxonomy=category&hide_empty=0' ); ?>
			</fieldset>

			<!-- post Content -->
			<fieldset class="content">
				<label for="description">Description and Notes:</label>
				<textarea id="description" tabindex="15" name="description" cols="80" rows="10"></textarea>
			</fieldset>

			<!-- post tags -->
			<fieldset class="tags">
				<label for="post_tags">Additional Keywords (comma separated):</label>
				<input type="text" value="" tabindex="35" name="post_tags" id="post_tags" />
			</fieldset>

			<fieldset class="submit">
				<input type="submit" value="Post Review" tabindex="40" id="submit" name="submit" />
			</fieldset>

			<input type="hidden" name="action" value="new_post" />
			<?php wp_nonce_field( 'new-post' ); ?>
		</form>
		</div> <!-- END WPCF7 -->

You’ll notice I have some tags in there that come from Contact Form 7. we wrap the form in a wpcf7 class, and apply the wpcf7-form class to the actual form. This is not required of course. I just did it because I already have css in place from this tutorial. If I apply the same classes, I can reuse the css with no edits. Keep things simple eh!

The important part is to make sure the name and ID on these inputs match up with what I have. That is because we are using standard inputs. These will save to specific values that go to your database from the block of code I’m about to give you. You will also notice the second block makes use of wp_dropdown_categories, I like the idea of giving a list of categories here, since my cats are wine types. This is one place you could swap in a custom taxonomy. And finally at the bottom you’ll notice a little use of wp_nonce_field again, just a simple verification on where the data is coming from.

So that has our form all built. If you saved it now, and then applied this template to a page you would have your post form. Depending on if you followed this tutorial before, it may or may not be styled. But the big thing you would notice is that the form doesn’t do anything! You can fill it out for sure, but the data does nothing. Let’s fix that!

Way at the top of our template, under the page template header, but above the get_header call, we are going to put some code.

if( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] ) &&  $_POST['action'] == "new_post") {

	// Do some minor form validation to make sure there is content
	if (isset ($_POST['title'])) {
		$title =  $_POST['title'];
	} else {
		echo 'Please enter the wine name';
	}
	if (isset ($_POST['description'])) {
		$description = $_POST['description'];
	} else {
		echo 'Please enter some notes';
	}

	$tags = $_POST['post_tags'];

	// ADD THE FORM INPUT TO $new_post ARRAY
	$new_post = array(
	'post_title'	=>	$title,
	'post_content'	=>	$description,
	'post_category'	=>	array($_POST['cat']),  // Usable for custom taxonomies too
	'tags_input'	=>	array($tags),
	'post_status'	=>	'publish',           // Choose: publish, preview, future, draft, etc.
	'post_type'	=>	'post'  //'post',page' or use a custom post type if you want to
	);

	//SAVE THE POST
	$pid = wp_insert_post($new_post);

             //SET OUR TAGS UP PROPERLY
	wp_set_post_tags($pid, $_POST['post_tags']);

	//REDIRECT TO THE NEW POST ON SAVE
	$link = get_permalink( $pid );
	wp_redirect( $link );

} // END THE IF STATEMENT THAT STARTED THE WHOLE FORM

//POST THE POST YO
do_action('wp_insert_post', 'wp_insert_post');

Up at the top are some instruction to WordPress to use this as a post, and we set up new_post which is what our nonce_field verifies against. After that we do some validation. Just some basic fields we want to require. And then we set up the array which grabs the data from our form and puts it all together to insert into the WordPress database. The wp_redirect line is optional, this redirects the user to their new post once they hit submit. This works great on a wine rating site I thought, take the user right to their post. (redirect threw errors, working on it) I have update the above code again. Everything works splendidly. The redirect block of code is optional or can be edited to redirect where you would like.

I’ve tried to mark with comments in the code where custom post types and custom taxonomies can be swapped out. But that pretty well does it! With this code you can have your own front end post form.

If your form isn’t styled, just take a look at this post, it has the styling I use for Contact Form 7, which if you set up your form using the layout I did above, it will work for this form as well.

Now just save up this page template to your theme and apply it to a page, and you have a post from the front end form available to your users! You probably don’t want this available to just anyone, I keep the access restricted to authors and above on my site.

Notes For Multi Category Select:I haven’t had time to totally sort this out yet, but I’m posting it here for info.
If you replace the wp_dropdown_categories line with this:

		<?php $select_cats = wp_dropdown_categories( array( 'echo' => 0, 'taxonomy' => 'category', 'hide_empty' => 0 ) );
		$select_cats = str_replace( "name='cat' id=", "name='cat[]' multiple='multiple' id=", $select_cats );
		echo $select_cats; ?>

It will allow for multiple category select. However, something needs done with the processing code above to allow that array to be handled.

Around line 16 (of the processing code), where we set up the post tags, I have this

$post_cat = $_POST['cat'];

And then in the array, I replaced the post category line with this

'post_category' =>   $post_cat,

And that was it, I am now able to select and save multiple categories!

UPDATE: If you check out this post, the end review of this form, down at the bottom we have an update with a possible fix to get the validation working properly. If you have a chance to try the fix out and report back if it works, that would be awesome!

UPDATE(2): If you cruise around the site, and search a little, you’ll find that there are a whole variety of posts related to this frontend post form. But here is a couple valuable links – our great VoodooPress readers have been busy! One of our readers provided his technique for editing and deleting these posts from the front end. Another reader got validation working and provided us with that code! That’s a lot of cool stuff! If you have anything to add here, feel free to submit your stuff, or even ask about a guest post! We are well on our way to posting perfection!