Forum Replies Created

  • Right, exit! That did the trick.

    I can’t generate a value for return in acf_form() prior to calling it, as part of the process is a check to see if the user is already registered (even if he’s not logged in). This might get changed later, and if it is I’d definitely prefer go this route instead of wp_redirect() -> exit.

  • I think I got it: if I move the is_user_logged_in() part to the bottom of the form, just before the submit button, it correctly passes the user ID to acf_create_new_user(). I suppose that all those instances of acf_form() reset the post ID?

    Do you have any thoughts on my other question, why wp_redirect() isn’t working after form submission? To reiterate, I don’t want to use acf_form( 'return' => 'some-url' ) because the redirects are conditional (e.g. user already exists, user was registered, etc.).

  • Thanks! Got it working, mostly.

    calling acf_form_head() is required before get_header() or before any output is created in header.php

    Noted. I’ve moved this bit to the page template, called it in at right place.

    // if you don’t want the above fields also saved as custom fields for the user

    Regarding unset(), good call. I wish I had done this sooner, now I have hundreds of instances of orphaned post data I have to delete…

    I’ve simplified the code (and also complicated it a bit). It’s solved most issues, created others.

    // set ACF pre-save stuff
    add_filter('acf/pre_save_post' , 'acf_create_new_user' );
    function acf_create_new_user( $post_id ) {
        error_log( 'post id: ' . $post_id);
        // // exit if user already logged in, front-end form sent his ID
        // if ( $post_id != 'new' ) {
        //     error_log( 'post not new: ' . $post_id);
        //     // wp_redirect( home_url() );
        //     return $post_id;
        // }
        $field_group = acf_get_fields_by_id('302');
        //prepare basic user info
        foreach ( $field_group as $key => $value ) {
            $$value['name'] = $_POST['acf'][$value['key']];
        $password           = wp_generate_password( 10, true, false );
        $username           = $candidate_email;
        $display_name       = $candidate_given_name_romaji . ' ' . $candidate_family_name_romaji;
        // check if user exists, exit if so
        if ( email_exists( $candidate_email ) ) {
            error_log( 'email exists: ' . $candidate_email );
            wp_redirect( home_url() . '/sign-up/?email_exists&user_email=' . $candidate_email );
            return $candidate_email;
        // register user
        $user_id = wp_create_user( $username, $password, $candidate_email );
        error_log( 'guy just created: ' . $user_id );
        // update other user info
        wp_update_user( array(
            'ID'            => $user_id,
            'first_name'    => $candidate_given_name_romaji,
            'last_name'     => $candidate_family_name_romaji,
            'display_name'  => $display_name
        ) );
        // update other user meta, prevent creation of post data
        foreach ( $field_group as $key => $value ) {
            update_user_meta( $user_id, $value['name'], $_POST['acf'][$value['key']] );
            unset( $_POST['acf'][$value['key']] );
        // redirect to login page after finish
        wp_redirect( home_url() . '/sign-in/?new_user=true&user_email=' . $candidate_email );
        return 'user_' . $user_id;

    (1) // exit if user already logged in bit has been commented out because it just grabs the ID of the page, not the post data. I can’t remember if this was working before.

    (2) wp_redirect() bits are not working. I know I can add redirects to acf_form() but they’re conditional: a successful registration will go to one place and an unsuccessful one will go elsewhere.

    Please note, the way I use acf_form() code has changed. I ran into some issues with calling in an entire field group and had to call in the fields one-by-one. It looks like this:

    // ensures that user is not logged in
    if ( is_user_logged_in() == true ) : 
        global $current_user;
        $user_id = 'user_' . $current_user->ID;
    else : $user_id = 'new';
    acf_form( array(
        'post_id' => $user_id,
        'form' => false,
    ) );

    Then further down the page I have a bunch of these:

    acf_form( array(
        'fields' => array('some_acf_field'),
        'form' => false,
    ) );
  • It would be something that simple, wouldn’t it! Below is what I ended up using:

    $attrs = array(
        'id'      => $field['id'],
        'name'    => $field['name'],
    <select <?php echo implode( ' ', array_map(function($val, $key) { return sprintf( '%1$s="%2$s"', $key, esc_attr($val) ); }, $attrs, array_keys( $attrs ))); ?>>
        foreach ($languages as $language) {
            ?><option value=<?php echo '"' . $language['tag'] . '"'; if($language['tag'] == $field['value']): ?> selected="selected"<?php endif; ?>><?php echo $language['name']; ?></option><?php

    Credit to

  • I did. Was just referring to the original file name so people could identify it.

  • I was trying to do the same thing a while ago. Couldn’t figure out how to do it natively in ACF so I just made a normal PHP array, sorted it, then looped through it.

    Full credit to the following (my solution is basically these stuck together):

    // check if the repeater field has rows of data
    if( have_rows('person_repeater') ):
        $personArray = get_field('person_repeater');
        function callback( $a, $b ) {
            if ( $a['person_group'] > $b['person_group'] ) {
                return 1;
            } else if ( $a['person_group'] < $b['person_group'] ) {
                return -1;
            return 0;
        uasort( $personArray, 'callback' );
        foreach ($personArray as $person) {
            Group name: <?php echo $person['person_group']; ?>, Person Name: <?php echo $person['person_name']; ?><br>
    else :
        // no rows found
  • Thanks for confirming.

    I was trying to keep everything in one place but now that I think about it a CPT would be the way to go.

  • The second example was all I needed! Thanks, it works now. Here’s what I ended up using:

    function acf_load_color_field_choices( $field ) {
        $field['choices'] = array();
        $choices = get_field( 'colour_repeater', 'option', false );
        if( have_rows( 'colour_repeater', 'options' ) ): while ( have_rows( 'colour_repeater', 'options' ) ) : the_row();
            $choice = get_sub_field( 'colour_name', 'options' );
            $field['choices'][$choice] = $choice;
        $i++; endwhile; endif;
        return $field;
    add_filter( 'acf/load_field/name=colours', 'acf_load_color_field_choices' );
  • Hi James,

    Ends up that I cannot use the field names, for the reason that you mentioned.

    I want to use acf_form() but I couldn’t get it to work for me. It’s not really a big issue, as I found a workaround.

    Below is the end product. I’m pretty satisfied with this (in that it works), but any further suggestions/comments are appreciated.

    $some_post = array(
    	'post_title' => 'Title',
    	'post_content' => 'Content',
    	'post_content' => '',
    	'post_status' => 'publish'
    $the_post_id = wp_insert_post($some_post);
    update_field('field_111111111111', 'Tom', $the_post_id);
    update_field('field_222222222222', 'New York', $the_post_id);
    // repeater field with one subfield
    $classs_field_key = 'field_3a3a3a3a3a3a';
    $classs_subfield_key = 'field_3b3b3b3b3b3b';
    $classs_items = array('class 1','class 2','class 3');
    foreach ($classs_items as $classs_items_value) {
    	$classs_value[] = array($classs_subfield_key => $classs_items_value);
    	update_field($classs_field_key, $classs_value, $the_post_id);
    // repeater field with multiple subfields
    $fruit_field_key = 'field_4a4a4a4a4a4a';
    $fruit_subfield_name = 'field_4b4b4b4b4b4b';
    $fruit_subfield_colour = 'field_4c4c4c4c4c4c';
    $fruit_names = array('Banana','Pear','Grape');
    $fruit_colours = array('yellow','green','purple');
    foreach ($fruit_names as $index => $fruit_names) {
    	$fruit_value[] = array($fruit_subfield_name => $fruit_names, $fruit_subfield_colour => $fruit_colours[$index]);
    	update_field( $fruit_field_key, $fruit_value, $the_post_id );
  • Thanks for pointing me towards those resources. I pieced things together and came up with the following…

    $field_key = 'field_123123123123';
    $subfield_key = 'field_456456456456'; // corresponds with my-class-item in my previous post
    $post_id = $the_post_id; // gets current post ID
    $items = array('class 1','class 2','class 3');
    foreach ($items as $items_value) {
    	$value[] = array($subfield_key => $items_value);
    	update_field( $field_key, $value, $post_id );

    It’s not a game changer, but is there any way to use the name of the custom field instead of the field key (e.g. “my-class-item” instead of “field_456456456456”)?

  • Many thanks for the clarification. I’m learning how to make templates now but will probably have to go with Pods for this website due to deadlines.

    Thanks again!

  • The xml thing was just a shot in the dark – I was just throwing everything at the wall to see what stuck. I realised later that I didn’t have to use it.

    I’m using the shortcode on 100+ pages, not posts. I just entered it using WP’s built-in editor. This is sort of what I want the pages to do:

    We sell apples. Order your apples to (custom field: city).

    Because you live in (custom field: country), you will incur an import tax of (custom field: tax).

    There are some things you should know about regarding applies in your country… (custom field: paragraph on country-specific apple information)

    (custom field: image of an apple)

    Further research yesterday indicated that I might have to build an entire template just to render custom fields. If that’s what it takes it’s fine – I’ll go ahead and learn it. But I would imagine that by now someone would have built a widget or something that renders custom fields?

Viewing 12 posts - 1 through 12 (of 12 total)