WordPress Custom Post and Custom Taxonomy Permalinks

I have the following setup:
– A custom post type called Products.
– A custom taxonomy called Product Categories.
– A page called Products with a custom page template assigned to it. This page template allows me to query my custom posts and display them in a layout of my choosing. Slug is set to /products.

I wanted my urls for my products to display in the following way:

Or to be more specific:
– View my “Products” page set with the custom template at the url /products
– View each “Product Category” on a url of /products/product-category
– View my custom post type “Products” on a url of /products/product-category/product-name

But nothings ever easy. The trouble I was having was that both my product page and product post type wanted to use the same slug (/products) and therefore conflicted causing 404’s. Not only that but custom taxonomies by default do not show the category in the url, and finally although in my head it made sense as a user to see the url /products/product-category/product-name they were not in any kind of heirarchical structure within wordpress to order them in a url this way.

So after a lot of googling and after finding this really helpful article I finally managed to put together some code that fixed the problem.

add_action( 'init', 'register_custom_post_types' );
//Set up Product Post Type
function register_custom_post_types() {
	register_post_type('products', array(
		'label' => __('Products'),
		'singular_label' => __('Product'),
		'public' => true,
		'show_ui' => true,
		'capability_type' => 'post',
		'hierarchical' => true,
		'rewrite' => array( 'slug' => 'products/%productcats%' ),
		'publicly_queryable' => true,
		'query_var' => true,
		'has_archive' => true,
		'supports' => array('title','editor','thumbnail','excerpt'),
        //Set up Product Categories
	register_taxonomy('productcats', 'products', array(
		'hierarchical' => true,
		'label' => 'Categories',
		'singular_label' => 'Category',
		'rewrite' => array( 'slug' => 'products' ),
//Fix Permalinks
add_filter('post_link', 'product_permalink', 10, 3);
add_filter('post_type_link', 'product_permalink', 10, 3);
function product_permalink($permalink, $post_id, $leavename) {
	if (strpos($permalink, '%productcats%') === FALSE) return $permalink;
		// Posts
		$post = get_post($post_id);
		if (!$post) return $permalink;
		// Custom Taxonomy
		$terms = wp_get_object_terms($post->ID, 'productcats');
		if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) $taxonomy_slug = $terms[0]->slug;
		else $taxonomy_slug = 'uncategorized';
	return str_replace('%productcats%', $taxonomy_slug, $permalink);
//Flush permalinks
flush_rewrite_rules( false );

For a step by step explanation of the permalink function please refer to the original article I found on google. You may find you need to go to settings/permalinks in your admin and save again for the changes to take effect. You will already need to have the custom permalink structure set to /%postname%. More information on setting up custom page templates, custom post types and custom taxonomies can be found on the wordpress codex.

WordPress Comments Form – How to change HTML

I searched high and low for a good tutorial on how to change the HTML of the wordpress comment form. From the articles I did find I managed to put together something that works. Feel free to post a comment if there is a better way of doing this…

I put the below code in functions.php and comment_form(); in my comments.php

The code below is my modified version. For defaults simply add or replace my code with http://codex.wordpress.org/Function_Reference/comment_form

add_filter( 'comment_form_defaults', 'my_comment_defaults');
function my_comment_defaults($defaults) {
	$req = get_option( 'require_name_email' );
	$aria_req = ( $req ? " aria-required='true'" : '' );
	$defaults = array(
		'fields'        	   => array(
		'author' => '<div><label for="author">' . __( 'Name' ) . ( $req ? '<span class="required">*</span>' : '' ) . '</label> ' . '<input id="author" name="author" placeholder="your name" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '" size="30"' . $aria_req . ' /></div>',
		'email' => '<div><label for="email">' . __( 'Email' )  . ( $req ? '<span class="required">*</span>' : '' ) . '</label> ' . '<input id="email" name="email" placeholder="email@address.co.uk" type="email" value="' . esc_attr(  $commenter['comment_author_email'] ) . '" size="30"' . $aria_req . ' /></div>'
		'comment_field' => '<div><label for="comment">' . _x( 'Comment', 'noun' ) . '</label><textarea id="comment" name="comment" cols="45" rows="8" aria-required="true"  placeholder="your comment"></textarea></div>',
		'must_log_in'          => '<p class="must-log-in">' .  sprintf( __( 'You must be <a href="%s">logged in</a> to post a comment.' ), wp_login_url( apply_filters( 'the_permalink', get_permalink( $post_id ) ) ) ) . '</p>',
		'logged_in_as'         => '<p class="logged-in-as">' . sprintf( __( 'Logged in as <a href="%1$s">%2$s</a>. <a href="%3$s" title="Log out of this account">Log out?</a>' ), admin_url( 'profile.php' ), $user_identity, wp_logout_url( apply_filters( 'the_permalink', get_permalink( $post_id ) ) ) ) . '</p>',
		'comment_notes_before' => '<fieldset>',
		'comment_notes_after'  => '</fieldset>',
		'id_form'              => 'commentform',
		'id_submit'            => 'submit',
		'title_reply'          => __( 'Leave a Comment' ),
		'title_reply_to'       => __( 'Leave a Reply %s' ),
		'cancel_reply_link'    => __( 'Cancel reply' ),
		'label_submit'         => __( 'Comment' ),
    return $defaults;

You will notice I have made the following modifications

  • Removed the website field
  • Added type=”email” to the Email field (HTML5)
  • Added placeholder text (HTML5)
  • Removed the default text from the top and bottom of the form and replaced with <fieldset></fieldset>
  • Moved the required * inside the label
  • Changed the “Leave a Reply” title to “Leave a Comment”
  • Changed the text of the submit button

WordPress 404 on Custom Post Types

I came across a nightmare of a problem today. Everytime I viewed my custom post types I kept getting a 404 error.  I just couldnt understand what was going on.  Thanks to this article I finally solved the problem.

When setting up custom post types and a custom permalink structure add the below code to the function used to create custom posts.

flush_rewrite_rules( false );

I just wanted to write a quick post to highlight the problem but an explanation of why this is needed can be found on the wordpress codex.

How to use Post Formats in WordPress 3.1

WordPress 3.1 has seen the introduction of Post Formats. They provide the ability to target posts within templates using get_post_format() and through css using the extra classes wordpress now adds automatically to posts. This will save on creating extra categories or tags just for targeting and styling these types of content.

So how does it work…

Add this to the functions.php file in your theme. You only need to list the formats you wish to use.

// This theme uses post formats<br/>
add_theme_support( 'post-formats', array( 'aside', 'gallery', 'link','image', 'quote', 'status', 'video', 'audio', 'chat' ));

You will then see a list of radio buttons in your edit post right hand column.

Once a type is selected you can style using the following class added to your post on listing pages

and using the following class added to your tag on single pages.

Within your templates you can target posts by format using the following code

 if ( has_post_format( 'image' )) {
  echo 'this is an image format';

WordPress 3.1

Yesterday saw the release of WordPress 3.1 and it has some pretty nice features for both general users and developers like myself.

New Admin Bar
An admin bar has been added when logged in. Its a nice little touch for the not so experienced wordpress user. It makes the admin section and the front end appear more seamless by allowing you to click through to create a new post, manage your personal details, appearance, comments and updates whilst browsing the front end of your site. For multisite users it makes switching between sites quick and easy.

Continue reading