Support

Account

Home Forums ACF PRO Map ACF blocks with ACF fields

Unread

Map ACF blocks with ACF fields

  • Hello to all ! 🙂

    I am looking to get all the field types used in a template file without creating the block in the administration.

    For example I want to import a block with the following code:
    get_template_part('gutenberg/' . $block_name . '/template');

    And this file contains for example the following code:

    <?php
    $title = get_field('title');
    ?>
    
    <section class="articles">
        <h1><?php echo $title ?></h1>
    </section>

    But by doing this, I can’t read any data because this block obviously doesn’t exist in my website.

    I want to display the block with custom data, for example a title like “Lorem Ipsum”, but I need this manipulation to be done in such a way that I can use it for any template and any type of ACF data without needing a database (a lot of complications).

    The goal is to extend this idea and create a gallery of ACF blocks.

    What I have done so far is, I think, too complex and not scalable. It works but the complexity of the algorithm is too exponential to be reasonable:

    <?php
    
    /**
     * Check if a field group can be mapped to a block name
     */
    function kiitoss_field_group_is_in_block($block_name, $field_group)
    {
        // get the locations of the field group
        $field_group_locations = $field_group['location'];
    
        $is_inside_locations = false;
    
        // loop through locations groups
        // each location group is a "OR" selector between multiple locations
        foreach ($field_group_locations as $or_locations) {
            // no location means the field is not in the current block
            if (!count($or_locations)) continue;
    
            $is_inside_all_locations = true;
    
            // loop through locations
            // each location subgroup is a "AND" selector between multiple locations
            foreach ($or_locations as $and_locations) {
                // check if the current block is inside the field location
                if ($and_locations['param'] != 'block' || $and_locations['operator'] != '==' || $and_locations['value'] != $block_name) {
                    $is_inside_all_locations = false;
                }
            }
    
            // useless to continue if the field is inside all the locations
            if ($is_inside_all_locations) {
                $is_inside_locations = true;
                break;
            }
        }
    
        return $is_inside_locations;
    }
    
    /**
     * Map the field groups to the ACF blocks
     */
    function kiitoss_generate_field_groups_mapped_to_blocks()
    {
        global $field_groups_mapped_to_blocks;
        // retrieve the ACF registered block types
        $block_types = acf_get_block_types();
    
        // retrieves all the ACF field groups
        $field_groups = acf_get_field_groups();
    
        $field_groups_mapped_to_blocks = array();
    
        // loop through block the ACF block types
        foreach ($block_types as $block_type) {
            // retrieve the block name
            $block_name = $block_type['name'];
            // loop through field groups of the block type
            foreach ($field_groups as $field_group) {
                if (kiitoss_field_group_is_in_block($block_name, $field_group)) {
                    $field_groups_mapped_to_blocks[$block_name][] = $field_group;
                }
            }
        }
    }
    add_action('acf/init', 'kiitoss_generate_field_groups_mapped_to_blocks');
    
    /**
     * Set a default value for auto generated ACF fields
     */
    function kiitoss_acf_load_field($value, $post_id, $_field)
    {
    
        global $current_field_groups;
    
        // get the field type
        $type = $_field['type'];
    
        // directly return the valye in some cases
        if (is_admin() || $value || $type || !$current_field_groups) return $value;
    
        $found = false;
    
        // loop through the global variable $current_field_group
        foreach ($current_field_groups as $field_group) {
            // get the fields of the group and loop through it
            $fields = acf_get_fields($field_group['key']);
            foreach ($fields as $field) {
                // check the ID correspondance
                if ($field['name'] == $_field['name']) {
                    // update the field type
                    $type = $field['type'];
                    $found = true;
                    break;
                }
            }
            if ($found) break;
        }
    
        // update the render value depending of the field type
        switch ($type) {
            case 'text':
                return 'Lorem ipsum';
            case 'email':
                return '[email protected]';
            default:
                return $value;
        }
    }
    add_filter('acf/load_value', 'kiitoss_acf_load_field', 10, 3);

    Does anyone have a better algorithm idea or maybe a better way to do it? With some existing features that I haven’t discovered yet?

    Thank you for your time ! 🙂

Viewing 1 post (of 1 total)

You must be logged in to reply to this topic.