WordPress

Remove Blog Prefix For Custom Post Types

This is a problem I've seen a couple of times and it sometimes tricks people out of using custom post types in WordPress. When people first create a WordPress site I've seen most of the time they will just install WordPress as an add-on to their existing site and just use it as a blog, with the intention of moving the entire site over to WordPress. Having an existing site means that they want to prefix the WordPress blog posts with the sub-folder of /blog/.

http://example.com/blog/blog-post

This is done by going to your permalinks page and change the permalinks of your posts to have a URL of /blog/%postname%.

When you want to move the entire site over to WordPress and use custom post types to display the other pages. When you create your custom post types you have a number of options of how you want to customise this new post type.

add_action( 'init', 'register_cpt_cp_name' );
 
function register_cpt_cp_name() {
 
    $labels = array( 
  	'name'               => __( 'plural post type name', 'text_domain' ),
		'singular_name'      => __( 'single post type name', 'text_domain' ),
		'add_new'            => _x( 'Add New single post type name', '${4:Name}', 'text_domain' ),
		'add_new_item'       => __( 'Add New single post type name', 'text_domain}' ),
		'edit_item'          => __( 'Edit single post type name', 'text_domain' ),
		'new_item'           => __( 'New single post type name', 'text_domain' ),
		'view_item'          => __( 'View single post type name', 'text_domain' ),
		'search_items'       => __( 'Search plural post type name', 'text_domain' ),
		'not_found'          => __( 'No plural post type name found', 'text_domain' ),
		'not_found_in_trash' => __( 'No plural post type name found in Trash', 'text_domain' ),
		'parent_item_colon'  => __( 'Parent single post type name:', 'text_domain' ),
		'menu_name'          => __( 'plural post type name found', 'text_domain' ),
    );
 
    $args = array( 
		'labels'              => $labels,
		'hierarchical'        => true,
		'description'         => 'description',
		'taxonomies'          => array( 'category' ),
		'public'              => true,
		'show_ui'             => true,
		'show_in_menu'        => true,
		'menu_position'       => 5,
		//'menu_icon'         => '',
		'show_in_nav_menus'   => true,
		'publicly_queryable'  => true,
		'exclude_from_search' => false,
		'has_archive'         => true,
		'query_var'           => true,
		'can_export'          => true,
		'rewrite'             => true,
		'capability_type'     => 'post', 
		'supports'            => array( 
									'title', 'editor', 'author', 'thumbnail', 
									'custom-fields', 'trackbacks', 'comments', 
									'revisions', 'page-attributes', 'post-formats'
								),
    );
 
    register_post_type( 'cp_name', $args );
}

You can change the labels, categories, menu name, if you can query the post type, you can customise everything that you would want.

Now when you navigate to your newly created custom post type this will also be prefixed with the same permalink as the blog section so your URL will look like this.

http://example.com/blog/products/custom-post-type

This obviously isn't going to work for a section for your products, you need to be able to remove the blog prefix so you are left with simply /products/custom-post-type.

To do this you need to extend the rewrite option when registering your new post type. Using the rewrite option you can define the URL that you want to use for your products section. There are two options that you need to define on the rewrite section, this is with_front and slug.

Using the with_front option and setting it to false you will remove any prefix that is defined from the permalink structure, if this is set to true then it will continue using the rules defined by the permalink page.

The slug is used to customise the permalink structure that you want to use on this custom post type.

Use the following option on the rewrite to remove the blog prefix and define the slug as products.

'rewrite' => array(
    'with_front' => false,
    'slug'       => 'products'
)

Now when you visit your custom post types the URLs will now be http://example.com/products/custom-post-type.

If you do this on existing post types and the URL hasn't changed you may need to flush the WordPress rewrite rules.

WordPress Rewrite Problems

Back to top