Using custom field as custom post title

I’ve setup a custom post type with a series of custom fields using the WPAlchemy class. I’m trying to take the value of one of the custom fields and use that as the post title. So far, though, I’ve had no success. I’ve been browsing around and I’ve tried the following two different blocks of code:

function custom_post_type_title ( $post_id ) {
    global $wpdb;
    if ( get_post_type( $post_id ) == 'listing' ) {
        $title = get_post_meta($post_id, 'listing_name', true);
        $where = array( 'ID' => $post_id );
        $wpdb->update( $wpdb->posts, array( 'post_title' => $title ), $where );
    }
}

add_action('init', 'listing_save_post');
function listing_save_post( $post_id ) {
        if ( ! defined( 'DOING_AUTOSAVE' ) && ! DOING_AUTOSAVE ) return;
        add_action('save_post', 'custom_post_type_title', 100);
        add_action('publish_post', 'custom_post_type_title', 100);
}

And.. (temporarily commenting out the nonce fields until I figure out how they work)

Read More
add_filter('wp_insert_post_data', 'change_title', 99, 2);
function change_title($data, $postarr)
{    
    // If it is our form has not been submitted, so we dont want to do anything
    if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;

    // Verify this came from the our screen and with proper authorization because save_post can be triggered at other times
   // if(!isset($_POST['my_nonce_field'])) return;

    // If nonce is set, verify it
   // if(isset($_POST['my_nonce_field']) && !wp_verify_nonce($_POST['my_nonce_field'], plugins_url(__FILE__))) return;

       // Combine address with term
    $title = $_POST['listing_name'];
    $data['post_title'] = $title;

    return $data;
}

In both cases, the results are the same:

  1. On saving the new post, it reloads the page, says it worked, and all of the custom fields are empty. (Without either code set running, the custom post works just fine and the fields are saved).

  2. On viewing the custom post type index, the posts aren’t there.

Any ideas?

UPDATE

To clarify, I am using a custom post without the title support. I am trying to populate the title field nonetheless, though, using the value in the custom field.

Related posts

Leave a Reply

2 comments

  1. So, every time you save a post, you want to replace the value of a title that just got saved with another value from a custom field…

    Seems like you should just put whatever you what the title to be in the actual title field.

    BUT I’m assuming this is for presentational purposes: you want that custom post type to display a different title on the front end based on the value of a custom field. Filters would be an easy way to accomplish this.

    the_title, the common template tag, is a very thin wrapper around get_the_title, which contains a filter called the_title. It gets two arguments: the actual title and the post ID. Hook into that and change the title based on your custom field.

    <?php
    add_filter( 'the_title', 'wpse33385_filter_title', 10, 2 );
    function wpse33385_filter_title( $title, $post_id )
    {
        if( $new_title = get_post_meta( $post_id, 'custom_field_name', true ) )
        {
            return $new_title;
        }
        return $title;
    }
    

    A few things about your code to keep in mind:

    Actions don’t arbitrarily receive arguments. Functions hooked into init for example, don’t get any arguments passed to them. when do_action is called, the first argument is a hook name. Subsequent arguments are what gets passed to hooked in functions if you desire (specified by the fourth, option arguments of add_action).

    the do_action( 'init' ); call is in wp-settings.php. Take a look, no arguments.

    So this:

    <?php
    add_action('init', 'listing_save_post');
    function listing_save_post( $post_id ) {
            if ( ! defined( 'DOING_AUTOSAVE' ) && ! DOING_AUTOSAVE ) return;
            add_action('save_post', 'custom_post_type_title', 100);
            add_action('publish_post', 'custom_post_type_title', 100);
    }
    

    Is not going to work like you expect. Moreover, the add_action calls inside the function, can just be on their own outside the function… This works fine:

    add_action('save_post', 'custom_post_type_title', 100);
    function custom_post_type_title( $post_id ) {
        // do stuff
    }
    

    Only need to do stuff on save_post, not on that and publish_post

    I always try to avoid going directly to $wpdb if I can, because many times there are more convenient APIs. What you were trying to do is updated a post. So use wp_update_post. In your case, that’s not a valid option (as the codex states, it can cause an infinite loop).

    That was kind of long winded, sorry. Hopefully it cleared up some things about the WordPress hooks system!

    Make these your best friends:

  2. Thank you your filter worked a treat.

    FYI

    I added a check to see if in Admin to prevent changing the entry-title to my custom “longtitle” (default = menu-item-title) whilst editing a page.

    function pcdg_filter_title( $title, $post_id )
    {
        if(!is_admin())
        {
            if( $new_title = get_post_meta( $post_id, 'longtitle', true ) )
            {
                return $new_title;
            }
        }
        return $title;
    }
    add_filter( 'the_title','pcdg_filter_title',10,2 );