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.
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]);
}
}