Support

Account

Home Forums Add-ons Flexible Content Field Populate (same) flexible content layouts with data from other fields of CPT? Reply To: Populate (same) flexible content layouts with data from other fields of CPT?

  • There is no “easy” way to do this. If I had to do this then then I would.

    1) Create my new flexible content fields

    2) Add an acf/load_value filter on the flexible content field

    
    // field_XXXXXXX represents the field key of the flex field
    add_filter('acf/load_value/key=field_XXXXXXX', 'convert_to_flex' 20, 3);
    function convert_to_flex($value, $post_id, $field) {
      // only run in the flex field is empty
      if (!empty($value)) {
        return $value;
      }
      
      // construct flex layouts
      
      return $value;
    }
    

    // construct flex layouts in the above would be replaced code that builds the layouts from the old fields.

    $value is a nested array containing each layout

    
    $value = array(
      // nested array for each layout
      array(
        // acf layout name
        'acf_fc_layout' => 'LAYOUT NAME',
        // field_key => value pairs of each field in layout
        'field_XXXXXXX' => get_field('field_name, $post_id, false'),
        'field_YYYYYYY' => get_field('another_field_name', $post_id, false)
      )
    );
    

    note that we are using the 3rd parameter (false) so that the values are not formatted.

    If your layout contains repeater fields then you would have to loop over the repeater and build another nested array, the array for a repeater is similar to the array for a flex field.

    
    // repeater
    'field_ZZZZZZZ' => array(
      // nested repeater for each row
      array(
        // field_key => value pairs for each sub field
      )
    )
    

    What the above does is that when a post is edited the content will be transferred to the new fields.

    3) Once this is done and I was sure it was working is that I would rebuild my templates but I would leave the old code alone. I would add a check to see if the new layout fields have a value. They should, but you never know.

    
    if (have_rows('new_flex_field')) {
      // new code to show flex fields
    } else {
      // old code for old fields
    }
    

    4) Once I had that done I would then hide all of the original fields using acf/prepare_field filters. I would have an array of all of the old field keys and add a filter for each (DO NOT DELETE THESE FIELDS).

    
    $fields = array(
      'field_AAAAAAA',
      'field_BBBBBBB',
      // etc
    );
    foreach ($fields as $field) {
      add_filter('acf/prepare_field/key='.$field, '__return_false', 20);
    );
    

    5) As the final step I would create an acf/save_post action that deletes all of the old fields using delete_field() calls.

    When you’re done you have a system that will create the new layouts when each post is updated but allow the site and unedited posts to continue running as is, avoiding the need to update every post. At this point I would ignore it and let it run. At some point in the future, once all posts have been converted you might consider deleting the old fields and the old code, but I probably would not look at it again.