Hi,
I would like to know how could i use ACF to create reusable component fields that can be managed from one place, let’s say inside the options page.
I’ve tried using clone fields for that but the values don’t get synced between the main and the clones. No matter if the slug has a prefix or not.
Right now i’ve created a way in which i use ACF prepare_field filter. This works for simple fields but i’m not sure how could i use the same logic on for example repeater fields.
Here’s the code i’m running right now
add_filter('acf/prepare_field', function($field){
$current_screen = get_current_screen();
if($current_screen && $current_screen->id == 'toplevel_page_theme-settings') return $field;
$components = get_field('components', 'option');
foreach($components as $component){
if(array_key_exists($field['_name'], $component)){
if(isset($field['sub_fields'])){
foreach($field['sub_fields'] as $field_key => $sub_field){
foreach($component[$field['_name']] as $sub_component){
if(array_key_exists($sub_field['_name'], $sub_component)){
//$field['sub_fields'][$field_key]['value'] = $sub_component[$sub_field['_name']];
//consoleLog([$field, $sub_field, $sub_component[$sub_field['_name']]]);
}
}
}
}else{
$field['value'] = $component[$field['_name']];
}
}
}
return $field;
},10,3)
And here’s the ACF output for components field group
{
"key": "field_638edca18a922",
"label": "Components",
"name": "",
"aria-label": "",
"type": "tab",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"placement": "left",
"endpoint": 0
},
{
"key": "field_638edcad8a923",
"label": "Components",
"name": "components",
"aria-label": "",
"type": "flexible_content",
"instructions": "Reusable components that can be managed from one place",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"layouts": {
"layout_638edcb3c4b41": {
"key": "layout_638edcb3c4b41",
"name": "get_in_touch",
"label": "Get In Touch",
"display": "block",
"sub_fields": [
{
"key": "field_638edcc28a924",
"label": "Heading",
"name": "get_in_touch_heading",
"aria-label": "",
"type": "textarea",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"maxlength": "",
"rows": 3,
"placeholder": "",
"new_lines": ""
},
{
"key": "field_638edcd28a925",
"label": "Button",
"name": "get_in_touch_button",
"aria-label": "",
"type": "link",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"return_format": "array"
}
],
"min": "",
"max": ""
},
"layout_638f209874700": {
"key": "layout_638f209874700",
"name": "icon_group",
"label": "Icon group",
"display": "block",
"sub_fields": [
{
"key": "field_638f20b774701",
"label": "Icon group",
"name": "icon_group",
"aria-label": "",
"type": "repeater",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"layout": "table",
"min": 0,
"max": 0,
"collapsed": "",
"button_label": "Add Row",
"rows_per_page": 20,
"sub_fields": [
{
"key": "field_638f20ca74702",
"label": "Icon",
"name": "icon",
"aria-label": "",
"type": "image",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"return_format": "array",
"library": "all",
"min_width": "",
"min_height": "",
"min_size": "",
"max_width": "",
"max_height": "",
"max_size": "",
"mime_types": "",
"preview_size": "thumbnail",
"parent_repeater": "field_638f20b774701"
},
{
"key": "field_638f20da74703",
"label": "Background",
"name": "background",
"aria-label": "",
"type": "color_picker",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"enable_opacity": 0,
"return_format": "string",
"parent_repeater": "field_638f20b774701"
}
]
}
],
"min": "",
"max": ""
}
},
"min": "",
"max": "",
"button_label": "Add component"
}
For “Get In Touch” gield group it works but for “Icon Group” i’m not sure how to exactly achieve that.
I’m having a similar issue to this ticket. I’m using ACF and Timber with a renderCallback function. This works fine and seems to load the template on the front end but doesn’t seem to work in the editor. I get ‘Your site doesnβt include support for the “acf/[blockname]” block. You can leave this block intact or remove it entirely.’ errors in the editor even though the blocks load on the front-end. It even pulls in the field data that existed before I switched to block.json on the front-end only.
/button/block.json
{
"name": "acf/button",
"title": "Button",
"description": "A button block.",
"category": "dream",
"icon": "button",
"keywords": ["button", "buttons", "button group"],
"attributes": {
"blockId": {
"type": "string"
}
},
"usesContext": [ "buttonGroup/blockId" ],
"supports": {
"jsx": true,
"align": true,
"alignContent": true,
"alignText": true,
"anchor": true,
"className": true,
"multiple": true,
"html": false,
"inserter": true,
"color": {
"text": false,
"background": true,
"link": false,
"gradients": true,
"linkColor": true
},
"fontSize": true,
"fullHeight": false
},
"styles": [
{ "name": "default", "label": "Default", "isDefault": true },
{ "name": "other", "label": "Other" }
],
"editorScript": "file:./index.js",
"script": "file:./script.js",
"editorStyle": "file:./index.css",
"style": "file:./style.css",
"acf": {
"mode": "preview",
"renderCallback": "dream_block_render",
"postTypes": true,
"parent": "acf/button-group",
"reusable": true
}
}
I also get a js error in the console when editing pages whether or not blocks exist on the page:
acf-pro-blocks.min.js?ver=6.0.3:formatted:783 Uncaught TypeError: Cannot read properties of undefined (reading 'length')
at _ (acf-pro-blocks.min.js:783:51)
at Array.map (<anonymous>)
at acf-pro-blocks.min.js?ver=6.0.3:1419:24
at o (acf.min.js?ver=6.0.3:1:1417)
at Object.doAction (acf.min.js?ver=6.0.3:1:587)
at n.doAction (acf.min.js?ver=6.0.3:1:18745)
at post.php?post=1521&action=edit:3223:5
Looks like it may be related to the “attributes” key so maybe I’m just doing something wrong but I’m unsure.
Line 783 of acf-pro-blocks.min.js
for (const t in e.attributes)
0 === e.attributes[t].default.length && delete e.attributes[t].default;
e.supports.anchor && (e.attributes.anchor = {
type: "string"
});
## Issue
When duplicating an ACF block (registered with acf_register_block_type
) data between the blocks can switch place and/or regress. Repeater fields and expander toggles stop working. No javascript error is shown in console.
## Environment
PHP 7.4.21
WP 5.8.1
ACF Pro 5.10.2
## Reproduce
1. Create ACF Field Group
acf_add_local_field_group(array(
'key' => 'group_614c3a15115de',
'title' => 'Test Block',
'fields' => array(
array(
'key' => 'field_614c3c7d9b75e',
'label' => 'Test Field',
'name' => 'test_field',
'type' => 'text',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'default_value' => '',
'placeholder' => '',
'prepend' => '',
'append' => '',
'maxlength' => '',
),
),
'location' => array(
array(
array(
'param' => 'block',
'operator' => '==',
'value' => 'acf/test-block',
),
),
),
'menu_order' => 0,
'position' => 'acf_after_title',
'style' => 'default',
'label_placement' => 'top',
'instruction_placement' => 'label',
'hide_on_screen' => '',
'active' => true,
'description' => '',
'is_acf_component' => 0,
'acf_component_defaults' => array(
'repeatable' => '0',
'min' => '',
'max' => '',
'layout' => 'block',
'button_label' => '',
'appearances' => '',
),
));
2. Register ACF Block
acf_register_block_type(array(
'name' => 'test_block',
'title' => __('Test Block'),
'description' => __('Test Block'),
'render_template' => 'template-parts/content_builder-test.php',
'category' => 'formatting',
));
3. Create template file in render_template
location with the contents: <?php the_field('test_field');
3. Navigate to Widgets wp-admin/widgets.php
4. Add new ‘Test Block’
5. Duplicate ‘Test Block’ a few times.
6. Edit the contents of the fields, toggle between Edit/Preview.
## Expected Result
All fields and admin elements should work as normal.
## Actual Result
The preview does not align with the content, when switching back to edit, the value in the field may have changed too. The ‘Update’ button often is not triggered to an active state. When managing to save, reloading shows the widgets in a different state to when you left it.
## Extra
Copying the contents into a reusable block, editing then copy/pasting back in does not work. (Reusable blocks are not supported in the Widgets interface just yet.)
## Work around
Create all blocks from scratch within the widgets interface.
Thank you.
Issue
When duplicating an ACF block (registered with acf_register_block_type
) data between the blocks can switch place and/or regress. Repeater fields and expander toggles stop working. No javascript error is shown in console.
Environment
PHP 7.4.21
WP 5.8.1
ACF Pro 5.10.2
Reproduce
1. Create ACF Field Group
acf_add_local_field_group(array(
'key' => 'group_614c3a15115de',
'title' => 'Test Block',
'fields' => array(
array(
'key' => 'field_614c3c7d9b75e',
'label' => 'Test Field',
'name' => 'test_field',
'type' => 'text',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'default_value' => '',
'placeholder' => '',
'prepend' => '',
'append' => '',
'maxlength' => '',
),
),
'location' => array(
array(
array(
'param' => 'block',
'operator' => '==',
'value' => 'acf/test-block',
),
),
),
'menu_order' => 0,
'position' => 'acf_after_title',
'style' => 'default',
'label_placement' => 'top',
'instruction_placement' => 'label',
'hide_on_screen' => '',
'active' => true,
'description' => '',
'is_acf_component' => 0,
'acf_component_defaults' => array(
'repeatable' => '0',
'min' => '',
'max' => '',
'layout' => 'block',
'button_label' => '',
'appearances' => '',
),
));
2. Register ACF Block
acf_register_block_type(array(
'name' => 'test_block',
'title' => __('Test Block'),
'description' => __('Test Block'),
'render_template' => 'template-parts/content_builder-test.php',
'category' => 'formatting',
));
3. Create template file in render_template
location with the contents: <?php the_field('test_field');
3. Navigate to Widgets wp-admin/widgets.php
4. Add new ‘Test Block’
5. Duplicate ‘Test Block’ a few times.
6. Edit the contents of the fields, toggle between Edit/Preview.
Expected Result
All fields and admin elements should work as normal.
Actual Result
The preview does not align with the content, when switching back to edit, the value in the field may have changed too. The ‘Update’ button often is not triggered to an active state. When managing to save, reloading shows the widgets in a different state to when you left it.
Extra
Copying the contents into a reusable block, editing then copy/pasting back in does not work. (Reusable blocks are not supported in the Widgets interface just yet.)
Work around
Create all blocks from scratch within the widgets interface.
Thank you.
Let’s say I have a field group called “Call To Action” with the name “cta”. This group contains a Text field, a URL field, and a checkbox called “Open in new window”.
I also have a Home Page field group that needs this “Call To Action” group cloned into the Hero tab, the Content Teaser tab, and the Promo tab. If I choose “Seamless” as the cloning method, I will have 3 field groups labeled “Call To Action”, which is great. But these groups will all be named “cta” and have the exact same field key, which obviously will cause problems. If I choose “Group” as the cloning method, it will nest my “Call To Action” group into another group, which I do not want.
Cloning could be a very useful feature for creating reusable groups (that act like modules), but this limitation of not being able to specify a custom name when using “Seamless” makes it very limited. If I want all of my “Call To Action” fields inside a group with a unique name and key, I need to use the “Group” cloning mode and select each individual field to clone into it. Later, if I decide to add another field into the master “Call To Action” group, I would need to go to every clone instance and add that field into it. That really takes away a major advantage of creating reusable elements (being able to edit all instances in a single place).
If we could input a custom field name when using the “Seamless” cloning mode, that would make these fields so much more useful as a templating tool. Or maybe there’s a way to do this that I’m missing?