I currently use Post name for the permalink structure. I want to add text from a field at the end of the permalink. Is there any hook for the permalink creation when a Post is published?
In my case, I use Advanced Custom Fields and every post has a Title and Subtitle. Currently, the permalink is /title/ but I wanted to be /title-subtitle/.
Edit: similar to this previous question, except that I only want to do it for post creation and not on future post editions, since this will modify the URL of the post which is a disaster for SEO.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Here is what I did to implement this:
function slug_save_post_callback( $post_ID, $post, $update ) {
// allow 'publish', 'draft', 'future'
if ($post->post_type != 'post' || $post->post_status == 'auto-draft')
return;
// only change slug when the post is created (both dates are equal)
if ($post->post_date_gmt != $post->post_modified_gmt)
return;
// use title, since $post->post_name might have unique numbers added
$new_slug = sanitize_title( $post->post_title, $post_ID );
$subtitle = sanitize_title( get_field( 'subtitle', $post_ID ), '' );
if (empty( $subtitle ) || strpos( $new_slug, $subtitle ) !== false)
return; // No subtitle or already in slug
$new_slug .= '-' . $subtitle;
if ($new_slug == $post->post_name)
return; // already set
// unhook this function to prevent infinite looping
remove_action( 'save_post', 'slug_save_post_callback', 10, 3 );
// update the post slug (WP handles unique post slug)
wp_update_post( array(
'ID' => $post_ID,
'post_name' => $new_slug
));
// re-hook this function
add_action( 'save_post', 'slug_save_post_callback', 10, 3 );
}
add_action( 'save_post', 'slug_save_post_callback', 10, 3 );
It generates and updates the slug. Previous slug generated by WP can not be reused since it can have unique numbers if the title/slug was already used in another post. So, I sanitize the title. Then, wp_update_post makes sure there are no duplicates for the new slug with wp_unique_post_slug.
The only way I could find to only do this on publish is to compare the creation and the modified time. They are only equal when the post is created. The $update parameter is useless, since is true for the publish.
Method 2
in your functions.php file, you should be able to accomplish your desired functionality with something like this:
function adjust_permalinks() {
global $wp_rewrite;
$title = get_field( 'title_field' );
$subtitle = get_field( 'sub_title_field' );
$wp_rewrite->set_permalink_structure( $title . '-' . $subtitle );
$wp_rewrite->flush_rules();
}
add_action('init', 'adjust_permalinks');
this will set your permalink structure to always use the $title & $subtitle
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0