How do you create %post_type%/%postname%/ permalink structure?

Beyond the fact that disabling ‘pretty’ permalinks in the Settings > Permalink page disables pretty permalinks for all post types and taxonomies, the options do not effect custom post types or taxonomies.

If you set the permalinks to blog/%postname% then your posts will have the structure: www.yoursite.com/blog/hello-world.

On the other hand, when a post type is registered (by default) it will set the permalink to www.yoursite.com/post-type/newpost (assuming you have pretty permalinks enabled, and the post type is post-type).

The same goes for custom taxonomies: A custom taxonomy will display as www.yoursite.com/custom-taxonomy/ and a custom taxonomy term will display as www.yoursite.com/custom-taxonomy/custom-taxonomy-term/.

There are a couple of things that have to be in place for this to happen though.

In register_posttype() of the post type the following must be set:

'rewrite' => true,
'has_archive' => 'post-type-name', // "post-type-name" is replaced with your post type name

Rewrite simply allows WordPress to rewrite the URL. It is set to true by default. has_archive defines the name of the archive (index) page for this post type. If this value is not set the post type has no index page.

The same is true for custom taxonomies. In register_taxonomy():

'rewrite' => array('slug' => 'hierarchical-taxonomy' ),

From the Codex:

rewrite
(boolean or array) (optional) Set to false to prevent
automatic URL rewriting a.k.a. “pretty permalinks”. Pass an $args
array to override default URL settings for permalinks as outlined
below.

$args array

  • ‘slug’ – Used as pretty permalink text (i.e. /tag/) – defaults to $taxonomy (taxonomy’s name slug)
  • ‘with_front’ – allowing permalinks to be prepended with front base –
    defaults to true ‘hierarchical’ – true or false allow hierarchical
  • urls (implemented in Version 3.1)

Note: You may need to flush the
rewrite rules after changing this. You can do it manually by going to
the Permalink Settings page and re-saving the rules — you don’t need
to change them — or by calling $wp_rewrite->flush_rules(). You should
only flush the rules once after the taxonomy has been created, not
every time the plugin/theme loads.