0
votes

I use wordpress theme called Dreamland which has defefined some custom post types and taxonomies. I want to change permalink structure for omit slug in in url. Almost every solution I've found is based on rewrite parameter on register_post_type() function. I tried to change it directly on place where that custom post type is registered or by register_post_type_args filter like this:

function custom_post_type_args( $args, $post_type ) {
    if ( $post_type == "bunch_property" ) {
        $args['rewrite'] = array(
            'slug' => ''
        );
    }

    return $args;
}
add_filter( 'register_post_type_args', 'custom_post_type_args', 999, 2 );

It was always ended with 404 error. The important information is that only allowed slug is "property" although real slug of this post type is "bunch_property". I had same problem with its taxonomy called "property_category" but I solved it by this solution. Is there also anything like it for post type instead of taxonomy? Or any different solution except rewrite rule on .htaccess?

2
This works fine if permalink structure is %postname% but I want my own permalink scheme: /%property_category%/%postname% Unfortunatelly doen't work in this case.Pavel Němec

2 Answers

1
votes

try this solution Remove Custom Post Type Slug from Permalinks

function gp_remove_cpt_slug( $post_link, $post, $leavename ) {
 
    if ( 'bunch_property' != $post->post_type || 'publish' != $post->post_status ) {
        return $post_link;
    }
 
    $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
 
    return $post_link;
}
add_filter( 'post_type_link', 'gp_remove_cpt_slug', 10, 3 );

function gp_parse_request_trick( $query ) {

    // Only noop the main query
    if ( ! $query->is_main_query() )
        return;

    // Only noop our very specific rewrite rule match
    if ( 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
        return;
    }

    // 'name' will be set if post permalinks are just post_name, otherwise the page rule will match
    if ( ! empty( $query->query['name'] ) ) {
        $query->set( 'post_type', array( 'post', 'page', 'bunch_property' ) );
    }
}
add_action( 'pre_get_posts', 'gp_parse_request_trick' );

add custom taxonomy to post type url

add_filter('generate_rewrite_rules', 'taxonomy_slug_rewrite');

function taxonomy_slug_rewrite($wp_rewrite) {
    $rules = array();
    // change "^property/([^/]+)/([^/]+)/?" to "^([^/]+)/([^/]+)/?" to test without "property" in url
    $rules["^property/([^/]+)/([^/]+)/?"] = 'index.php?post_type=bunch_property&property_category=$matches[1]&resource=$matches[2]';
    // merge with global rules
    $wp_rewrite->rules = $rules + $wp_rewrite->rules;
}
0
votes

Finally I solve it thanks to Sofiane Achouba. Except the last part which is solved by add_rewrite_rule. It's not optimal because I have to call loop for go throught all posts and apply add_rewrite_rule() function for each of them:

function my_custom_rewrite() {
   $args = array("post_type" => "bunch_property","posts_per_page" => -1);
   $posts = get_posts( $args );
      foreach($posts as $post){
         $cat = get_the_terms($post,"property_category");
         $cat_slug = $cat[0]->slug;
         $post_slug = $post->post_name;
         add_rewrite_rule('^'.$cat_slug.'/'.$post_slug.'?/','index.php/property/'.$cat_slug.'/'.$post_slug.'/', 'top');
      }
}
add_action('init', 'my_custom_rewrite');

I've tried go throught catagories only but it doesn't work.

It 's strange but this works:

add_rewrite_rule('^xxx/(.*?)/', 'index.php/property/xxx/yyy/','top'); // where xxx is post name and yyy category slug

but this doen't:

add_rewrite_rule('^xxx/(.*?)/', 'index.php/property/xxx/$matches/','top');

Which led me to the solution above. Again repeat it's not optimal.