0

I have 2 custom post types: software and hardware. For SEO reasons I would like to have the permalinks of single software and hardware pages like:

https://domain.com/custom-post-name/

But as default WordPress adds post-type slug on it like:

https://domain.com/post-type-slug/custom-post-name/

I've removed the slug with following script that makes a replacement of the string. Now the single page is reachable with both urls described above and Google search console find 2 pages with the exact same content which is not good for SEO. Is it possible to change the complete structure of a permalink and get rid of custom post type slug?

register_post_type( 'hardware',
    array (
        'labels' => $labels,
        'has_archive' => true,
        'public' => true,
        'supports' => array( 'title', 'editor', 'excerpt', 'custom-fields', 'thumbnail' ),
        'taxonomies' => array( 'hardware-post_tag', 'hardware-category' ),
        'exclude_from_search' => false,
        'capability_type' => 'post',
        'rewrite' => array( 'slug' => 'hardware' ),
    )
);

  • Please edit your question and let we know how did you use the register_post_type – Pmpr Feb 1 '16 at 17:10
  • ` //register post type register_post_type( 'hardware', array ( 'labels' => $labels, 'has_archive' => true, 'public' => true, 'supports' => array( 'title', 'editor', 'excerpt', 'custom-fields', 'thumbnail' ), 'taxonomies' => array( 'hardware-post_tag', 'hardware-category' ), 'exclude_from_search' => false, 'capability_type' => 'post', 'rewrite' => array( 'slug' => 'hardware' ), ) ); ` – 3ky Feb 1 '16 at 18:35
1

Note one Important thing to the above answer:

While it'll work fine from the first sigth it will cause performance problems. All this code will be called on init hook so every page load will cause it to run and flush_rules() is very time expensive.

So it's recomended to call flush rules upon theme\plugin activation only. Also you can use add_permastruct functions without need to access global $wp_rewrite

Final improved solution would be:

add_action('init', 'my_custom_rewrite'); 
function my_custom_rewrite() {

    add_permastruct('hardware', '/%customname%/', false);
    add_permastruct('produkt', '/%customname%/', false);
}

add_filter( 'post_type_link', 'my_custom_permalinks', 10, 2 );
function my_custom_permalinks( $permalink, $post ) {
      return str_replace( '%customname%/', $post->post_name, $permalink );
}

 /* in case for plugin */
register_activation_hook(__FILE__,'my_custom_plugin_activate');
function my_custom_plugin_activate() {
    flush_rewrite_rules();
}


/* in case of custom Theme in Functions.php */
add_action('after_switch_theme', 'mytheme_setup');
function mytheme_setup () {
    flush_rewrite_rules();
}
0

SOLVED

with usage of $wp_rewrite you can add a new permalink structure

add_action('init', 'my_custom_rewrite');
function my_custom_rewrite() {
    global $wp_rewrite;
    $wp_rewrite->add_permastruct('hardware', '/%customname%/', false);
    $wp_rewrite->add_permastruct('produkt', '/%customname%/', false);
    $wp_rewrite->flush_rules();
}

then you replace your custom tag with str_replace when you filter the link url

add_filter( 'post_type_link', 'my_custom_permalinks', 10, 2 );
function my_custom_permalinks( $permalink, $post ) {
    return str_replace( '%customname%/', $post->post_name, $permalink );
}

NOTE: if you use this function the way is written (removing the post type slug from permalink) you can expect bad issues cause there is no control if you make a custom post permalink the same as a page or standard post

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.