我对 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();
?>
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>
)
}