URLs can be hard. When you have custom post types in WordPress it can be harder.

Take, for example, a custom post type for videos. Do you want your URLs to be http://example.com/videos/video-name/ or http://example.com/video/video-name/ ? And do you want the archive to be http://example.com/videos/ or http://example.com/video/ ? And what happens when you change your mind?

Thankfully, WordPress lets you do some weird things.

Pick Your Default

Let’s look at the video/videos idea for a moment. Individual posts should be video but the archive should be videos in order to grammatically make sense. When you make your custom post type there’s a parameter called has_archive – by default it’s false. If you make it true, then it’ll have the same ‘base’ as your custom post types.

But. If you make it a string then you can make it ‘videos’ or ‘photos’ and magically your archives will have those names. That makes it pretty easy to change, just remember to re-save your permalinks after. I personally recommend doing a redirect so that video goes to videos (and videos/postname go to video/postname) so that any random bad URLs would still be caught.

Remember that you can leave it false and make a page to be a placeholder page, or you use archive-{post_type}.php to customize it further.

When You Need Both

But… What if you need both?

This is probably a bad idea, but let’s pretend you want to have both video and videos work for all cases. That’s when you’ll need something like this:

$plural_types = array( 
	'videos' => 'post_type_videos', 
	'photos' => 'post_type_photos' 
);

foreach( $plural_types as $slug => $type ) {
	add_rewrite_rule(
		'^'.$slug.'/?$',
		'index.php?post_type='.$type,
		'top'
	);
	add_rewrite_rule(
		'^'.$slug.'/page/([0-9]+)?/?$',
		'index.php?post_type='.$type.'&paged=$matches[1]',
		'top'
	);
}

In that example, I have the slug for my custom post types set to the singular, and then the $plural_types array has the correct plural and the associated custom post type. This is tossed into a for-loop that creates a custom rewrite rule that will redirect.

Reader Interactions

%d bloggers like this: