Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Custom post type and permalinks WordPress

  • SOLVED

I'd like to setup a new post type called 'guide' with a custom taxonomy 'guide-categories', I've used the custom post type UI plugin to setup this before but it has caused issues so I'm looking to start over so hopefully I can achieve the following:

<strong>/guide/</strong> - I'd like this to show a template page (not an archive)
I'd like all archive urls to be in the format of <strong>/guide/*guide-category*</strong>
And all posts to show in the format of <strong>/guide/*guide-category*/*post-name*</strong>

Would appreciate some help setting this up :)

Hope this makes sense?

Answers (5)

2011-08-15

Gabriel Merovingi answers:

Hi. I would put it together like this:


add_action( 'init', 'theme_init' );
function theme_init()
{
$labels = array(
'name' => _x( 'Guides', 'post type general name' ),
'singular_name' => _x( 'Guide', 'post type singular name' ),
'add_new' => _x( 'Add New', 'guide' ),
'add_new_item' => __( 'Add New Guide' ),
'edit_item' => __( 'Edit Guide' ),
'new_item' => __( 'New Guide' ),
'view_item' => __( 'View Guide' ),
'search_items' => __( 'Search Guides' ),
'not_found' => __( 'No guides found' ),
'not_found_in_trash' => __( 'No guides found in the trash' ),
'parent_item_colon' => ''
);
$args = array(
'labels' => $labels,
'public' => true,
'description' => 'Optional Description',
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array( "slug" => "guide" ),
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => 4,
'supports' => array( 'title', 'editor', 'excerpt', 'comments', 'author' )
);
register_post_type( 'guide', $args );

$guide_category_labels = array(
'name' => _x( 'Clients', 'taxonomy general name' ),
'singular_name' => _x( 'Client', 'taxonomy singular name' ),
'search_items' => __( 'Search clients' ),
'popular_items' => __( 'Popular clients' ),
'all_items' => __( 'All Clients' ),
'parent_item' => null,
'parent_item_colon' => null,
'edit_item' => __( 'Edit Client' ),
'update_item' => __( 'Update Client' ),
'add_new_item' => __( 'Add New Client' ),
'new_item_name' => __( 'New Client' ),
'separate_items_with_commas' => __( 'Separate clients with commas' ),
'add_or_remove_items' => __( 'Add or remove client' ),
'choose_from_most_used' => __( 'Choose from the most common clients' )
);
register_taxonomy( 'guide-categories', array( 'guide' ), array(
'hierarchical' => true,
'labels' => $guide_category_labels,
'show_ui' => true,
'query_var' => true,
'update_count_callback' => '_update_post_term_count'
}
}


This would go into your functions.php


Dale Williams comments:

Thanks, this works to create the post type however the permalink is still registered as /guide/*postname* rather than /guide/*guide-category*/*postname*


Gabriel Merovingi comments:

Ah ok. In that case change the custom taxonomies slug re-write rule:


'rewrite' => array( 'slug' => '/guide/guide-category' ) ) );


Gabriel Merovingi comments:

sorry typo in previous code it should be


register_taxonomy( 'guide-categories', array( 'guide' ), array(
'hierarchical' => true,
'labels' => $guide_category_labels,
'show_ui' => true,
'query_var' => true,
'update_count_callback' => '_update_post_term_count',
'rewrite' => array( 'slug' => '/guide/guide-categories' )
}


Dale Williams comments:

really appreciate the help you are giving with this! still showing posts as /guide/*postname* though


Gabriel Merovingi comments:

Well we can set the rewrite of the slug for the custom post type to guide/guide-categories/ like this:


$args = array(
'labels' => $labels,
'public' => true,
'description' => 'Optional Description',
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array( "slug" => "guide/guide-categories/" ),
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => 4,
'supports' => array( 'title', 'editor', 'excerpt', 'comments', 'author' )
);

But by doing this, your custom post types archive page address will be the same /guide/guide-categories/.


Gabriel Merovingi comments:

Also if you want to show a custom page for the archive, you should change 'has_archive' => true to 'has_archive' => false
You know how to make a custom page template?


Dale Williams comments:

Yeah, quite happy creating templates, it's the functions file and permalinks I get confused over :)

We're very nearly there urls now showing as /guide/guide-categories/postname can we change this to actually display the category rather than guide-categories?

For example if I have a guide category called 'attractions' (there are lots of other categories too) then the url would be /guide/attractions/postname?


Gabriel Merovingi comments:

Ok so what your looking for sounds a lot of like what you can do with Categories and Tags but it can not be done with custom taxonomies (yet).

Have a look at this: http://wordpress.org/support/topic/using-yearmonthday-permalinks-with-custom-post-types?replies=2

It explains the current limitations.

On the other hand there might be someone here that knows this better then me and can hack something up but we are now beyond my current skill sets.


Gabriel Merovingi comments:

There is one way to get what your asking for. You could use your "guides" as posts. Then just change your sites permalink structure to /guides/category/%category%/%postname%/ and your category base to guides.

This would return a "post" in the category "florida" as:

http://yoursite.com/guides/category/florida/postname/

while category structure would be :

http://yoursite.com/guides/category/florida/

But you can experiment around in your Settings > Permalinks.


Gabriel Merovingi comments:

and here is a function to "rename" your posts to "guides"


add_filter( 'gettext', 'change_post_to_guide' );
add_filter( 'ngettext', 'change_post_to_aguide' );
function change_post_to_guide( $translated )
{
$translated = str_ireplace( 'Post', 'Guide', $translated );
return $translated;
}


Gabriel Merovingi comments:

sorry just saw a typo in the code above, should be:


add_filter( 'gettext', 'change_post_to_guide' );
add_filter( 'ngettext', 'change_post_to_guide' );
function change_post_to_guide( $translated )
{
$translated = str_ireplace( 'Post', 'Guide', $translated );
return $translated;
}


Dale Williams comments:

Brilliant idea! My standard posts are unused so this will hopefully work well!
Out of interest does this affect anything on the frontend or does it only change names in wp-admin?


Gabriel Merovingi comments:

All this does is change names used for posts. Anywhere where you use WPs functions to call post details it will be renamed to the new name. But nothing changes. Its still posts and needs no custom query.

2011-08-15

Reland Pigte answers:

try to add this to your functions.php


add_action('init', 'create_post_type');
function create_post_type()
{
$labels = array(
'name' => _x('Guide', 'post type general name'),
'singular_name' => _x('Guide', 'post type singular name'),
'add_new' => _x('Add New', 'guide'),
'add_new_item' => __('Add New Guide'),
'edit_item' => __('Edit Guide'),
'new_item' => __('New Guide'),
'all_items' => __('All Guide'),
'view_item' => __('View Guide'),
'search_items' => __('Search Guide'),
'not_found' => __('No guide found'),
'not_found_in_trash' => __('No guide found in Trash'),
'parent_item_colon' => '',
'menu_name' => 'Guide'
);

$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => true,
'capability_type' => 'post',
'has_archive' => true,
'rewrite' => array('slug' => 'guide'),
'hierarchical' => false,
'menu_position' => null,
'supports' => array('title','editor','author','thumbnail','excerpt','comments')
);
register_post_type('guide', $args);
}

//hook into the init action and call create_book_taxonomies when it fires
add_action( 'init', 'create_guide_taxonomies', 0 );

//create two taxonomies, genres and writers for the post type "book"
function create_guide_taxonomies()
{
// Add new taxonomy, make it hierarchical (like categories)
$labels = array(
'name' => _x( 'Guide Categories', 'Taxonomy general name' ),
'singular_name' => _x( 'Guide Category', 'Taxonomy singular name' ),
'search_items' => __( 'Search Guide Categories' ),
'all_items' => __( 'All Guide Categories' ),
'parent_item' => __( 'Parent Guide Categories' ),
'parent_item_colon' => __( 'Parent Guide Categories:' ),
'edit_item' => __( 'Edit Guide Categories' ),
'update_item' => __( 'Update Guide Categories' ),
'add_new_item' => __( 'Add New Guide Categories' ),
'new_item_name' => __( 'New Guide Categories Name' ),
'menu_name' => __( 'Guide Categories' ),
);

register_taxonomy('guide_gategories' ,array('guide'), array(
'hierarchical' => true,
'labels' => $labels,
'show_ui' => true,
'query_var' => true,
));
}

Hope this works!

2011-08-16

Jurre Hanema answers:

Doing this turns out to be slightly more complicated than you might think. I came up with the following solution, which works:


add_action('init', 'wpq_register_post_types');
add_filter('post_type_link', 'wpq_permalinks', 10, 3);


function wpq_register_post_types()
{
// Register the post type

$guide_labels = array(
'name' => 'Guides',
'singular_name' => 'Guide',
'add_new' => 'Add New',
'add_new_item' => 'Add New Guide',
'edit_item' => 'Edit Guide',
'new_item' => 'New Guide',
'view_item' => 'View Guide',
'search_items' => 'Search Guides',
'not_found' => 'No guides found',
'not_found_in_trash' => 'No guides found in trash'
);

register_post_type('guide',
array(
'labels' => $guide_labels,
'query_var' => 'guide',
'rewrite' => false,
'capability_type' => 'post',
'has_archive' => false,
'public' => true
)
);


// Register the taxonomy

$guide_category_labels = array(
'name' => 'Guide categories',
'singular_name' => 'Guide category',
'search_items' => 'Search guide categories',
'popular_items' => 'Popular guide categories',
'all_items' => 'All guide categories',
'edit_item' => 'Edit guide category',
'update_item' => 'Update guide category',
'add_new_item' => 'Add new guide category',
'new_item_name' => 'New guide category',
'separate_items_with_commas' => 'Separate categories with commas',
'add_or_remove_items' => 'Add or remove guide category',
'choose_from_most_used' => 'Choose from most used guide categories'
);


register_taxonomy('guide-categories', 'guide',
array
(
'labels' => $guide_category_labels,
'hierarchical' => true,
'query_var' => 'guide_category',
'rewrite' => false
)
);


// Register custom rewrite rules

global $wp_rewrite;

$wp_rewrite->add_rewrite_tag('%guide%', '([^/]+)', 'guide=');
$wp_rewrite->add_rewrite_tag('%guide_category%', '([^/]+)', 'guide_category=');

$wp_rewrite->add_permastruct('guide-categories', '/guide/%guide_category%', false, EP_CATEGORIES);
$wp_rewrite->add_permastruct('guide', '/guide/%guide_category%/%guide%', false);
}


function wpq_permalinks($permalink, $post_id, $leavename)
{
$no_terms = 'no-category';

$post = get_post($post_id);

if($post->post_type != 'guide' || empty($permalink) || in_array($post->post_status, array('draft', 'pending', 'auto-draft')))
return $permalink;

$terms = wp_get_object_terms((int)$post->ID, 'guide-categories');

if(is_wp_error($terms) || empty($terms))
{
$term_slug = $no_terms;
} else
{
$term = reset($terms);

if(is_object($term))
$term_slug = $term->slug;
else
$term_slug = $no_terms;
}

$permalink = str_replace('%guide_category%', $term_slug, $permalink);

return $permalink;
}


If it doesn't work right away, go to the WP admin and visit the page Settings -> Permalinks.


Jurre Hanema comments:

Aaaaaaaaand of course I forgot something. Also add this code:


add_filter('term_link', 'wpq_term_link', 10, 3);

function wpq_term_link($termlink, $term, $taxonomy)
{
$termlink = str_replace('%guide_category%', $term->slug, $termlink);

return $termlink;
}


Btw @ Jermaine Oppong: the functionality of that plugin is a core Wordpress feature since 3.1 and it won't solve this issue at all.


Dale Williams comments:

Amazing, worked perfectly, thank you!

Man, all of you guys are totally awesome, did not expect so much help! Thanks to everyone who helped me out here, I have a couple of good solutions and answers :)

2011-08-14

MDan answers:

Hello,
Maybe this post will help you:

http://xplus3.net/2010/05/20/wp3-custom-post-type-permalinks/


Dale Williams comments:

Thanks, this kind of helps, I can register the post type in my functions file but I do not understand the last part mainly under "putting things together" on the page you posted.

2011-08-16

Jermaine Oppong answers:

I had a simi8lar issue until I used this plugin - [[LINK href="http://www.thinkoomph.com/plugins-modules/wordpress-custom-post-type-archives/"]]Simple Custom Post Type Archives[[/LINK]]