wp-graphql / wp-graphql-acf

WPGraphQL for Advanced Custom Fields
https://wpgraphql.com/acf
626 stars 123 forks source link

Clone field support? #57

Closed alexwybraniec closed 11 months ago

alexwybraniec commented 5 years ago

"The Clone field needs some more assessment to determine if it can properly be supported."

Is there a discussion about this anywhere public?

Our use case is we often create an ACF group called Flexible Content (which contains a flexible content field with different options defined in it) and then Clone that into different content types.

When I query this using the plugin, I get an empty array back.

dclawson commented 4 years ago

I'm interested in finding out more about this issue too.

Maybe we can help look into why Clone fields are causing problems?

Arno500 commented 4 years ago

From what I just tested, cloned fields are supported, but not recursively. You can clone a field group in another, but if you are adding one layer (like recloning this field group in some other) fields in GraphQL won't be populated. I don't know if this linked to the ACF API, or just a function that does not recurse.

henrikwirth commented 4 years ago

@jasonbahl There certainly is a lot of bugs in the Clone field still. Just had a similar issue, that breaks the schema completely.

1. If you set your Display options as follows:

image

This will not output anything. The expected behaviour would be to have group with the name of the Clone field, that holds the field values, that have been cloned.

2. If Display is set to Seamless:

image

This will work and populate the fields of the Core Field Group into the layout (flexible_layout).

3. If one instead clones a flexible_content field like so:

image

This will fully break the schema and will output internal server errors.

Here is an ACF export to play with:

[
    {
        "key": "group_5e24492429924",
        "title": "Core",
        "fields": [
            {
                "key": "field_5e24492a9ca5f",
                "label": "Width",
                "name": "width",
                "type": "text",
                "instructions": "",
                "required": 0,
                "conditional_logic": 0,
                "wrapper": {
                    "width": "",
                    "class": "",
                    "id": ""
                },
                "show_in_graphql": 1,
                "default_value": "",
                "placeholder": "",
                "prepend": "",
                "append": "",
                "maxlength": ""
            },
            {
                "key": "field_5e2449379ca60",
                "label": "Has Container",
                "name": "has_container",
                "type": "true_false",
                "instructions": "",
                "required": 0,
                "conditional_logic": 0,
                "wrapper": {
                    "width": "",
                    "class": "",
                    "id": ""
                },
                "show_in_graphql": 1,
                "message": "",
                "default_value": 0,
                "ui": 0,
                "ui_on_text": "",
                "ui_off_text": ""
            }
        ],
        "location": [
            [
                {
                    "param": "post_type",
                    "operator": "==",
                    "value": "post"
                }
            ]
        ],
        "menu_order": 0,
        "position": "normal",
        "style": "default",
        "label_placement": "top",
        "instruction_placement": "label",
        "hide_on_screen": "",
        "active": true,
        "description": "",
        "show_in_graphql": 1,
        "graphql_field_name": "core"
    },
    {
        "key": "group_5decc2241a06d",
        "title": "Page Builder",
        "fields": [
            {
                "key": "field_5decc2474dcfc",
                "label": "Layouts",
                "name": "layouts",
                "type": "flexible_content",
                "instructions": "",
                "required": 0,
                "conditional_logic": 0,
                "wrapper": {
                    "width": "",
                    "class": "",
                    "id": ""
                },
                "show_in_graphql": 1,
                "layouts": {
                    "layout_5decc25b9abd5": {
                        "key": "layout_5decc25b9abd5",
                        "name": "hero",
                        "label": "Hero",
                        "display": "block",
                        "sub_fields": [
                            {
                                "key": "field_5decc2c051eeb",
                                "label": "Image",
                                "name": "image",
                                "type": "image",
                                "instructions": "",
                                "required": 1,
                                "conditional_logic": 0,
                                "wrapper": {
                                    "width": "",
                                    "class": "",
                                    "id": ""
                                },
                                "show_in_graphql": 1,
                                "return_format": "array",
                                "preview_size": "medium",
                                "library": "all",
                                "min_width": "",
                                "min_height": "",
                                "min_size": "",
                                "max_width": "",
                                "max_height": "",
                                "max_size": "",
                                "mime_types": ""
                            },
                            {
                                "key": "field_5decc4477634e",
                                "label": "Text",
                                "name": "text",
                                "type": "text",
                                "instructions": "This text will be placed on top of the image.",
                                "required": 0,
                                "conditional_logic": 0,
                                "wrapper": {
                                    "width": "",
                                    "class": "",
                                    "id": ""
                                },
                                "show_in_graphql": 1,
                                "default_value": "",
                                "placeholder": "",
                                "prepend": "",
                                "append": "",
                                "maxlength": ""
                            },
                            {
                                "key": "field_5decc46e7634f",
                                "label": "Text Color",
                                "name": "text_color",
                                "type": "color_picker",
                                "instructions": "The color of the text. Default is white.",
                                "required": 0,
                                "conditional_logic": 0,
                                "wrapper": {
                                    "width": "",
                                    "class": "",
                                    "id": ""
                                },
                                "show_in_graphql": 1,
                                "default_value": "#FFFFFF"
                            }
                        ],
                        "min": "",
                        "max": ""
                    },
                    "layout_5e24420cf6c60": {
                        "key": "layout_5e24420cf6c60",
                        "name": "section",
                        "label": "Section",
                        "display": "block",
                        "sub_fields": [
                            {
                                "key": "field_5e244216f6c61",
                                "label": "Test Cloned",
                                "name": "test_cloned",
                                "type": "clone",
                                "instructions": "",
                                "required": 0,
                                "conditional_logic": 0,
                                "wrapper": {
                                    "width": "",
                                    "class": "",
                                    "id": ""
                                },
                                "clone": [
                                    "group_5e24492429924"
                                ],
                                "display": "group",
                                "layout": "block",
                                "prefix_label": 0,
                                "prefix_name": 0
                            }
                        ],
                        "min": "",
                        "max": ""
                    },
                    "layout_5decc4a5d2fc7": {
                        "key": "layout_5decc4a5d2fc7",
                        "name": "text_block",
                        "label": "Text Block",
                        "display": "block",
                        "sub_fields": [
                            {
                                "key": "field_5decc4c4d2fc8",
                                "label": "Text",
                                "name": "text",
                                "type": "wysiwyg",
                                "instructions": "",
                                "required": 0,
                                "conditional_logic": 0,
                                "wrapper": {
                                    "width": "",
                                    "class": "",
                                    "id": ""
                                },
                                "show_in_graphql": 1,
                                "default_value": "",
                                "tabs": "all",
                                "toolbar": "full",
                                "media_upload": 1,
                                "delay": 0
                            },
                            {
                                "key": "field_5decc52fd2fca",
                                "label": "Text Color",
                                "name": "text_color",
                                "type": "color_picker",
                                "instructions": "The color of the text. Make sure it has enough contrast to the background color.",
                                "required": 0,
                                "conditional_logic": 0,
                                "wrapper": {
                                    "width": "",
                                    "class": "",
                                    "id": ""
                                },
                                "show_in_graphql": 1,
                                "default_value": "#000000"
                            },
                            {
                                "key": "field_5decc509d2fc9",
                                "label": "Background Color",
                                "name": "background_color",
                                "type": "color_picker",
                                "instructions": "The background color. Make sure it has enough contrast to the text color.",
                                "required": 0,
                                "conditional_logic": 0,
                                "wrapper": {
                                    "width": "",
                                    "class": "",
                                    "id": ""
                                },
                                "show_in_graphql": 1,
                                "default_value": "#FFFFFF"
                            }
                        ],
                        "min": "",
                        "max": ""
                    }
                },
                "button_label": "Add Row",
                "min": "",
                "max": ""
            }
        ],
        "location": [
            [
                {
                    "param": "post_type",
                    "operator": "==",
                    "value": "page"
                }
            ],
            [
                {
                    "param": "post_type",
                    "operator": "==",
                    "value": "post"
                }
            ]
        ],
        "menu_order": 0,
        "position": "normal",
        "style": "default",
        "label_placement": "top",
        "instruction_placement": "label",
        "hide_on_screen": [
            "the_content",
            "discussion",
            "comments",
            "send-trackbacks"
        ],
        "active": true,
        "description": "",
        "show_in_graphql": 1,
        "graphql_field_name": "pageBuilder"
    }
]
degregar commented 4 years ago

@jasonbahl I've added Flexible Content field, let's say "sections", which is cloned in two other groups with prefix: "dynamic" and "static".

If I fill in basic "sections" field, I get by gql query same data in both "dynamic_sections" and "static_sections".

If I add anything to "dynamic" or "static" it doesn't show in results.

I've tried to debug that and found out that:

  1. Here it checks if it's cloned field: https://github.com/wp-graphql/wp-graphql-acf/blob/0d03813bb98ee470aae2bdbe08405c1aa67b087b/src/class-config.php#L282

  2. In the next line https://github.com/wp-graphql/wp-graphql-acf/blob/0d03813bb98ee470aae2bdbe08405c1aa67b087b/src/class-config.php#L283 it gets the key of the "sections" field, the base for cloning.

If I changed that line to: $key = $acf_field['_clone']; and manually echo value of the field, I can get my data.

But it still nulls that value in line

https://github.com/wp-graphql/wp-graphql-acf/blob/0d03813bb98ee470aae2bdbe08405c1aa67b087b/src/class-config.php#L301

And I don't know why is that. Can't easily find what hooks into that filter.

PSalaun commented 3 years ago

I'm adding a case which wasn't obvious to me, if other people are scratching their head about why their clone field isn't working.

If you clone a group of fields (which are not clones themselves) at the root of a field group, their value won't be populated in GraphQL.

query MyQuery {
  pages {
    nodes {
      acfHomepage { <--- field group
          hero { <---- cloned group
            title
            tagline
          }
      }
    }
  }
}

To fix it, I need to wrap the clone in another group field (or a repeater, or flexible layout):

query MyQuery {
  pages {
    nodes {
      acfHomepage { <--- field group
        heroWrapper { <--- group
          hero { <---- cloned group
            title
            tagline
          }
        }
      }
    }
  }
}

which adds an unnecessary (?) layer, here heroWrapper. Then in the front end I need to write smthg like acfHome.heroWrapper.hero.title, which looks kinda weird.

To mitigate this last issue, when I create a field group for a page, I add a global "group" field with no label, and then inside I put my tabs, cloned fields, etc. So it looks like:

query MyQuery {
  pages {
    nodes {
      acfHomepage {
        fields {
          hero {
            title
            tagline
          }
          otherCloneGroup
          normalField
        }
      }
    }
  }
}

then in my template I write const acfData = data.wpPage.acfHomepage.fields, so afterwards I just need to do acfData.hero.title and this feels more natural in the code.

simplenotezy commented 3 years ago

Interesting, thanks for sharing your solution @PSalaun.

So if I understand the issue and temporary quick-fix correctly, the solution is to wrap the cloned field (and perhaps the other "normal non-cloned" fields) inside a group? Without any code customisation?

I use flexible content sections, and I use cloned fields quite heavily, but haven't began to setup the GraphQL part yet.

simplenotezy commented 3 years ago

After having tested the use case, I seem to experience no issues getting out cloned fields inside Flexible Content with GraphQL:

image image image

simplenotezy commented 3 years ago

After testing more, I withdraw my above statement that it works. It works, but only partially.

If I use the button clone inside, say a Repeater, it works fine.

However, if I use the clone directly inside the "Flexible Content" section, it does not show up as a GraphQL Field. However, if I enable the Prefix Field Names it shows up just fine.

A current workaround is to enable the Prefix Field Names:

image

gil0mendes commented 3 years ago

If we add a case 'clone': before case 'group': on the register_graphql_field method, it's possible to use clones was groups. There is any disadvantage of doing this? 🤔

jasonbahl commented 11 months ago

👋🏻 Clone Fields are fully supported in the new version of WPGraphQL for ACF: https://github.com/wp-graphql/wpgraphql-acf

I'm going to close this as we have a solution in the new version of the plugin.

Any bugs/enhancements should be reported as new issues on the new repo as this repo will be archived in the not-too-distant future.