InnerBlock 未保存在自制的自定义插件中

问题描述 投票:0回答:1

我对 WP 开发有点陌生。我正在尝试构建自己的插件,其中有自定义块类型供我使用。我已经将每个自定义博客的 js 文件设置为具有编辑器的 html 和样式。并且客户端代码已经放在php文件中了。

我现在遇到的问题是我正在尝试构建自己的英雄块,我在其中添加了 InnerBlocks 标签。我允许使用另一个名为 GenericHeader 的自定义块。我可以将 GenericHeader 添加到编辑器中的 Hero 块中,保存时一切似乎都按预期工作。但是当我刷新 GenericHeader 块时,它就消失了。我不确定我错过了什么,但话又说回来,我不太习惯 WP 开发,所以我可能在这里做了一些完全错误的事情。

Hero.js 文件

import "./hero-block.scss"
import {InnerBlocks} from "@wordpress/block-editor"

// custom block type hero
wp.blocks.registerBlockType("dotnyma-custom-blocks/hero", {
    title: "Hero",
    icon: "image",
    category: "common",
    attributes: {
        imageUrl: {type: "string"},
    },
    edit: EditHeroComponent,
    save: function () {
        return null;
    }
});


function EditHeroComponent(props) {
    const {attributes, setAttributes} = props;

    return (
        <>
            <div className="hero-editor-container">
                <img src={attributes.imageUrl} alt='test'/>
                <div className="hero-editor-content-container">
                    <InnerBlocks allowedBlocks={['dotnyma-custom-blocks/generic-header']} />
                </div>
            </div>
        </>
    )
}


hero.php 文件

<?php

class HeroBlock
{
    function heroBlockRender($attributes, $content, $block_class): string
    {
        $item_count = count($block_class->inner_blocks);

        if ( $item_count < 1 ) {
            return '<h1>No blocks found</h1>';
        }

        wp_enqueue_style('customBlockTypesStyles');
        ob_start();
        ?>
        <div class="hero-editor-container">
            <img src="<?php echo esc_html($attributes['imageUrl'])?>" alt='test'/>
            <div class="hero-editor-content-container">
               <?php
                   // iterate over the available inner blocks
               for ($index = 1; $index <= $item_count; $index++) :

                   // Get the inner block data
                   $inner_block = $block_class->inner_blocks->current();

                   // Holds the inner block attribute
                   $attribute = $inner_block->attributes;

                   // This will display the attributes data
                   var_dump($attribute);

                   // increase the index in the WP_Block_List class used to retrieve the current block
                   $block_class->inner_blocks->next();
               endfor;
               // reset the index in the WP_Block_List class to the initial state
               $block_class->inner_blocks->rewind();
               ?>
            </div>
        </div>
        <?php return ob_get_clean();
    }
}

?>

genericHeader.js

import "./generic-header.scss"
import { RichText }  from "@wordpress/block-editor";

// custom block type hero
wp.blocks.registerBlockType("dotnyma-custom-blocks/generic-header", {
    title: "Generic header",
    icon: "image",
    category: "common",
    attributes: {
        text: { type : "string"},
        size: { type : "string", default: "large" }
    },
    edit: EditGenericHeaderComponent,
    save: function () {
        return null;
    }
});


function EditGenericHeaderComponent(props) {
    const {attributes, setAttributes} = props;

    function handleTextChange(event) {
        console.log(event);
        setAttributes( {text: event} );
    }

    return (
        <>
            <RichText tagName={"h1"} value={attributes.text} onChange={handleTextChange}/>
        </>
    )
}

genericHeader.php 文件

<?php
class GenericHeaderBlock
{
    function genericHeaderRender(): string
    {
        wp_enqueue_style('customBlockTypesStyles');
        ob_start();
        ?>
        <h1>this is working</h1>
        <?php return ob_get_clean();
    }
}
?>

索引.js

import "./index.scss"
import "./blocks/hero/hero-block"
import "./blocks/generic-header/generic-header"

index.php

<?php

/*
    Plugin Name: ****************
    Description: **************
    Version: 1.0
    Author: ***********
    Author URI: ***********
*/

if (!defined('ABSPATH')) exit;

include (__DIR__ . "/src/blocks/hero/hero-block.php");
include (__DIR__ . "/src/blocks/generic-header/generic-header.php");

class DotNymaCustomBlocks
{
    function __construct()
    {
        add_action('init', array($this, 'customBlockAssets'));
    }

    function customBlockAssets(): void
    {
        $heroBlock = new HeroBlock();
        $genericHeaderBlock = new GenericHeaderBlock();

        wp_register_style('customBlockTypesStyles', plugin_dir_url(__FILE__) . 'build/index.css');
        wp_register_script('customBlockTypes', plugin_dir_url(__FILE__) . 'build/index.js', array('wp-blocks', 'wp-element', 'wp-editor'));

        register_block_type('dotnyma-custom-blocks/hero', array(
            'editor_script' => 'customBlockTypes',
            'editor_style' => 'customBlockTypesStyles',
            'render_callback'  => [ $heroBlock, 'heroBlockRender' ]
        ));
        register_block_type('dotnyma-custom-blocks/generic-header', array(
            'editor_script' => 'customBlockTypes',
            'editor_style' => 'customBlockTypesStyles',
            'render_callback' => [$genericHeaderBlock, 'genericHeaderRender']
        ));
    }
}

$dotNymaCustomBlocks = new DotNymaCustomBlocks();
?>

php wordpress wordpress-gutenberg gutenberg-blocks
1个回答
0
投票

Innerblocks需要保存在

save
组件中。保存组件负责渲染 HTML,该 HTML 将被保存为帖子或页面的内容,然后可以渲染到前端。

拥有

render_callback
并不是完成这项工作所必需的。但是,
render_callback
对于添加需要服务器端渲染的任何其他逻辑(例如获取最新帖子)非常有用。在这种情况下,可以在
$content
render_callback
参数中访问保存的 HTML。

import "./hero-block.scss"
import { useBlockProps, useInnerBlocksProps } from "@wordpress/block-editor"
import { registerBlockType } from "@wordpress/blocks";

registerBlockType("dotnyma-custom-blocks/hero", {
  title: "Hero",
  icon: "image",
  category: "common",
  attributes: {
    imageUrl: { type: "string" },
  },
  allowedBlocks: ["dotnyma-custom-blocks/generic-header"],
  edit: EditHeroComponent,
  save: SaveHeroComponent
});


function EditHeroComponent(props) {
  const { attributes, setAttributes } = props;
  const blockProps = useBlockProps({
    className: 'hero-editor-container'
  });

  const innerBlocksProps = useInnerBlocksProps({
    className: 'hero-editor-content-container'
  });

  return (
    <div {...blockProps}>
      <img src={attributes.imageUrl} alt='test' />
      
      <div {...innerBlocksProps} />
    </div>
  )
}

function SaveHeroComponent(props) {
  const { attributes } = props;
  const blockProps = useBlockProps.save({
    className: 'hero-editor-container'
  });

  const innerBlocksProps = useInnerBlocksProps.save({
    className: 'hero-editor-content-container'
  });

  return (
    <div {...blockProps}>
      <img src={attributes.imageUrl} alt='test' />
      
      <div {...innerBlocksProps} />
    </div>
  )
}
© www.soinside.com 2019 - 2024. All rights reserved.