only the first meta field is used
Yes, and it’s because the $new_slug contains just one meta which is maker.
So if you want to add other meta like model and year, and have a slug that looks like <maker>-<model>-<year>, you can try my code below — just replace the $new_slug = get_post_meta($post_id,'maker', true); in your code with the following:
Note: You should use the first snippet in the question.
// List of meta that will be added to the post slug (post_name). Just add another
// get_post_meta() if you want to add another meta to the slug. And just reposition
// the array items based on your preferences, e.g. you could put the 'year' before
// 'maker'.
$meta = array(
get_post_meta( $post_id, 'maker', true ),
get_post_meta( $post_id, 'model', true ),
get_post_meta( $post_id, 'year', true ),
);
$new_slug = implode( '-', array_filter( $meta ) );
target only my CPT “cars”
You could use get_post_type() like so:
add_action( 'save_post', 'set_slug' );
function set_slug( $post_id ) {
// Do nothing if the post type is NOT "cars".
if ( 'cars' !== get_post_type( $post_id ) ) {
return;
}
// ... your code here.
}
But a simpler option is using the save_post_<post type> hook instead of save_post like so:
add_action( 'save_post_cars', 'set_slug' );
function set_slug( $post_id ) {
// ... your code here.
}
Additional Notes
-
Just remove the
$post_type = get_post_type($post,'cars', true);from your code. -
Before you update the post, you should ensure that the slug is not already the same as the value of the
$new_slugvariable. So for example, add this after the above$new_slug = implode( '-', array_filter( $meta ) );:if ( strtolower( $new_slug ) === get_post_field( 'post_name', $post_id ) ) { return; } -
“set_slug” is a very generic name, so please use a better name that is unique enough, e.g.
wpse_387941_set_slug.. ( and be sure to update the function name in theremove_action()andadd_action()calls ).