@wordpress/create-block 创建多个blocks框架教程

创建自定义的Block的归类,然后注册block的时候在block.json里面将category改成这个:

/**
 * Register custom block category
 *
 * @param array $categories Array of block categories.
 * @param WP_Block_Editor_Context $editor_context The current block editor context.
 * @return array Modified array of block categories.
 */
function my_plugin_register_block_category($categories, $editor_context)
{
	// Add your custom category
	return array_merge(
		$categories,
		array(
			array(
				'slug' => 'material',
				'title' => __('Material Blocks', 'material'),
				'icon' => 'admin-plugins', // Optional: Dashicon name
			),
		)
	);
}
add_filter('block_categories_all', 'my_plugin_register_block_category', 10, 2);

如果只转移的话带有package.json的话就 使用 npm install 进行安装

把模块安装到framework文件夹下面的themeblocks文件夹里, 首先打开framework文件夹,然后用cmd打开,输入下面的命令:

只需要安装一次npm的module模块:

npx @wordpress/create-block@latest my-custom-block –variant dynamic –namespace themeblocks

my-custom-block 是block的名字

你打开themeblocks文件夹,已经安装好了模块blocks开发的框架。

–variant: (两个横线)设置输出为render.php 设置dynamic : 不输出静态内容 输出动态内容

–namespace: 注册block时候的命名空间 比如注册block的时候是 wptutorblocks/my-custom-block。namespace就是block.json里面的name属性。title属性也需要同步更改。

点击确认就能安装模块

如果你要安装多个blocks, 只需要复制src里面的文件夹,更改为你需要的内容即可, 然后输入命令npm run build就可以创建一个自定义的bllock。不需要重新执行npx的命令来安装模块。

文件解释:

所有更改的文件都位于src文件夹里相关的Block的文件,build文件夹是成品文件,修改了有用,但是不建议修改,通过修改src文件夹文件内容之后然后通过命令 npm run build进行webpack即可,或者你开启npm start 命令, 会检测你的修改内容然后自动打包。

package.json:不用改。 最主要的执行命令的文件和加载dependencies依赖的文件

block.json: 主要修改的文件,定义block的全部属性和初始字段以及 编辑器样式文件,输出文件,前端样式文件等内容。 创建字段的文件,block最基础的配置文件,配置字段和block基本信息等,里面配置设置了加载的js和渲染的页面,最新的话渲染适用render.php

"editorScript": "file:./index.js",
  "render": "file:./render.php",
  "editorStyle": "file:./index.css",
  "style": "file:./style-index.css",
  "viewScript": "file:./view.js"

src里面的index.js:基本不用改。 有时候创建的时候没有添加编辑器的样式, 就要新增: import ‘./editor.scss’; 然后去创建editor.scss 文件, 然后里面去添加样式。其为注册block的功能性文件。 通过import引入其他js文件导出的模块

src里面的render.php: 主要动态输出的文件模板。 执行加载编辑和前端输出界面的内容。

styles.css和view.js 执行的是前端的脚本,edit.js和editor.css 加载的是编辑页面的脚本。

如果你选择用editor.scss的话,首先要按照上面说的先去index.js里面去引入editor.scss, 然后你要去block.json里面去创建editorStyle的属性, 值为file:./index.css; 然后打包的时候会自动创建index.css在build文件夹。

通过package.json文件里的build或者start的命令通过wp-script执行webpack-copy-php加载build文件夹里面的blocks-manifest.php 转换成build文件夹中的成品block.

wp-scripts 会检测无限多的block并进行渲染。

主要的php文件里已经通过blocks-manifest.php 循环注册block (记得安装模块时候要安装latest版本)

$manifest_data = require DIR . ‘/build/blocks-manifest.php’;
foreach ( array_keys( $manifest_data ) as $block_type ) {
register_block_type( DIR . “/build/{$block_type}” );
}

Wp加载的都是build里面的成品Block 而不是src文件夹里的。

通过这个方法来加载样式到编辑器:

/**
 * Enqueue block styles for both front-end and editor.
 */
function my_block_enqueue_styles() {
    // Frontend and editor shared styles
    wp_register_style(
        'my-block-style',
        get_template_directory_uri() . '/assets/css/plugins.css',
        array(),
        '1.0.0'
    );

    // Frontend
    wp_enqueue_style('my-block-style');
}
add_action('enqueue_block_assets', 'my_block_enqueue_styles');

如果npm命令失效了查看下面的最新命令

npm run build 执行一次production成品

npm start 监听

WP Script 官方介绍

https://developer.wordpress.org/block-editor/reference-guides/packages/packages-scripts

CRETAE BLOCK 官方介绍

https://developer.wordpress.org/block-editor/reference-guides/packages/packages-create-block

如何在页面上打印出自定义block

$blocks = parse_blocks(get_the_content());
    foreach ($blocks as $block) {
        if (isset($block['blockName']) && $block['blockName'] == 'korvex/hero') {
            echo render_block($block);
            break;
        }
    }

专业方案,重点推荐使用,用函数return方式所以无需break, 将它单独放在函数模板里可以在任何页面调用

// 1. 获取首页内容(优先通过 queried_object 保证拿到首页真实 content)
$front_page_id = get_queried_object_id() ?: (int) get_option('page_on_front');
$page_content  = $front_page_id ? get_post_field('post_content', $front_page_id) : get_the_content();
$blocks        = parse_blocks($page_content);

// 2. 递归查找目标块(避免被 Group/Columns 等容器嵌套时遗漏)
if (!function_exists('wpdemo_find_block')) {
    function wpdemo_find_block(array $block_list, string $target_name) {
        foreach ($block_list as $b) {
            if (isset($b['blockName']) && $b['blockName'] === $target_name) {
                return $b;
            }
            if (!empty($b['innerBlocks'])) {
                $nested = wpdemo_find_block($b['innerBlocks'], $target_name);
                if ($nested) {
                    return $nested;
                }
            }
        }
        return null;
    }
}

$heng_block = wpdemo_find_block($blocks, 'tt/top-heng');

if ($heng_block) {
    echo render_block($heng_block);
} else {
    // 备选方案:如果后台页面未手动添加该块,可通过 do_blocks 输出带默认属性的该块
    // echo do_blocks('<!-- wp:tt/top-heng /-->');
}
?> 

其中,直接输出默认属性的区块,可以作为主体交接时候的默认内容区块展示

echo do_blocks('<!-- wp:tt/top-heng /-->');

更新增强版

/**
 * 递归查找目标块(避免被 Group/Columns 等容器嵌套时遗漏)
 *
 * @param array  $block_list  解析后的块列表 (由 parse_blocks 返回)
 * @param string $target_name 目标块名称 (如 'tt/top-heng', 'tt-theme/idx-about')
 * @return array|null 匹配到的块结构,未找到返回 null
 */
if (!function_exists('wpdemo_find_block')) {
	function wpdemo_find_block(array $block_list, string $target_name)
	{
		foreach ($block_list as $b) {
			if (isset($b['blockName']) && $b['blockName'] === $target_name) {
				return $b;
			}
			if (!empty($b['innerBlocks'])) {
				$nested = wpdemo_find_block($b['innerBlocks'], $target_name);
				if ($nested) {
					return $nested;
				}
			}
		}
		return null;
	}
}

/**
 * 获取指定页面(或当前页/首页)解析后的块列表(带内存静态缓存)
 *
 * @param int|null $post_id 页面 ID,留空则自动获取当前页面(或首页)ID
 * @return array
 */
if (!function_exists('wpdemo_get_page_blocks')) {
	function wpdemo_get_page_blocks($post_id = null)
	{
		static $cached_blocks = [];

		if (null === $post_id) {
			$post_id = get_the_ID() ?: (get_queried_object_id() ?: (int) get_option('page_on_front'));
		}

		$cache_key = (int) $post_id;
		if (isset($cached_blocks[$cache_key])) {
			return $cached_blocks[$cache_key];
		}

		$page_content = $post_id ? get_post_field('post_content', $post_id) : get_the_content();
		$cached_blocks[$cache_key] = !empty($page_content) ? parse_blocks($page_content) : [];

		return $cached_blocks[$cache_key];
	}
}

/**
 * 专门获取首页块列表(即使在内页调用,也总是能获取到首页的块)
 *
 * @param int|null $post_id 页面 ID,留空则默认读取后台设置的首页 ID
 * @return array
 */
if (!function_exists('wpdemo_get_front_page_blocks')) {
	function wpdemo_get_front_page_blocks($post_id = null)
	{
		if (null === $post_id) {
			$post_id = (int) get_option('page_on_front') ?: get_queried_object_id();
		}
		return wpdemo_get_page_blocks($post_id);
	}
}

/**
 * 递归查找并输出指定块(支持任意页面)
 *
 * @param string   $block_name 目标块名 (如 'tt/top-heng', 'tt-theme/idx-about')
 * @param string   $fallback   后台未添加该块时的备选 HTML 或 block 标记
 * @param int|null $post_id    页面 ID(留空为当前页面)
 */
if (!function_exists('wpdemo_render_block')) {
	function wpdemo_render_block(string $block_name, string $fallback = '', $post_id = null)
	{
		$blocks = wpdemo_get_page_blocks($post_id);
		$block  = wpdemo_find_block($blocks, $block_name);

		if ($block) {
			echo render_block($block);
		} elseif (!empty($fallback)) {
			echo do_blocks($fallback);
		}
	}
}

/**
 * 查找并输出首页块(即使在内页调用也可直接渲染首页的块)
 */
if (!function_exists('wpdemo_render_front_block')) {
	function wpdemo_render_front_block(string $block_name, string $fallback = '', $post_id = null)
	{
		if (null === $post_id) {
			$post_id = (int) get_option('page_on_front') ?: get_queried_object_id();
		}
		wpdemo_render_block($block_name, $fallback, $post_id);
	}
}

用法

Viewed functions.php:225-275
Edited functions.php
Ran command: php -l functions.php

The functions in functions.php have been generalized to support any page. Here is how to use them across different templates (e.g., page.php, single.php, footer.php, etc.):


Use Case 1: Render a block from the current page

(Works inside page.php, single.php, or any custom template like page-about.php)

Option A: One-line render

<?php wpdemo_render_block('tt-theme/idx-about'); ?>

Option B: Manual access to block attributes/HTML

<?php
// Automatically gets the current page's blocks
$blocks = wpdemo_get_page_blocks();

$target_block = wpdemo_find_block($blocks, 'tt-theme/idx-about');
if ($target_block) {
    // You can read block attributes:
    // $title = $target_block['attrs']['title'] ?? '';

    // Or render it:
    echo render_block($target_block);
}
?>

Use Case 2: Render a block from a specific Page ID

If you designed a block on one specific page (e.g., Page ID 25) and want to display it on other pages:

Option A: One-line render

<?php 
// 3rd parameter is the Post/Page ID:
wpdemo_render_block('tt-theme/idx-about', '', 25); 
?>

Option B: Manual lookup

<?php
// Pass the specific page ID:
$blocks = wpdemo_get_page_blocks(25);

$target_block = wpdemo_find_block($blocks, 'tt-theme/idx-about');
if ($target_block) {
    echo render_block($target_block);
}
?>

Use Case 3: Pull a block from the Homepage while on an Inner Page

If you are on an inner page (like archive.php, contact.php, or in footer.php) and want to display a section created on the homepage:

<?php 
// This will always pull from the homepage, even when viewed on inner pages:
wpdemo_render_front_block('tt/top-heng'); 
?>

Quick Function Reference in functions.php

FunctionDescription
wpdemo_render_block($name, $fallback = '', $post_id = null)Finds and renders a block on the current page (or specified $post_id).
wpdemo_get_page_blocks($post_id = null)Returns parsed blocks for the current page (or specified $post_id) with static memory caching.
wpdemo_render_front_block($name, $fallback = '')Specifically targets and renders a block from the homepage.
wpdemo_find_block($blocks, $name)Recursively searches any blocks array (including nested columns/groups).

添加了fallback的用法

Searched for "register_block_type"
Viewed functions.php:260-295
Viewed functions.php:290-304
Edited functions.php
Ran command: `php -l functions.php`

The automatic fallback has been implemented in [`wpdemo_render_block()`](file:///d:/Local%20Sites/temp/app/public/wp-content/themes/wpdemo/functions.php#L280) and [`wpdemo_render_front_block()`](file:///d:/Local%20Sites/temp/app/public/wp-content/themes/wpdemo/functions.php#L302) in [functions.php](file:///d:/Local%20Sites/temp/app/public/wp-content/themes/wpdemo/functions.php).

---

### How it works now

The `$fallback` parameter now **defaults to `true`**:

```php
if ($block) {
    echo render_block($block);
} elseif ($fallback === true) {
    // Automatically renders the block with default attributes if not added in backend
    echo do_blocks(sprintf('<!-- wp:%s /-->', $block_name));
} elseif (is_string($fallback) && !empty($fallback)) {
    // Custom fallback HTML/block markup
    echo do_blocks($fallback);
}
```

---

### Usage in [front-page.php](file:///d:/Local%20Sites/temp/app/public/wp-content/themes/wpdemo/front-page.php#L121-L131) and other pages

Because `$fallback` defaults to `true`, you **don't need to change anything** in [front-page.php](file:///d:/Local%20Sites/temp/app/public/wp-content/themes/wpdemo/front-page.php):

```php
<!--  banner  -->
<?php wpdemo_render_block('tt/top-heng'); ?>
<!--首页产品中心 结束-->

<!--首页公司简介 开始-->
<?php wpdemo_render_block('tt-theme/idx-about'); ?>
<!--首页公司简介 结束-->

<!--首页技术优势 开始-->
<?php wpdemo_render_block('tt-theme/tech-advantages'); ?>
<!--首页技术优势 结束-->
```

1. **If the block is added in the backend**: It renders the block with the user's customized attributes.
2. **If the block is NOT added in the backend**: It automatically executes `do_blocks('<!-- wp:block-name /-->')` and renders the block with its **default attributes**.

---

### Optional overrides

- **Disable fallback** (render nothing if missing):
  ```php
  <?php wpdemo_render_block('tt/top-heng', false); ?>
  ```
- **Custom fallback markup**:
  ```php
  <?php wpdemo_render_block('tt/top-heng', '<div class="notice">Section coming soon...</div>'); ?>
  ```

更新后的函数

/**
 * 递归查找目标块(避免被 Group/Columns 等容器嵌套时遗漏)
 *
 * @param array  $block_list  解析后的块列表 (由 parse_blocks 返回)
 * @param string $target_name 目标块名称 (如 'tt/top-heng', 'tt-theme/idx-about')
 * @return array|null 匹配到的块结构,未找到返回 null
 */
if (!function_exists('wpdemo_find_block')) {
	function wpdemo_find_block(array $block_list, string $target_name)
	{
		foreach ($block_list as $b) {
			if (isset($b['blockName']) && $b['blockName'] === $target_name) {
				return $b;
			}
			if (!empty($b['innerBlocks'])) {
				$nested = wpdemo_find_block($b['innerBlocks'], $target_name);
				if ($nested) {
					return $nested;
				}
			}
		}
		return null;
	}
}

/**
 * 获取指定页面(或当前页/首页)解析后的块列表(带内存静态缓存)
 *
 * @param int|null $post_id 页面 ID,留空则自动获取当前页面(或首页)ID
 * @return array
 */
if (!function_exists('wpdemo_get_page_blocks')) {
	function wpdemo_get_page_blocks($post_id = null)
	{
		static $cached_blocks = [];

		if (null === $post_id) {
			$post_id = get_the_ID() ?: (get_queried_object_id() ?: (int) get_option('page_on_front'));
		}

		$cache_key = (int) $post_id;
		if (isset($cached_blocks[$cache_key])) {
			return $cached_blocks[$cache_key];
		}

		$page_content = $post_id ? get_post_field('post_content', $post_id) : get_the_content();
		$cached_blocks[$cache_key] = !empty($page_content) ? parse_blocks($page_content) : [];

		return $cached_blocks[$cache_key];
	}
}

/**
 * 专门获取首页块列表(即使在内页调用,也总是能获取到首页的块)
 *
 * @param int|null $post_id 页面 ID,留空则默认读取后台设置的首页 ID
 * @return array
 */
if (!function_exists('wpdemo_get_front_page_blocks')) {
	function wpdemo_get_front_page_blocks($post_id = null)
	{
		if (null === $post_id) {
			$post_id = (int) get_option('page_on_front') ?: get_queried_object_id();
		}
		return wpdemo_get_page_blocks($post_id);
	}
}

/**
 * 递归查找并输出指定块(支持任意页面)
 *
 * @param string      $block_name 目标块名 (如 'tt/top-heng', 'tt-theme/idx-about')
 * @param bool|string $fallback   未找到时的回退方案:
 *                                - true (默认): 自动执行 do_blocks('<!-- wp:块名 /-->') 输出带默认属性的该块
 *                                - string: 输出自定义 HTML 或自定义块标记
 *                                - false: 未找到则不输出任何内容
 * @param int|null    $post_id    页面 ID(留空为当前页面)
 */
if (!function_exists('wpdemo_render_block')) {
	function wpdemo_render_block(string $block_name, $fallback = true, $post_id = null)
	{
		$blocks = wpdemo_get_page_blocks($post_id);
		$block  = wpdemo_find_block($blocks, $block_name);

		if ($block) {
			echo render_block($block);
		} elseif ($fallback === true) {
			// 后台未添加该块时,使用 do_blocks 输出带默认属性的该块
			echo do_blocks(sprintf('<!-- wp:%s /-->', $block_name));
		} elseif (is_string($fallback) && !empty($fallback)) {
			echo do_blocks($fallback);
		}
	}
}

/**
 * 查找并输出首页块(即使在内页调用也可直接渲染首页的块)
 *
 * @param string      $block_name 目标块名
 * @param bool|string $fallback   回退方案 (默认 true 自动输出默认属性块)
 * @param int|null    $post_id    页面 ID
 */
if (!function_exists('wpdemo_render_front_block')) {
	function wpdemo_render_front_block(string $block_name, $fallback = true, $post_id = null)
	{
		if (null === $post_id) {
			$post_id = (int) get_option('page_on_front') ?: get_queried_object_id();
		}
		wpdemo_render_block($block_name, $fallback, $post_id);
	}
}
×
@wordpress/create-block 创建多个blocks框架教程

@wordpress/create-block 创建多个blocks框架教程

创建自定义的Block的归类,然后注册b...

查看更多

AI agent 如何翻译网站(标签+动态内容)

先让AI把网站进行i18n化, …