AdvancedCustomFields / acf

Advanced Custom Fields
http://advancedcustomfields.com/
823 stars 168 forks source link

get_block_wrapper_attributes() doesn't function properly when a Block is re-rendered after fields are edited #871

Open MadtownLems opened 10 months ago

MadtownLems commented 10 months ago

Describe the bug When using get_block_wrapper_attributes() to generate classes and style attributes for a block based with ACF, the function works as expected when you first open the editor to a Post that contains an ACF block.

Example block output from a basic debugging block (when first opening the editor):

The selected animal is: alligator
The value of get_block_wrapper_attributes is: class="ext-acf-sample-block has-background has-sky-background-color wp-block-acf-ext-sample-block"

Here's the same block's debugging output after simply toggling a Select field in the right hand toolbar:

The selected animal is: cat
The value of get_block_wrapper_attributes is: class="ext-acf-sample-block"

To Reproduce Steps to reproduce the behavior:

  1. Add color support to an ACF block that has one or more editable fields.
  2. Insert the block into a Post and set one or more colors
  3. Update one of the block's editable fields

Expected behavior The block's markup should include the classes from get_block_wrapper_attributes, just as it does when you first edit a page

Code block.json

{
    "name": "acf/ext-sample-block",
    "title": "ACF Sample Block (EXT)",
    "description": "A basic ACF block.",
    "style": "file:./css/ext-acf-sample-block.css",
    "icon": "hammer",
    "category": "widgets",
    "keywords": ["sample", "test"],
    "acf": {
        "mode": "preview",
        "renderTemplate": "block-template.php"
    },
    "supports": {
        "jsx": true,
        "align": true,
        "alignText": true,
        "anchor": true,
        "color": {
            "background": true,
            "text": true,
            "link": true
        },
        "mode": "preview",
        "spacing": {
            "margin": [
                "top",
                "bottom"
            ],
            "padding": true
        }
    },
    "example": {
        "attributes": {
            "mode": "preview",
            "data": {
                "ext_acf_block_preview": 1
            }
        }
    }
}

from block-template.php

// Create class attribute allowing for custom "className".
$class_name = 'ext-acf-sample-block';
if ( ! empty( $block['className'] ) ) {
    $class_name .= ' ' . $block['className'];
}

// process our custom field
$selected = get_field( 'select_an_animal' );

$block_wrapper_attributes = get_block_wrapper_attributes(
    array(
        'class' => esc_attr( $class_name ),
    )
    );
?>

<div
    <?php
    echo wp_kses_data(
        $block_wrapper_attributes
    );
    ?>
>

// i'm having trouble making the opening php tag show in the comment
    echo "The selected animal is: " . $selected ;
    echo "The value of get_block_wrapper_attributes is: " . $block_wrapper_attributes;
// closing php tag here 

</div>

Version Information:

lgladdy commented 10 months ago

This is a known problem. get_block_wrapper_attributes is not supported in the editor, only for front-end output, so should only be used in if ( ! $is_preview ) {

The reason for this is blocks aren't rendered with the the full context of the page and render location which is required for get_block_wrapper_attributes.

For most users, this isn't an issue, as blocks in the editor view will have these attributes automatically added to their container editor by WordPress, and most users will want that $is_preview check anyway for backend previews, to avoid things like padding or margin being applied twice.

For the first preview, that is rendered in the full page context by our cache system, which is why it "seems" to work for preloading.