$conf, $runtime; function_exists('chdir') AND chdir(APP_PATH); $r = 'mysql' == $conf['cache']['type'] ? website_set('runtime', $runtime) : cache_set('runtime', $runtime); } function runtime_truncate() { global $conf; 'mysql' == $conf['cache']['type'] ? website_set('runtime', '') : cache_delete('runtime'); } register_shutdown_function('runtime_save'); ?>setAttribute For Nested Array in Wordpress Block Plugin Not Updating|Programmer puzzle solving
最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

setAttribute For Nested Array in Wordpress Block Plugin Not Updating

matteradmin9PV0评论

I am new to this area. I am just testing and working with the syntax to learn while slowly progressing to a functional block plugin. I have started this test project from one of the templates provided by the Wordpress Block Plugin beginner guide.

I have an array nested inside of another attribute array that I want to dynamically update.

I am creating a new array of the attribute to update then attempting to set the attribute but it is not updating.

I am not sure if its how my block.json is set or other syntax. Below is my block.json

{
"$schema": ".json",
"apiVersion": 3,
"name": "create-block/copyright-date-block",
"version": "0.1.0",
"title": "Copyright Date Block",
"category": "widgets",
"description": "My new description here...",
"example": {},
"attributes": {
    "rowCount": {
        "type": "number",
        "default": 0
    },
    "content": {
        "type": "array",
        "source": "query",
        "default": [],
        "query": {
            "cells": {
                "type": "array",
                "default": [],
                "source": "query",
                "query": {
                    "text": {
                        "type": "string",
                        "source":"html"
                    }
                }
            }
        }
    }
},
"supports": {
  "color": {
    "background": true,
    "text": true
    },
    "html": true,
    "typography": {
        "fontSize": true
    }
},
"textdomain": "copyright-date-block",
"editorScript": "file:./index.js",
"render": "file:./render.php",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css",
"viewScript": "file:./view.js"
  }

Below is my edit.js. In the function to update the content attribute, I have a console readout to validate the array is correct. The console reads perfectly fine. The issue is the content attribute doesn't update in the Wordpress database.

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';
import { InspectorControls, RichText } from '@wordpress/block-editor';
import { PanelBody, TextControl } from '@wordpress/components';
import { __experimentalNumberControl as NumberControl } from '@wordpress/components';
export default function Edit( { attributes, setAttributes } ) {

const { rowCount, content } = attributes;
const blockProps = useBlockProps();

function updateArray(arr, attributes){

    var test = attributes.content;
    var cells = ["one", "two"];
    test.push({cells});
    setAttributes({rowCount : arr});
    setAttributes({content : test});
    console.log(attributes.content[0]['cells'][0]);
}

function updateText(idx, index, text, attributes){
    {blockProps}
    //console.log(index + " = " + text);
    var oldArr = attributes.content;        
    oldArr[index][idx] = text;
    setAttributes( { content: oldArr });
}

return (
    <>
        <InspectorControls>
            <PanelBody title={ __( 'Settings', 'copyright-date-block' ) }>
                <NumberControl
                    __next40pxDefaultSize
                    spinControls='native'
                    label = { __('Configure row count')}
                    isShiftStepEnabled={ true }
                    onChange={ ( value ) =>
                        updateArray(value, attributes) }
                    shiftStep={ 1 }
                    value={ parseInt(rowCount) }
                />
            </PanelBody>
        </InspectorControls>
        
        <div { ...blockProps }>
                
                    { content.map((item, index) => {
                            return (
                                item['cells'].map((innerContent, idx) => {
                                    return (
                                            <RichText
                                                className= { "blah_" + idx }
                                                tagName="p"
                                                value={ innerContent + " - " + idx + " - " + index }
                                                allowedFormats={ [ 'core/bold', 'core/italic' ] } 
                                                onChange={ ( value ) => updateText(idx, index, value, attributes) } 
                                                placeholder={ __( '?...' ) } 
                                            />
                                            
                                            )   
                                        })
                                )
                        })
                    }
                    
                
        </div>
        
    </>
    
);
}

No matter how different I change the setAttributes line for the content attribute, it don't update in the database. Only the rowCount attribute updates.

Below is what is in the Wordpress database for post content while testing.

Ex. if I update the line incremented 4 times to update the rowCount, the rowCount attribute updates properly. Just not the content attribute.

<!-- wp:create-block/copyright-date-block {"rowCount":"4"} /-->

As stated before, I am attempting dynamic rendering using render.php that just echos a var_dump of $content attribute for now until I get this to work.

Any help would be appreciated.

I am new to this area. I am just testing and working with the syntax to learn while slowly progressing to a functional block plugin. I have started this test project from one of the templates provided by the Wordpress Block Plugin beginner guide.

I have an array nested inside of another attribute array that I want to dynamically update.

I am creating a new array of the attribute to update then attempting to set the attribute but it is not updating.

I am not sure if its how my block.json is set or other syntax. Below is my block.json

{
"$schema": "https://schemas.wp/trunk/block.json",
"apiVersion": 3,
"name": "create-block/copyright-date-block",
"version": "0.1.0",
"title": "Copyright Date Block",
"category": "widgets",
"description": "My new description here...",
"example": {},
"attributes": {
    "rowCount": {
        "type": "number",
        "default": 0
    },
    "content": {
        "type": "array",
        "source": "query",
        "default": [],
        "query": {
            "cells": {
                "type": "array",
                "default": [],
                "source": "query",
                "query": {
                    "text": {
                        "type": "string",
                        "source":"html"
                    }
                }
            }
        }
    }
},
"supports": {
  "color": {
    "background": true,
    "text": true
    },
    "html": true,
    "typography": {
        "fontSize": true
    }
},
"textdomain": "copyright-date-block",
"editorScript": "file:./index.js",
"render": "file:./render.php",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css",
"viewScript": "file:./view.js"
  }

Below is my edit.js. In the function to update the content attribute, I have a console readout to validate the array is correct. The console reads perfectly fine. The issue is the content attribute doesn't update in the Wordpress database.

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';
import { InspectorControls, RichText } from '@wordpress/block-editor';
import { PanelBody, TextControl } from '@wordpress/components';
import { __experimentalNumberControl as NumberControl } from '@wordpress/components';
export default function Edit( { attributes, setAttributes } ) {

const { rowCount, content } = attributes;
const blockProps = useBlockProps();

function updateArray(arr, attributes){

    var test = attributes.content;
    var cells = ["one", "two"];
    test.push({cells});
    setAttributes({rowCount : arr});
    setAttributes({content : test});
    console.log(attributes.content[0]['cells'][0]);
}

function updateText(idx, index, text, attributes){
    {blockProps}
    //console.log(index + " = " + text);
    var oldArr = attributes.content;        
    oldArr[index][idx] = text;
    setAttributes( { content: oldArr });
}

return (
    <>
        <InspectorControls>
            <PanelBody title={ __( 'Settings', 'copyright-date-block' ) }>
                <NumberControl
                    __next40pxDefaultSize
                    spinControls='native'
                    label = { __('Configure row count')}
                    isShiftStepEnabled={ true }
                    onChange={ ( value ) =>
                        updateArray(value, attributes) }
                    shiftStep={ 1 }
                    value={ parseInt(rowCount) }
                />
            </PanelBody>
        </InspectorControls>
        
        <div { ...blockProps }>
                
                    { content.map((item, index) => {
                            return (
                                item['cells'].map((innerContent, idx) => {
                                    return (
                                            <RichText
                                                className= { "blah_" + idx }
                                                tagName="p"
                                                value={ innerContent + " - " + idx + " - " + index }
                                                allowedFormats={ [ 'core/bold', 'core/italic' ] } 
                                                onChange={ ( value ) => updateText(idx, index, value, attributes) } 
                                                placeholder={ __( '?...' ) } 
                                            />
                                            
                                            )   
                                        })
                                )
                        })
                    }
                    
                
        </div>
        
    </>
    
);
}

No matter how different I change the setAttributes line for the content attribute, it don't update in the database. Only the rowCount attribute updates.

Below is what is in the Wordpress database for post content while testing.

Ex. if I update the line incremented 4 times to update the rowCount, the rowCount attribute updates properly. Just not the content attribute.

<!-- wp:create-block/copyright-date-block {"rowCount":"4"} /-->

As stated before, I am attempting dynamic rendering using render.php that just echos a var_dump of $content attribute for now until I get this to work.

Any help would be appreciated.

Share Improve this question asked May 6 at 8:40 Russell SjoblomRussell Sjoblom 111 bronze badge 0
Add a comment  | 

3 Answers 3

Reset to default 1

Thank you for everyones support but I figured out my wrong doing. I needed to look back at the Wordpress Block Editor Handbook. I needed to remove the "source":"query" from the top content attribute so the contents data would go into the blocks comment delimiter with rowCount.

Below is what I needed for it to work.

    "content": {
        "type": "array",
        "default": [],
        "query": {
            "cells": {
                "type": "array",
                "default": [],
                "source": "query",
                "query": {
                    "text": {
                        "type": "string",
                        "source": "text"

                    }
                }
            }
        }
    }

Merge both updates in one setAttributes call

setAttributes({
    rowCount: arr,
    content: test
});

The setAttributes should work with multiple lines. Just make sure to adjust the data handling in your updateArray function accordingly, so that the contents are correctly added.

Here's a little tip to help you out.

An example (not tested):

function updateArray(arr, attributes) {
        const cells = ['one', 'two'];

        // Safely create a new array from existing content or initialize as empty
        const oldContent = Array.isArray(attributes.content)
            ? [...attributes.content]
            : [];

        // Add a new row
        oldContent.push({ cells });

        // Update the attributes
        setAttributes({ rowCount: arr, content: oldContent });

        // Optional: log safely
        if (oldContent[0] && Array.isArray(oldContent[0].cells)) {
            console.log(oldContent[0].cells[0]);
        }
    }
Post a comment

comment list (0)

  1. No comments so far