Support

Account

Home Forums Backend Issues (wp-admin) Replacing custom post type post title with an acf?

Solved

Replacing custom post type post title with an acf?

  • Hello,

    I’m just starting out with ACF, and I’d like to use it to replace a lot of the functionality within WordPress to allow my clients to be able to easily update areas of their site.

    One problem that I’m having, that I can’t seem to find the answer to is; is it possible to replace the WordPress title with a custom field created using advanced custom fields? When I remove the title field from my custom post type, I just get some ‘Auto Draft’ Posts.

    Thanks,
    Steph

  • Hi @stephw

    Yes. You can use an action called acf/update_value to hook in and run some custom functionality for the saving of a value.

    Please read up on this action on the ACF docs, and then hook into the field via it’s key and use the updated value to update the post with.

    WP contains functions to update the post data sich as title, content, etc.

    Thanks
    E

  • Ah excellent! I thought there must be something!

    Thank you.

  • @stephw
    I came accross you posts / rely: I also wanted to hide the ‘Title’ from the backend form, as it acts as a duplicate of 2 collated fields (firstname & last name…). Obviously the title is the post name so is needed.
    Could you please share the way you set up the title value, without having to input it ?
    I understand the ACF hooks system, similar to theWP logic, but am not comfortable with it at all yet (where to I how, which hoo to use, how to I collate the 2 values befofore saving the form…?
    Many thanks
    JMB

  • Hi @jmb

    You should use the ‘acf/update_value’ filter. Docs here: http://www.advancedcustomfields.com/resources/filters/acfupdate_value/

    You should target the second field, not the first. I’m guessing this is ‘last_name’.

    In your filter function, you can get the last_name value from $value (a parameter of the function), and you can get the ‘first_name’ via a standard get_field function.

    Hope that helps.

    Thanks
    E

  • Hi @elliot,
    Many thanks for your reply.
    I’ll tweak this function/hook to see if I can understand the way it works.
    I do have a question , though:
    the “field” I need to change is the post_name, which obviously goes into the WP_POST Table of the DB. If I understand correctly, this should be the $value from the hook function ? & the aggregated ‘data’ (ie. something like get_field(‘firstname’).” “.get_field(‘lastname’)) should be the $field parameter of the function ? & How do I get the $post_id ?
    Sorry if I sound thick, lol !
    I’d like to var_dump() either the WP_post post before it gets recorded to see what the variable / object hold . When & how should I do this ?

    Many thanks again for your help.

  • Hi @jmb

    Lets start with the above filter I linked you to. This filter will demonstrate ho you can get the post_id and $value.

    You can run a debug script within the function like so to test the value before saving it

    
    echo '<pre>';
    	print_r( $value );
    echo '</pre>';
    die;
    

    Thanks
    E

  • @elliot,
    Thanks for the headsup, I put the folllowing hook in my functions.php file but nothing happened: Looks as if the hook was disregarded / ineffective:

    
    function my_acf_update_value( $value, $post_id, $field  )
    {
        //$value = "Custom value";
     
        // do something else to the $post object via the $post_id
     
        //return $value;
    	echo '<pre>';
    	print_r( $value );
    echo '</pre>';
    die;
    }
    // acf/update_value - filter for every field
    add_filter('acf/update_value', 'member_lastname', 10, 3);
    

    I cant be using it properly to get the value from ‘m’mber_lastname’…?

  • Hi @js

    Your filter is attaching a function called ‘member_lastname’, but your function is actually called ‘my_acf_update_value’.

    These need to match for obvious reasons.

    Thanks
    E

  • Hi @Elliot,
    stupid mistake !
    So I got the 2 below hooks / filters below running fine, each returning the proper member_lastname & member_firstname value, one after the other, when I ‘publish the field set.
    At this point the WP_post /Post is created, but needs to be updated with the proper values, ie.
    – for the post_name a slug => member_firstname.”-“.member_firstname;
    – for the post_title => member_firstname.” “.member_firstname;

    add_filter('acf/update_value/name=member_lastname', 'my_acf_update_value', 10, 3);
    add_filter('acf/update_value/name=member_firstname', 'my_acf_update_value', 10, 3);

    So :
    – how do I keep both values from the previous hooks, so that I can use them to build both the above variables ?
    – do I need to build yet another hook to update the wp_post table, & “where / when” should this happen ? I guess when ACF completes the publishing / update of the wp_postmeta table ?

    Agin, many thanks for your help on this
    Regards,
    JMB

  • Hi @stephw

    Because the ‘member_lastname’ is saved AFTER the ‘member_firstname’ (order of fields), you can simply hook into just the lastname filter and run your code there like so:

    
    <?php 
    
    function my_acf_update_value( $value, $post_id, $field ) {
    	
    	// vars
    	$new_title = get_field('member_firstname', $post_id) . ' ' . $value;
    	$new_slug = santize_title( $new_title );
    	
    	// update post
    	// http://codex.wordpress.org/Function_Reference/wp_update_post
    	
    	
    	
    }
    
    add_filter('acf/update_value/name=member_lastname', 'my_acf_update_value', 10, 3);
    
     ?>
    

    I’ll leave the updata_post bit to you.

    Cheers
    E

  • HI @Elliot, and thanks for your reply.

    the ‘get_field (‘member_firstname’) does not seem to recall the field, when used inside this function… the rest works perfectly :
    – composing the $new_title & slug;
    – update of the wp_post with $post_id, – of course W/O the “member_firstname field value…!-:

    $my_post = array('ID'=> $post_id,'post_title' => $new_title,'post_name' => $new_slug );
    wp_update_post( $my_post );

    Another related question is how do I proceed to call this hook / function when / if the fieldset is updated (as opposed to just ‘created’) to reflect the change in member_last / firstname should these fields be changed?

  • Hi @stephw

    The update_value filter will be run each time the value is changed, not only for just created.

    I can’t explain why the get_field function is not working… perhaps you will need to use a more basic get_postmeta function from WP? Or perhaps get the value from $_POST?

    Thanks
    E

  • Hi @Elliot!
    Thanks for the udate.
    I’ve tweaked the function some & found out that, for some reason, including $\POST in the function makes it work !
    Even if the $_POSRT does not contain the field ‘memeber_firstname per se…I guess the get_field function than can refer to the field name, with it’s corresponding value in the postmeta table :

    <?php
    function my_acf_update_value( $value, $post_id, $field ) {
    	global $_POST;
    	// vars
    
    	$new_title = get_field('member_firstname', $post_id) . ' ' . $value;
    	$new_slug = sanitize_title( $new_title );
    
    	// update post
    	// http://codex.wordpress.org/Function_Reference/wp_update_post
    	  $my_post = array(
          'ID'           => $post_id,
          'post_title' => $new_title,
    	  'post_name' => $new_slug
      );
    
    // Update the post into the database
      wp_update_post( $my_post );
    	
    	
    }
    
    add_filter('acf/update_value/name=member_lastname', 'my_acf_update_value', 10, 3);
    
    ?>

    Thanks for all !
    I intend to post a full & clear how-to post on this solution as it may come in handy to anyone else.Obviously won’t take the credit for any of it ! 🙂

    Thanks again
    JMB

  • Hi JMB,

    have you published something about it? I tried to follow your code but there is some strange behaviour with it…

    I mean, if I update a title I’ll get both values, the old one and the new one as title of my post.

    Ive tried a var_dump() on the $value and I noticed that this will be printed twice, the first string contains the new value and the second will contain both…

    Can someone will help me up with this?

    BTW I am using the ACF PRO 5.0.5

  • I’ve got this working just as desired with regular text fields, but I’m having trouble doing it with a repeater. I’m using a repeater because the columns make the layout a lot cleaner, but there’s only a single row. The repeater has 3 sub fields, all text. Here’s my latest attempt:

    
    function sk_acf_update_pocket_postdata( $value, $post_id, $field ) {
    	global $_POST;
    	
    	$pocket_name_fields = $value[0];
      
    	$head_brand = $pocket_name_fields['head_brand'];
    	$head_name = $pocket_name_fields['head_name'];
    	$pocket_type = $pocket_name_fields['pocket_type'];
      
    	$pocket_title = $head_brand . ' ' . $$head_name . ' ' . $pocket_type;
    	$pocket_slug = sanitize_title( $pocket_title );
      
      $pocket_postdata = array(
        'ID'          => $post_id,
        'post_title'  => $pocket_title,
    	  'post_name'   => $pocket_slug
      );
      
      wp_update_post( $pocket_postdata );
    	
    	return $value;
    	
    }
    
    add_filter('acf/update_value/key=field_53f7a5039c2a8', 'sk_acf_update_pocket_postdata', 10, 3);
    

    The field key I’m using is for the repeater. I was using a field key for one of the sub fields, and was able to pull that value in successfully, but I wasn’t able to pull in the other two values using get_the_field_object.

    Any help would be greatly appreciated.

  • Follow up to my own question. I’ve got this working as desired, but I want to post my code below in case it’s useful to anyone, and to make sure I’m doing this right.

    
    function sk_acf_update_pocket_postdata( $value, $post_id, $field ) {
    	global $_POST;
    	
    	$pocket_name_fields = get_field('pocket_name', $post_id)[0];
      
    	$head_brand = $pocket_name_fields['head_brand'];
    	$head_name = $pocket_name_fields['head_name'];
      
    	$pocket_title = $head_brand . ' ' . $head_name . ' ' . $value;
    	$pocket_slug = sanitize_title( $pocket_title );
      
      $pocket_postdata = array(
        'ID'          => $post_id,
        'post_title'  => $pocket_title,
    	  'post_name'   => $pocket_slug
      );
      
      wp_update_post( $pocket_postdata );
    	
    	return $value;
    	
    }
    
    add_filter('acf/update_value/key=field_53f7a5369c2ab', 'sk_acf_update_pocket_postdata', 10, 3);
    

    I changed the field key I’m hooking into to the last sub field in the repeater. If I used the other two, it would only rewrite the title and slug after hitting update for a second time.

    Still seems a little strange and inelegant, but it’s working. I welcome feedback of any kind.

    BTW, thanks @Elliot for building and maintaining such an incredible tool. It has completely changed how I work.

  • And now a brand new problem. Any idea why this would break the site when pushed to a remote server? It says the issue is with the “[” character on the line $pocket_name_fields = get_field('pocket_name', $post_id)[0];, but I don’t know why that would be.

    Databases are the same… field key is the same… what am I missing?

  • Edit: [SOLVED] It is enogh use the $value and store it even if the var_dump( $value ) gives me two strings.

    Hi @Elliot,

    as you can notice I have some trouble regarding the hook add_filter('acf/update_value/name=long_tit');

    I am customizing your functionality in order to remove the default WordPress title and set it (and the slug) with the info I can get from a text field.

    You can check all the code at this Gist (https://gist.github.com/AndreaBarghigiani/aac1f96a95dc03d7a100) but the thing I do not understand is why my value is been repeated. Here is an example of a var_dump() on the variable that will contain get_field('titolo_lunghissimo', $post_id) . ' ' . $value;

    string(5) " Test" string(9) "Test Test"

    Why it is set as two string instead of one? And why I can’t put my hands on the first string?

    Can you help me up with this?

    Thanks in advance for the tool and for the help

  • Hi, thanks so much for this. Helped a lot! But I need some help here, please.

    I want my title to have not only the ACF field value, but also the custom taxonomy I’ve created called “pico”. When I run this code,

    function my_acf_update_value( $value, $post_id, $field ) {
    	
      $terms = wp_get_post_terms($post_id, 'pico');
    
      $pico = false;
      foreach($terms as $term)
      {
          if($term->parent)
          {
              $parent = get_term($term->parent, 'pico');
              $pico = $term->name;
              break;
          }
      }
      //Default to first selected term name if no children were found
      $pico = $pico ? $pico : $terms[0]->name;
    
    	$new_title = $pico . ' - ' . $value;
    	$new_slug = sanitize_title( $new_title );
    	
    	// Update post
      $my_post = array(
          'ID'           => $post_id,
          'post_title'   => $new_title,
          'post_name'		 => $new_slug,
      );
    
    	// Update the post into the database
      wp_update_post( $my_post );
    	
    	return $value;
    }
    
    add_filter('acf/update_value/name=data_do_boletim', 'my_acf_update_value', 10, 3);

    it gives me these error messages:

    Notice: Undefined offset: 0 in /Users/Mauricio/Sites/RicoSurf/wp-content/themes/ricosurf/functions.php on line 219

    Notice: Trying to get property of non-object in /Users/Mauricio/Sites/RicoSurf/wp-content/themes/ricosurf/functions.php on line 219

    Warning: Cannot modify header information – headers already sent by (output started at /Users/Mauricio/Sites/RicoSurf/wp-content/themes/ricosurf/functions.php:219) in /Users/Mauricio/Sites/RicoSurf/wp-includes/pluggable.php on line 1196

    But when I go back and see that post, the title is perfect, exactly the way I want.

    So I assume the code “is working” just not 100%. Can some one help me find out what’s wrong?

  • I was trying to accomplish something similar. Here is how I did it.

    My PHP is rusty so if you spot any improvements please do let me know.

    I wanted to populate my post title to combine two custom fields: first-name and last-name

    function custom_field_value_as_title( $value, $post_id, $field ) {
    	global $_POST;
    	// vars
    
    	$new_title_first_name = get_field('first-name', $post_id);
    	$new_title_last_name = get_field('last-name', $post_id);
        $new_title = "$new_title_last_name, $new_title_first_name";
    	//$new_slug = sanitize_title( $new_title );
    
        $result = 
    
    	// update post
    	// http://codex.wordpress.org/Function_Reference/wp_update_post
    	  $my_post = array(
          'ID'         => $post_id,
          'post_title' => $new_title,
    	  'post_name'  => $post_id //originally $new_slug
      );
    
    // Update the post into the database
      wp_update_post( $my_post );
    }
    
    add_filter('acf/update_value', 'custom_field_value_as_title', 10, 3);

    The result in the post title is last-name, first-name. For example: “Obama, Barack”

  • Oh dear… Something peculiar happened. The code I posted above was working fine for V4 but I just updated to V5 PRO and suddenly every time I hit update or publish, ALL fields are cleared and return to holding no value.

    Any advice would be greatly appreciated.

    Many thanks.

  • This reply has been marked as private.
  • A variation of what has been posted worked for us. Unlike others we seemed to be getting trapped in an infinite loop. Here is a solution derived from some information on the WP codex. Maybe it can help you out:

    function person_update_title( $value, $post_id, $field ) {
    	
    	$new_title = get_field( 'person_first_name', $post_id) . ' ' . $value;
    	$new_slug = sanitize_title( $new_title );
    	
    	// update post
    	$person_postdata = 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', 'person_update_title');
    	
    		// update the post, which calls save_post again
    		wp_update_post( $person_postdata );
    
    		// re-hook this function
    		add_action('save_post', 'person_update_title');
    	}	
    	
    	return $value;
    }
    
    add_filter('acf/update_value/name=person_last_name', 'person_update_title', 10, 3);

    (If this is a duplicate, please kill it. Having troubles navigating the interwebs)

  • I’ve moved my comment.

Viewing 25 posts - 1 through 25 (of 30 total)

The topic ‘Replacing custom post type post title with an acf?’ is closed to new replies.