Question

i have created a custom post type using Jetengine called "cars" and meta field like this "model" "maker" "year" .. etc, what i want is to use more than one meta field as post permalink and target only my CPT "cars" (this one im not sure about it), for now my code looks like this:

add_action('save_post', 'set_slug');

function set_slug($post_id){
    $new_slug = get_post_meta($post_id,'maker', true);
    $post_type = get_post_type($post,'cars', true);
    $post_args = array(
        'ID' => $post_id,
        'post_name' => $new_slug,
    );
    
    // unhook this function to prevent infinite loop
    remove_action( 'save_post', 'set_slug' );

    wp_update_post($post_args);
    // re-hook this function
    add_action( 'save_post', 'set_slug' );
}

i tried to add more meta field next to each other but its didn't work , only the first meta field is used

any help is appreciate since i'm still new to this.

thanks

Edit:

im trying to have more meta field into my permalink of CPT posts like this: "www.mywebsite.com/cars/maker-model-year"

at the moment i have my code like below and its working like i want it post permalink but i wish to know how i can add more meta field and make it conditional to a specific CPT

add_action('save_post', 'set_slug');
if (get_post_type($post_object->ID) == 'car') {
    function set_slug($post_id){
    $new_slug = get_post_meta($post_id, true);
    $post_args = array(
        'ID' => $post_id,
        'post_name' => $new_slug,
    );
    // unhook this function to prevent infinite loop
    remove_action( 'save_post', 'set_slug' );
}
    wp_update_post($post_args);
    // re-hook this function
    add_action( 'save_post', 'set_slug' );
}

I should also add this : i have another code in place that set post title from my form field like this Form 1 : Maker + Model + Year = BMW-M3-2011 Post title = Post permalink

and this one only works if i set $new_slug like this in my code above $new_slug = get_post_meta($post_id, true);

i apologize if i'm making this confusing , i don't mean to.

Was it helpful?

Solution

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

  1. Just remove the $post_type = get_post_type($post,'cars', true); from your code.

  2. Before you update the post, you should ensure that the slug is not already the same as the value of the $new_slug variable. 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;
    }
    
  3. "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 the remove_action() and add_action() calls ).

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top