I'm trying to create a custom permalink structure that will allow me to accomplish the following.
I want my permalink structure to look like this:
projects/category/project-name
or
/%custom-post-type%/%custom-taxonomy%/%post-name%/
I've been able to succesfully use /%category%/ in permalinks for normal, out-of-the-box WP posts, but not for CPTs.
How would creating such a permalink structure affect the URLs or other pages? Is it possible de define a custom permalink structure and restrict it to a single CPT?
Thanks
To get the permalink of a custom post type you can use get_post_permalink($id) . If you're using it inside The Loop use get_permalink() instead. Retrieves the full permalink for the current post or post ID.
Changing Custom Post Type Permalinks in WordPress Upon activation, you need to visit Settings » Permalinks page and scroll down to 'Permalink Settings for Custom Post Types' section. Here you can change the permalink structure of single items in your custom post type.
' So make sure you have a custom post type created before you begin creating your taxonomies. Next, go to CPT UI » Add/Edit Taxonomies menu item in the WordPress admin area to create your first taxonomy. On this screen, you will need to do the following: Create your taxonomy slug (this will go in your URL)
A permalink is the web address used to link to your content. The URL to each post should be permanent and never change — hence the name permalink. The Settings Permalinks Screen allows you to choose your default permalink structure. You can choose from common settings or create custom URL structures.
Lucky for you, I just had to do this for a client project. I used this answer on the WordPress Stackexchange as a guide:
/**
* Tell WordPress how to interpret our project URL structure
*
* @param array $rules Existing rewrite rules
* @return array
*/
function so23698827_add_rewrite_rules( $rules ) {
$new = array();
$new['projects/([^/]+)/(.+)/?$'] = 'index.php?cpt_project=$matches[2]';
$new['projects/(.+)/?$'] = 'index.php?cpt_project_category=$matches[1]';
return array_merge( $new, $rules ); // Ensure our rules come first
}
add_filter( 'rewrite_rules_array', 'so23698827_add_rewrite_rules' );
/**
* Handle the '%project_category%' URL placeholder
*
* @param str $link The link to the post
* @param WP_Post object $post The post object
* @return str
*/
function so23698827_filter_post_type_link( $link, $post ) {
if ( $post->post_type == 'cpt_project' ) {
if ( $cats = get_the_terms( $post->ID, 'cpt_project_category' ) ) {
$link = str_replace( '%project_category%', current( $cats )->slug, $link );
}
}
return $link;
}
add_filter( 'post_type_link', 'so23698827_filter_post_type_link', 10, 2 );
When registering the custom post type and taxonomy, be sure to use the following settings:
// Used for registering cpt_project custom post type
$post_type_args = array(
'rewrite' => array(
'slug' => 'projects/%project_category%',
'with_front' => true
)
);
// Some of the args being passed to register_taxonomy() for 'cpt_project_category'
$taxonomy_args = array(
'rewrite' => array(
'slug' => 'projects',
'with_front' => true
)
);
Of course, be sure to flush rewrite rules when you're done. Good luck!
Since WordPress changed a lot in the recent years there is a new solution for this.
// Used for registering cpt_project custom post type
$post_type_args = array(
'rewrite' => array(
'slug' => '/%custom-post-type%/%custom-taxonomy%/%postname%/',
'with_front' => true
'walk_dirs' => false
)
);
%custom-post-type% must match the name for your custom post type %custom-taxonomy% must match the name for your taxonomy that WordPress automatically creates the right rewrite rules and links
with 'walk_dirs' => false you prevent WP from creating crazy rules like with only [^/]+/ cause your link starts with a custom-post-type
and often this dir walk isn't even needed cause u access only the sites in your structure or separate taxonomy sites.
With this your rewrite rules are as precise as possible, and you don't need to fetch the rules with
add_filter( 'rewrite_rules_array', 'so23698827_add_rewrite_rules' );
and prepend them later on with
add_filter( 'post_type_link', 'so23698827_filter_post_type_link', 10, 2 );
as mentioned in the accepted answer. This saves memory and execution time!
Hope this helps anyone, who is searching for this Problem with WP Versions > 5.X
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With