0

I've been trying to achieve this for a bit now, and having no success. I have a custom post type "Contributor" where I've disabled the default title field, and I'm trying to figure out how to set a custom title based on four values from Advanced Custom Fields:

  • a "Corporate?" checkbox;
  • a Corporate Name text field (if Corporate is checked);
  • a combination of Given Names and Surnames text fields (if Corporate is unchecked).

I'm using this function to put together the full name for the Admin columns, for example:

function biwp_contributor_name($post_id) {
    $corporate = get_field('biwp_corporate', $post_id ); //get Corporate checkbox value
    if ($corporate) { //if Corporate is checked, use biwp_cname (Corportate Name)
        $name = get_field('biwp_cname', $post_id );
    } else { //if Corporate is unchecked, use biwp_gnames (Given Names) and biwp_snames (Surnames)
        $gnames = get_field('biwp_gnames', $post_id );
        $snames = get_field('biwp_snames', $post_id );
        $name = $gnames .' '. $snames;
    }
    return $name;
}

And that works great for display purposes. But the problem is that a lot of things in WP rely on the default title, so it would be much better to use that function to actually create the post title (and slug) instead.

I've seen a few other threads on this topic, tried a few different solutions, but to no avail. This one is derived from posts in this ACF forum thread:

add_filter('acf/update_value', 'biwp_fix_contributor_title', 10, 3);

function biwp_fix_contributor_title( $value, $post_id, $field ) {
    if (get_post_type($post_id) == 'contributor') {

        $name = biwp_contributor_name($post_id);
        $new_title = $name;
        $new_slug = sanitize_title( $new_title );

        // update post
        $biwp_contributor = array(
            'ID'          => $post_id,
            'post_title'  => $new_title,
            'post_name'   => $new_slug,
        );  

        if ( ! wp_is_post_revision( $post_id ) ){
            // unhook this function so it doesn't loop infinitely
            remove_action('save_post', 'biwp_fix_contributor_title');
            // update the post, which calls save_post again
            wp_update_post( $biwp_contributor );
            // re-hook this function
            add_action('save_post', 'biwp_fix_contributor_title');
        }

    }   

    return $value;
}

And this one is from this SE thread:

add_action('save_post', 'biwp_fix_contributor_title', 12);

function biwp_fix_contributor_title ($post_id) {
    if ( $post_id == null || empty($_POST) )
        return;

    if ( !isset( $_POST['post_type'] ) || $_POST['post_type']!='contributor' )  
        return; 

    if ( wp_is_post_revision( $post_id ) )
        $post_id = wp_is_post_revision( $post_id );

    global $post;  
    if ( empty( $post ) )
        $post = get_post($post_id);

    if ($_POST['biwp_corporate']!='') {
        global $wpdb;
        $name = biwp_contributor_name($post_id);
        $where = array( 'ID' => $post_id );
        $wpdb->update( $wpdb->posts, array( 'post_title' => $name ), $where );
    }
}

But neither seems to actually do anything—not even a negative, undesired effect—which really makes me wonder.

Thanks in advance for any help.

0

2 Answers 2

1

The acf/update_value filter won't work as it's meant for modifying the acf value and not the post it's associated with. Try using the acf/save_post action instead. Here's a simplified example of how I'd normally set the post title from first and last name fields in acf.

add_action( 'acf/save_post', 'biwp_set_title_from_first_last_name', 20 );

function biwp_set_title_from_first_last_name( $post_id ) {
    $post_type = get_post_type( $post_id );

    if ( 'contributor' == $post_type ) {
        $first_name = get_field( 'biwp_first_name', $post_id );
        $last_name = get_field( 'biwp_last_name', $post_id );

        $title = $first_name . ' ' . $last_name; 

        $data = array(
            'ID'         => $post_id,
            'post_title' => $title,
            'post_name'  => sanitize_title( $title ),
        );

        wp_update_post( $data );
    }
}

Note the priority of 20 used in the action. A priority of less than 10 will hook into the acf/save_post action before ACF has saved the $_POST data. While a priority greater than 10 will hook into the acf/save_post action after ACF has saved the $_POST data. I'm using 20 so I can access the acf data that's been saved.

Looking at the docs, Version 5.6.0 of acf has just added a parameter called $values which is an array containing the field values. You could use this to get the acf values directly instead of using get_field.

5
  • Thanks for your answer. I couldn't get it to work, but after tinkering with it a bit I found out that the method of updating the title was working, but not the method of grabbing the ACF values nor the post type. If I remove the $post_type check and set the $title to a string, for example, it updates properly. It seems that, for some reason, neither get_field nor get_post_type are working, even though the $post_id is being passed in properly. Any idea why, or how to get around it?
    – Shed Simas
    Aug 18, 2017 at 20:38
  • Have you used 20 as the priority for the action? It's hard to pinpoint why it's not working in your situation. I'd suggest logging the values of $post_id and $post_type to see what's going on. Set WP_DEBUG and WP_DEBUG_LOG to true in your wp-config.php file. There's a Debugging WordPress article in the codex if you need more info. Once you've done that use error_log( print_r( $post_type, true ) ); to see what values you're working with.
    – Dylan
    Aug 18, 2017 at 23:18
  • Thanks Dylan. So, hah, get_post_type wasn't working because of a simple typo. But get_field still won't work. If I use error_log( print_r( $name, true ) ); for any of the name variables, I get an empty line in the error log. And I've tried every variation of get_field I can think of… using the field name vs. the field key as the first argument, with and without $post_id in the second argument, all coming back empty. I've read over the ACF documentation on get_post multiple times, checked and rechecked the field names and keys. Not sure what else to check.
    – Shed Simas
    Aug 19, 2017 at 0:27
  • What's the priority of your action?
    – Dylan
    Aug 19, 2017 at 1:53
  • 20, as per your suggestion. I have now posted this same question in the ACF forums (since now it is definitely ACF-specific), so if I hear back from them I'll post the solution here.
    – Shed Simas
    Aug 19, 2017 at 19:21
0

I went off of Dylan's answer and modified the pieces that you said were not working for you. This checks to make sure that the post has value for the acf field you are using to populate values rather than checking the post type. This solution worked for me and I hope it does for you as well.

add_action( 'acf/save_post', 'set_title', 20 );

function set_title( $post_id ) {

    if (get_post_meta( $post_id, 'contributor', true )) {

        $title = get_post_meta( $post_id, 'contributor', true );

        $data = array(
            'ID'         => $post_id,
            'post_title' => $title,
            'post_name'  => sanitize_title( $title ),
        );

        wp_update_post( $data );
    }
}

Your Answer

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

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