0

I've set up a CPT via a plugin, including custom fields for first and last name, so I'd like to automatically make the post title "First Name + ' ' + Last Name".

This post almost got me there:

How To Set Custom Post Type Title Without Supports

But my version (adapted code below) creates a title called "Array Array".

add_filter( 'save_post_practitioners', 'hexagon_practitioner_set_title', 10, 3 );
function hexagon_practitioner_set_title ( $post_id, $post, $update ){
    //This temporarily removes filter to prevent infinite loops
    remove_filter( 'save_post_practitioners', __FUNCTION__ );

    //get first and last name meta
    $first = get_metadata( 'first_name', $post_id ); //meta for first name
    $last = get_metadata( 'last_name', $post_id );   //meta for last name

    $title = $first . ' ' . $last;

    //update title
    wp_update_post( array( 'ID'=>$post_id, 'post_title'=>$title ) );

    //redo filter
    add_filter( 'save_post_practitioners', __FUNCTION__, 10, 3 );
}

I've delved into the functions involved but there seem to be many competing solutions that aren't quite what I'm looking for. What am I getting wrong?

Thanks!

2 Answers 2

2

The issue with your code is that the get_metadata() function returns an array of values, not a single value. So when you concatenate $first and $last variables in this line $title = $first . ' ' . $last;, you are actually concatenating two arrays, which results in the "Array Array" title.

To fix this, you can use the get_post_meta() function instead of get_metadata() to retrieve the first and last name values as follows:

$first = get_post_meta( $post_id, 'first_name', true ); //meta for first name
$last = get_post_meta( $post_id, 'last_name', true );   //meta for last name

The third parameter true in the get_post_meta() function specifies that you want to retrieve a single value instead of an array of values.

Here's the updated code:

add_filter( 'save_post_practitioners', 'hexagon_practitioner_set_title', 
10, 3 );
function hexagon_practitioner_set_title ( $post_id, $post, $update ){
//This temporarily removes filter to prevent infinite loops
remove_filter( 'save_post_practitioners', __FUNCTION__ );

//get first and last name meta
$first = get_post_meta( $post_id, 'first_name', true ); //meta for first 
name
$last = get_post_meta( $post_id, 'last_name', true );   //meta for last 
name

$title = $first . ' ' . $last;

//update title
wp_update_post( array( 'ID'=>$post_id, 'post_title'=>$title ) );

//redo filter
add_filter( 'save_post_practitioners', __FUNCTION__, 10, 3 );
}

This should set the post title to "First Name Last Name" as you intended.

6
  • Thanks @techshqq! Got it to work after a little fiddling, discovering I'd referenced my post type incorrectly in the filter name, calling it "save_post_practitioners" not "save_post_practitioner". I assume I should use whatever I put in 'singular_name', not 'name', in my CPT $labels array? Feb 15, 2023 at 17:35
  • One last wrinkle: I'd like the slug to reflect the same info as well, but I'm only getting a numeric one. [This link] (wordpress.stackexchange.com/questions/94364/…) discusses the issue, but I'm not sure how to integrate it into my own code. Feb 15, 2023 at 18:00
  • 1
    @AdamAbrams I thought I should help, so: 1) "I assume I should use whatever I put in 'singular_name'" - no, it's the first parameter passed to register_post_type(), but since you added your CPT using a plugin, then you need to check its documentation regarding which one is the post type name. 2) You can update the slug by adding 'post_name' => '<slug here>' to your args (the array you pass to wp_update_post()). So, for example, you can use 'post_name' => sanitize_title( $title ),.
    – Sally CJ
    Feb 16, 2023 at 14:06
  • Thanks @SallyCJ ! That works great for updating the slug. As for 1) though: I created the plugin, but that's just because it seemed the best-practice way to add the CPT code. So no documentation... But in the code for adding the CPT, the "$args = array()" part begins like this: label' => __( 'Practitioners', 'text_domain' ), i.e. the plural, "practitioners". Yet my code for setting the title/slug only works if I use save_post_practitioner - singular. Feb 16, 2023 at 19:36
  • @AdamAbrams In short, if you used register_post_type( 'practitioner',, then the post type name/slug is practitioner. If it's register_post_type( 'practitioners', (note the "s"), then the post type is practitioners. If you actually did use the plural "practitioners", but the one that worked was "practitioner", then that's weird 🤔 However, if you need further assistance with that, you should post another question. :)
    – Sally CJ
    Feb 17, 2023 at 0:15
1

Try setting the 'single' parameter to true. It's the 4th parameter and defaults to false which returns an array, and thus you got Array Array because you did not set that parameter (to true).

Additionally, you incorrectly used get_metadata() and received either an empty array or an array of all metadata (first_name, last_name, etc.) for the specific post. See the documentation for the correct syntax, where the 1st parameter is actually the meta type and not the meta key/name:

https://developer.wordpress.org/reference/functions/get_metadata/

So in your case, the meta type is post, and the correct syntax is:

$first = get_metadata( 'post', $post_id, 'first_name', true );
$last  = get_metadata( 'post', $post_id, 'last_name', true );
2
  • Hmm, with that change, it puts nothing in the post title field, in fact it forces it to be empty. I'll look closer at the get_metadata article though. Feb 14, 2023 at 23:35
  • It's returning an empty string meaning it cannot find the meta value. And your original attempt was returning an empty array.
    – shanebp
    Feb 15, 2023 at 0:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.