Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom permalink structure: /%custom-post-type%/%custom-taxonomy%/%post-name%/

I'm trying to create a custom permalink structure that will allow me to accomplish the following.

  1. I have a custom post type called "projects"
  2. I have a custom taxonomy called "project-category" that is assigned to the CPT "projects"

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

like image 641
Bruno Cloutier Avatar asked May 16 '14 15:05

Bruno Cloutier


People also ask

How do I get a custom post type permalink?

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.

How do I change the permalink of a custom post type in WordPress?

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.

How do I add custom taxonomy to 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)

What is a permalink structure?

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.


2 Answers

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!

like image 143
Steve Grunwell Avatar answered Oct 16 '22 21:10

Steve Grunwell


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

like image 42
Alletkla Avatar answered Oct 16 '22 20:10

Alletkla