|
<?php |
|
|
|
/** |
|
* Remove the /blog from URLs that are not Post and are not builtin post types |
|
* |
|
* @param array $args Arguments for the current post type |
|
* @param string $post_name Post type name/slug |
|
* |
|
* @return array Arguments for the custom post type |
|
*/ |
|
function update_blog_post_urls_remove_from_cpts( $args, $post_name ) { |
|
// get post types that are NOT builtin AND that are public |
|
$custom_post_types = get_post_types( [ 'public' => true, '_builtin' => false, ], 'names', 'and' ); |
|
|
|
// remove the /blog from custom post types |
|
// Remove from some other random post types that don't show up in the result of get_post_types() above some reason |
|
$random_other_post_types = [ 'news', 'publications' ]; |
|
if ( isset( $custom_post_types[$post_name] ) || in_array( $post_name, $random_other_post_types ) ) { |
|
// preserve the previous rewrite rule definition and only alter the with_front argument |
|
$args['rewrite'] = is_array( $args['rewrite'] ) ? array_merge( $args['rewrite'], [ 'with_front' => false ] ) : [ 'with_front' => false ]; |
|
} |
|
|
|
return $args; |
|
} |
|
add_filter( 'register_post_type_args', 'update_blog_post_urls_remove_from_cpts', 10, 2 ); |
|
|
|
/** |
|
* Remove the /blog from the archives of taxonomy terms after adding /blog to WordPress posts |
|
* |
|
* @param array $args Arguments for the current taxonomy |
|
* @param string $taxonomy Taxonomy name/slug |
|
* @param array $object_type Array of object types for the taxonomy (e.g. Post types that this taxonomy is registered to, etc...) |
|
* |
|
* @return array Arguments for the taxonomy |
|
*/ |
|
function update_blog_post_urls_remove_from_taxonomies( $args, $taxonomy, $object_type ) { |
|
// preserve the previous rewrite rule definition and only alter the with_front argument |
|
$args['rewrite'] = is_array( $args['rewrite'] ) ? array_merge( $args['rewrite'], [ 'with_front' => false ] ) : [ 'with_front' => false ]; |
|
|
|
return $args; |
|
} |
|
add_filter( 'register_taxonomy_args', 'update_blog_post_urls_remove_from_taxonomies', 10, 3 ); |
|
|
|
/** |
|
* Redirect all of the requests for the old blog pasts to the new URLs with the /blog value prepended |
|
* |
|
* @param WP_Query $query Current query object |
|
*/ |
|
function redirect_old_blog_urls( $query ) { |
|
global $wp; |
|
|
|
// if this request has resulted in a 404 error |
|
if ( isset( $query->query_vars['error'] ) && '404' === $query->query_vars['error'] ) { |
|
$custom_url_struct = get_option( 'permalink_structure' ); |
|
$parts = explode( '/', $custom_url_struct ); |
|
|
|
// Get the custom URL structure that we defined in the Permalinks menu and disregard any of the dynamic %placeholder% values that WP uses |
|
if ( ! empty( $parts ) ) { |
|
foreach ( $parts as $part ) { |
|
if ( false !== strpos( $part, '%' ) ) { |
|
continue; |
|
} |
|
|
|
$parts_to_prepend[] = $part; |
|
} |
|
} |
|
|
|
if ( ! empty( $parts_to_prepend ) ) { |
|
$new_blog_post_location = sprintf( '%s/%s/%s', home_url(), implode( '', $parts_to_prepend ), $wp->request ); |
|
|
|
$find_post = url_to_postid( $new_blog_post_location ); |
|
|
|
if ( ! empty( $find_post ) ) { |
|
wp_redirect( $new_blog_post_location, 301 ); |
|
exit; |
|
} |
|
} |
|
} |
|
} |
|
add_action( 'parse_request', 'redirect_old_blog_urls', 10, 1 ); |
Multilingual Blog Post URLs with WPML
For multilingual sites, you usually create a Posts Page (like
/blog/,/actualités/,/noticias/, etc.) and set it in Settings → Reading as the Blog Page.Since this page’s slug changes depending on the active language (via WPML in this case), you need to dynamically fetch the correct slug and use it in your post permalinks.
After adding this to your theme’s
functions.php(or a small plugin), go toSettings → Permalinks → click Save.
Make sure your structure is set to:
Result
Now posts will always include the localized blog page slug:
/en/blog/post-title//fr/actualites/post-title//es/noticias/post-title/Meanwhile:
/en/about//en/blog/,/fr/actualites/,/es/noticias/