Hi,
I’ve solved this problem now, in case anyone is interested, this is what I did:
1) I removed source/query etc. from the attributes so that the attributes would not be stored in the html but as JSON in the comments of the block’s content.
2) I changed the top level save function to return the innerblock as follows:
import { InnerBlocks } from ‘@wordpress/block-editor’;
export default function save() {
return <InnerBlocks.Content />;
}
3) I changed the inner block’s save to return null:
export default function Save() { return null; }
4) I changed the PHP as follows, the comments explain what’s going on (I hope):
<?php
/**
* Plugin Name: Cards
* Description: A generic cards block
* Requires at least: 5.9.3
* Requires PHP: 7.0
* Version: 0.1.0
* Author: Stephen Bugden
* License: GPL-2.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: generic-cards
*
* @package netmonics
*/
function render_html($attributes, $content, $post) {
$post = get_post($post_id);
// = parse_blocks($post->post_content);
ob_start(); ?>
<!-- <h1>Attributes<?php echo esc_html(var_dump($attributes)) ?>!</h3>
<h3>The number of columns is <?php echo esc_html($attributes['myColumns']) ?>!</h3>
<h2>The content is:</h2><p><?php echo esc_html($content) ?>!</p>
<h2>The content is </h2><p><?php echo esc_html(get_the_content()) ?>!</p>
<h2>The content is </h2><p><?php echo var_dump(parse_blocks( get_the_content() )) ?>!</p>
<h2>The post is </h2><p><?php echo var_dump($post) ?>!</p> -->
<!-- Write out the block's content -->
<h2>The content is </h2><p><?php echo esc_html(get_the_content()) ?>!</p>
<?php
// $parsed_blocks = parse_blocks($post->post_content);
// echo '<pre><h2>parsed blocks </h2>';
// print_r($content);
// echo '</pre>';
//Load the block's content
$dom1 = new DOMDocument;
$dom1->loadHTML(get_the_content());
$xpath1 = new DOMXpath($dom1);
echo "<h1>Comments</h1>";
//Get the comments
$comments = $xpath1->query('.//comment()', $dom1);
//Filter out the the comments for the InnerBlocks
$commentPrefix = "wp:netmonics/generic-card {";
$JSON = "";
foreach($comments as $comment){
if (substr( trim($comment->nodeValue.PHP_EOL), 0, strlen($commentPrefix) ) === $commentPrefix) {
//Add a comma to the end of each line except for the last line
if ($JSON !== "") {
$JSON = $JSON . ",";
}
//Retrieve the JSON from the comment
$JSON .= substr( $comment->nodeValue.PHP_EOL,strlen($commentPrefix), strlen($comment->nodeValue.PHP_EOL) - strlen($commentPrefix) - 3 );
}
}
//Create an array for the details
$JSON = '{"card-details": [' . $JSON . ']}';
echo $JSON;
//Create a JSON object from the JSON string
$decoded_json = json_decode($JSON, true);
$cardDetails = $decoded_json['card-details'];
echo "<br><br>";
//Loop through the JSON write out the details.
foreach($cardDetails as $cardDetail) {
echo 'Name: ' . $cardDetail['name'] . "<br>";
echo 'Bio: ' . $cardDetail['bio'] . "<br>";
echo 'Description: ' . $cardDetail['description'] . "<br>";
$socialLinks = $cardDetail['socialLinks'];
if (!is_null($socialLinks))
{
if (!empty($socialLinks)) {
// list is not empty.
echo "<br>";
foreach($socialLinks as $socialLink)
{
echo ' icon:' . $socialLink['icon'] . "<br>";
echo ' link:' . $socialLink['link'] . "<br>";
echo "<br>";
}
}
}
echo "<br>";
}
return ob_get_clean();
}
function cards_init() {
register_block_type_from_metadata( __DIR__, array(
'render_callback' => 'render_html'
) );
}
add_action( 'init', 'cards_init' );
See the content contains the JSON for the innerblocks:
The content is
<!– wp:block {"ref":4939} /–> <!– wp:block {"ref":6275} /–> <!– wp:kadence/rowlayout {"uniqueID":"_0bfc30-08","columns":1,"colLayout":"equal","inheritMaxWidth":true} –> <div class="wp-block-kadence-rowlayout alignnone"><div id="kt-layout-id_0bfc30-08" class="kt-row-layout-inner kt-layout-id_0bfc30-08"><div class="kt-row-column-wrap kt-has-1-columns kt-gutter-default kt-v-gutter-default kt-row-valign-top kt-row-layout-equal kt-tab-layout-inherit kt-m-colapse-left-to-right kt-mobile-layout-row kb-theme-content-width"><!– wp:kadence/column {"uniqueID":"_3ab532-7c"} –> <div class="wp-block-kadence-column inner-column-1 kadence-column_3ab532-7c"><div class="kt-inside-inner-col"><!– wp:netmonics/generic-cards –> <!– wp:netmonics/generic-card {"name":"Phil","bio":"bio","id":10676,"url":"https://netmonics6.local/wp-content/uploads/2022/05/Phil-14.jpg","socialLinks":[{"icon":"facebook","link":"https://facebook.com"},{"icon":"twitter","link":"https://twitter.com"}]} /–> <!– wp:netmonics/generic-card {"name":"Robert","bio":"bio","id":10679,"url":"https://netmonics6.local/wp-content/uploads/2022/05/Robert-8.jpg"} /–> <!– wp:netmonics/generic-card {"name":"Steve","bio":"bio","id":10680,"url":"https://netmonics6.local/wp-content/uploads/2022/05/Steve-Not-Despeckled-4.jpg"} /–> <!– /wp:netmonics/generic-cards –></div></div> <!– /wp:kadence/column –></div></div></div> <!– /wp:kadence/rowlayout –>!
The JSON strings combined into an array:
Comments
{“card-details”: [{“name”:”Phil”,”bio”:”bio”,”id”:10676,”url”:”https://netmonics6.local/wp-content/uploads/2022/05/Phil-14.jpg”,”socialLinks”:[{“icon”:”facebook”,”link”:”https://facebook.com”},{“icon”:”twitter”,”link”:”https://twitter.com”}]} ,{“name”:”Robert”,”bio”:”bio”,”id”:10679,”url”:”https://netmonics6.local/wp-content/uploads/2022/05/Robert-8.jpg”} ,{“name”:”Steve”,”bio”:”bio”,”id”:10680,”url”:”https://netmonics6.local/wp-content/uploads/2022/05/Steve-Not-Despeckled-4.jpg”} ]}
The values extracted from the JSON object:
Name: Phil
Bio: bio
Description:
icon:facebook
link:https://facebook.com
icon:twitter
link:https://twitter.com
Name: Robert
Bio: bio
Description:
Name: Steve
Bio: bio
Description:
So now I have the attributes stored as JSON. The save can be rewritten as PHP so now changes appear instantly without having to refresh each instance of the block and changes to the HTML won’t break the block.
I did get stuck for a while because I didn’t realise that the innerblock was registered with the same name as another block. This meant that my changes weren’t picked up and it took me a while to realise what was going on. That explains why I wasn’t seeing the JSON in the content, as commented on above.
I hope this all makes sense. Finally, my dream of creating blocks which update on the fly and don’t easily break seems possible.
Best Regards,
Steve
-
This reply was modified 2 years, 6 months ago by Yui.
-
This reply was modified 2 years, 6 months ago by Yui. Reason: formatting