I have a website with one custom post type as well as a blog.
For the custom post type I would like to have the slug as root, like so
/<title>
And the blog post I would like to display under /blog, like so
/<title>
I've managed to "minimize" the custom post type's urls by using these two functions:
add_filter( 'post_type_link', function($post_link, $post, $leavename) {
if('custom' == $post->post_type && 'publish' == $post->post_status) {
$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link);
return $post_link;
}
return $post_link;
}, 10, 3 );
and
add_action('pre_get_posts', function($query) {
if ( ! $query->is_main_query() || 3 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
return;
}
if ( ! empty( $query->query['name'] ) ) {
$query->set( 'post_type', array( 'post', 'custom', 'page' ) );
}
});
However, I have not managed to move my blog posts to /blog.
I've tried to set the permalink structure to
/blog/%postname%/
and the custom post type's rewrite to
'rewrite' => array('slug' => 'custom', 'with_front' => false)
However, this does not produce the desired effect (domain/title). Instead, the "custom" slug is now part of the url again. Manually removing it (domain/title) produces a 404.
I have a website with one custom post type as well as a blog.
For the custom post type I would like to have the slug as root, like so
http://domain/<title>
And the blog post I would like to display under /blog, like so
http://domain/blog/<title>
I've managed to "minimize" the custom post type's urls by using these two functions:
add_filter( 'post_type_link', function($post_link, $post, $leavename) {
if('custom' == $post->post_type && 'publish' == $post->post_status) {
$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link);
return $post_link;
}
return $post_link;
}, 10, 3 );
and
add_action('pre_get_posts', function($query) {
if ( ! $query->is_main_query() || 3 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
return;
}
if ( ! empty( $query->query['name'] ) ) {
$query->set( 'post_type', array( 'post', 'custom', 'page' ) );
}
});
However, I have not managed to move my blog posts to /blog.
I've tried to set the permalink structure to
/blog/%postname%/
and the custom post type's rewrite to
'rewrite' => array('slug' => 'custom', 'with_front' => false)
However, this does not produce the desired effect (domain/title). Instead, the "custom" slug is now part of the url again. Manually removing it (domain/title) produces a 404.
Share Improve this question asked Jan 15, 2019 at 22:05 FSHFSH 133 bronze badges 3 |1 Answer
Reset to default 1moving blog posts to /blog/
is pretty easy and you can use WordPress settings to do that - no coding needed.
The problem you will have though is that after moving posts, your CPT URL structure will conflict with URL structure of pages - so you'll have to modify your pre_get_posts
function.
As for your post_type_link
you can simplify it a lot (if it is not hierarchical... is it?):
add_filter( 'post_type_link', function($post_link, $post, $leavename) {
if ('custom' == $post->post_type && 'publish' == $post->post_status) {
$post_link = site_url('/') . $post->post_name .'/';
}
return $post_link;
}, 10, 3 );
And I also wouldn't use pre_get_posts
for selecting proper posts. Using parse_request
is a lot easier for this task and it allows you to prevent 404 errors a lot easier.
add_action( 'parse_request', function ( $wp ) {
if ( ! is_admin() ) {
if ( array_key_exists('error', $wp->query_vars) && '404' == $wp->query_vars['error'] ) {
$custom_post = get_page_by_path( $wp->request, OBJECT, 'CUSTOM' );
if ( $custom_post instanceof WP_Post ) {
unset( $wp->query_vars['error'] );
$wp->query_vars['page'] = '';
$wp->query_vars['CUSTOM'] = $wp->query_vars['name'] = $wp->request;
$wp->query_vars['post_type'] = 'CUSTOM';
}
}
}
return $wp;
} );
pre_get_posts
function? Especially the one with3 != ...
? – Krzysiek Dróżdż Commented Jan 15, 2019 at 22:193 !=
part I don't understand myself. – FSH Commented Jan 15, 2019 at 22:22