创建自定义的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 官方介绍
CRETAE 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
| Function | Description |
|---|---|
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);
}
}
WP开发教程 WordPress导师在线教程