如何创建WordPress区块模板

如何创建WordPress区块模板

古腾堡时代,设计过程与 WordPress 主题没有严格的联系。开箱即用的内容管理系统为用户提供了构建优秀网站布局所需的所有设计工具,而主题的目标是增加更多的构建和设计工具。

区块模板是一种可以释放更多网站构建能力的功能。根据区块编辑器手册

区块模板被定义为区块项目列表。这些区块可以有预定义的属性、占位符内容,也可以是静态或动态的。区块模板允许为编辑器会话指定默认初始状态。

换句话说,区块模板是预制的区块集合,用于在客户端动态设置默认状态。

👉 区块模板不同于模板文件。

模板文件是 PHP 文件,如 index.phppage.phpsingle.php,根据 WordPress 模板层次结构,经典主题和区块主题的工作方式相同。在经典主题中,这些文件是用 PHP 和 HTML 编写的。在区块主题中,这些文件完全由块构成。

👉 区块模板不同于区块样板。

区块样板需要手动添加到页面中,而区块模板会在您或您的团队成员创建新文章时自动提供初始布局和默认值。

您还可以将特定的区块模板绑定到自定义文章类型,并锁定某些区块或功能,以强制用户使用默认设置或防止出错。

创建区块模板有几种方法。您可以使用区块 API 通过 PHP 声明区块类型数组,也可以使用 InnerBlocks 组件创建自定义区块类型。

如何使用 PHP 创建区块模板

如果你是老派开发人员,可以使用插件或主题的 functions.php 定义自定义区块模板。如果您决定使用插件,请启动您最喜欢的代码编辑器,创建一个新的 PHP 文件,然后添加以下代码:

<?php
/*
* Plugin Name:       My Block Templates
* Plugin URI:        https://example.com/
* Description:       An example plugin
* Version:           1.0
* Requires at least: 5.5
* Requires PHP:      8.0
* Author:            Your name
* Author URI:        https://author.example.com/
* License:           GPL v2 or later
* License URI:       https://www.gnu.org/licenses/gpl-2.0.html
* Update URI:        https://example.com/my-plugin/
*/
function myplugin_register_my_block_template() {
$post_type_object = get_post_type_object( 'post' );
$post_type_object->template = array(
array( 'core/image' ),
array( 'core/heading' ),
array( 'core/paragraph' )
);
}
add_action( 'init', 'myplugin_register_my_block_template' );

在上述代码中, get_post_type_object 按名称检索文章类型。

将文件保存在 wp-content/plugins 文件夹中,进入 WordPress 面板中的插件界面,激活 My Block Templates 插件。

现在,当你创建一篇新文章时,编辑器会自动启动包含图片块、标题和段落的块模板。

在帖子编辑器中自动加载区块模板

在帖子编辑器中自动加载区块模板

您还可以为每个区块添加设置数组,并创建嵌套的区块结构。下面的函数创建了一个包含内部区块和设置的更高级的区块模板:

function myplugin_register_my_block_template() {
$block_template = array(
array( 'core/image' ),
array( 'core/heading', array(
'placeholder'	=> 'Add H2...',
'level'			=> 2
) ),
array( 'core/paragraph', array(
'placeholder'	=> 'Add paragraph...'
) ),
array( 'core/columns', 
array(), 
array( 
array( 'core/column',
array(),
array(
array( 'core/image' )
)
), 
array( 'core/column',
array(),
array(
array( 'core/heading', array(
'placeholder'	=> 'Add H3...',
'level'			=> 3
) ),
array( 'core/paragraph', array(
'placeholder'	=> 'Add paragraph...'
) )
) 
)
) 
)
);
$post_type_object = get_post_type_object( 'post' );
$post_type_object->template = $block_template;
}
add_action( 'init', 'myplugin_register_my_block_template' );

您可以在下图中看到上述代码的输出结果:

更高级的区块模板

更高级的区块模板

到目前为止,我们只使用了核心区块。但你也可以在区块模板中加入自定义区块区块样板,如下例所示:

function myplugin_register_my_block_template() {
$post_type_object = get_post_type_object( 'page' );
$post_type_object->template = array(
array( 'core/pattern', array(
'slug' => 'my-plugin/my-block-pattern'
) ) 
);
}
add_action( 'init', 'myplugin_register_my_block_template' );

如果您决定为已注册的自定义帖子类型创建一个默认的区块模板,这两者并无太大区别。只需将 get_post_type_object 的帖子类型改为自定义帖子类型名称即可,如下例所示:

<?php
function myplugin_register_my_block_template() {
$post_type_object = get_post_type_object( 'book' );
$post_type_object->template = array(
array( 'core/image' ),
array( 'core/heading' ),
array( 'core/paragraph' )
);
}
add_action( 'init', 'myplugin_register_my_block_template' );

既然你已经知道如何创建区块模板,我们就可以继续探索更多的使用案例。让我们深入探讨一下。

  1. 使用自定义帖子类型的区块模板
  2. 利用区块属性微调区块模板
  3. 锁定区块
  4. 防止用户解锁区块
  5. 禁用特定用户角色的代码编辑器

使用自定义帖子类型的区块模板

如前所述,您可以为自定义帖子类型附加区块模板。您可以在注册了自定义帖子类型后再这样做,但您可能更喜欢在注册自定义帖子类型时定义区块模板。

在这种情况下,你可以使用 register_post_type 函数的 template template_lock 参数:

function myplugin_register_book_post_type() {
$args = array(
'label' => esc_html__( 'Books' ),
'labels' => array(
'name' => esc_html__( 'Books' ),
'singular_name' => esc_html__( 'Book' ),
),
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_rest' => true,
'rest_namespace' => 'wp/v2',
'has_archive' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'supports' => array( 'title', 'editor', 'thumbnail' ),
'template' => array(
array( 'core/paragraph', array(
'placeholder'	=> 'Add paragraph...'
) ),
array( 'core/columns', 
array(), 
array( 
array( 'core/column',
array(),
array(
array( 'core/image' )
)
), 
array( 'core/column',
array(),
array(
array( 'core/heading', array(
'placeholder'	=> 'Add H3...',
'level'			=> 3
) ),
array( 'core/paragraph', array(
'placeholder'	=> 'Add paragraph...'
) )
) 
)
)
)
)
);
register_post_type( 'book', $args );
}
add_action( 'init', 'myplugin_register_book_post_type' );

就是这样。下图显示了编辑器界面中图书自定义帖子类型的块模板。

自定义文章类型的区块模板

自定义文章类型的区块模板

完成版面设计后,您可能需要使用图块设置来微调区块模板的行为和外观。

利用区块属性微调区块模板

我们把区块模板定义为区块列表。列表中的每一项都应是一个数组,包含区块名称和可选属性数组。如果使用嵌套数组,可能需要为子区块添加第三个数组。

包含栏目区块的模板可表示如下:

$template = array( 'core/columns', 
// attributes
array(), 
// nested blocks
array(
array( 'core/column' ),
array( 'core/column' ) 
) 
);

如上所述,列表中的第二个数组是一个可选的区块属性数组。通过这些属性,您可以自定义模板的外观,这样您或您的用户就可以专注于文章内容,而无需关心页面布局和设计。

首先,您可以使用区块编辑器创建一个区块结构,作为模板的参考。

区块编辑器中的区块布局

区块编辑器中的区块布局

添加区块、自定义布局和样式,然后切换到代码编辑器并查找区块分隔符。

栏目区块的区块分隔符

栏目区块的区块分隔符

区块分隔符以键/值对的形式存储区块设置和样式。您只需从区块标记中复制并粘贴键和值,即可填充属性数组:

$template = array( 'core/columns', 
array(
'verticalAlignment'	=> 'center',
'align'				=> 'wide',
'style'				=> array( 
'border'	=> array(
'width'	=> '2px',
'radius'	=> array(
'topLeft'		=> '12px', 
'topRight'		=> '12px', 
'bottomLeft'	=> '12px', 
'bottomRight'	=> '12px'
)
)
),
'backgroundColor' => 'tertiary'
),
array(
array( 'core/column' ),
array( 'core/column' ) 
) 
);

对模板中的每个区块重复这一过程,就完成了。

$template = array(
array( 'core/paragraph', array(
'placeholder'	=> 'Add paragraph...'
) ),
array( 'core/columns', 
array(
'verticalAlignment'	=> 'center',
'align'				=> 'wide',
'style'				=> array( 
'border'	=> array(
'width'		=> '2px',
'radius'	=> array(
'topLeft'		=> '12px', 
'topRight'		=> '12px', 
'bottomLeft'	=> '12px', 
'bottomRight'	=> '12px'
)
)
),
'backgroundColor' => 'tertiary',
'lock' => array(
'remove'	=> true,
'move'		=> true
)
), 
array( 
array( 'core/column',
array( 'verticalAlignment'	=> 'center' ),
array(
array( 'core/image', 
array(
'style'	=> array( 'border' => array( 'radius' => '8px' ) ) 
) 
)
)
), 
array( 'core/column',
array( 'verticalAlignment'	=> 'center' ),
array(
array( 'core/heading', array(
'placeholder'	=> 'Add H3...',
'level'			=> 3
) ),
array( 'core/paragraph', array(
'placeholder'	=> 'Add paragraph...'
) )
) 
)
)
)
);

锁定区块

您可以使用 $post_type_object template_lock 属性锁定特定区块或模板中包含的所有区块。

当你有一个多作者博客,并希望防止所有或特定用户更改区块模板的布局时,锁定模板就会非常有用。

在下面的示例中,我们锁定了区块模板中的所有区块:

function myplugin_register_my_block_template() {
$post_type_object = get_post_type_object( 'post' );
$post_type_object->template = array(
array( 'core/image' ),
array( 'core/heading' ),
array( 'core/paragraph' )
);
$post_type_object->template_lock = 'all';
}
add_action( 'init', 'myplugin_register_my_block_template' );

锁定的区块会在区块工具栏和列表视图中显示锁定图标:

锁定的标题区块

锁定的标题区块

用户可以通过图块工具栏上的 “选项” 菜单解锁区块。

解锁区块

解锁区块

单击 “解锁” 后,弹出一个模式窗口,允许您启用/禁用移动、防止移除或两者兼而有之:

锁定选项

锁定选项

template_lock 可以使用以下值之一:

  • all – 阻止用户添加新区块、移动和删除现有区块
  • insert – 阻止用户添加新区块和删除现有区块
  • contentOnly – 用户只能编辑模板中包含的区块内容。请注意, contentOnly  只能在模式或模板级别使用,必须用代码进行管理。(另请参阅 Locking APIs)。

设置 template_lock,防止模板块被删除

设置 template_lock,防止模板块被删除

如果要锁定特定区块,可以在每个区块上使用 lock 属性:

function myplugin_register_my_block_template() {
$post_type_object = get_post_type_object( 'post' );
$post_type_object->template = array(
array( 'core/image' ),
array( 'core/heading' ),
array( 'core/paragraph', array(
'lock' => array(
'remove'	=> true,
'move'		=> true
)
) )
);
}
add_action( 'init', 'myplugin_register_my_block_template' );

lock 属性可以使用以下值之一:

  • remove: 防止用户删除区块。
  • move: 防止用户移动区块。

您还可以将 lock template_lock 结合使用,对块模板中包含的区块的行为进行微调。在下面的示例中,我们锁定了除标题以外的所有区块:

function myplugin_register_my_block_template() {
$post_type_object = get_post_type_object( 'post' );
$post_type_object->template = array(
array( 'core/image' ),
array( 'core/heading', array(
'lock' => array(
'remove'	=> false,
'move'		=> false
) 
) ),
array( 'core/paragraph' )
);
$post_type_object->template_lock = 'all';
}
add_action( 'init', 'myplugin_register_my_block_template' );

下图显示了已锁定和未锁定区块的区块模板:

包含锁定和解锁区块的区块模板

包含锁定和解锁区块的区块模板

区块开发者也可以在 attributes 层的区块定义中使用 lock 属性(另请参阅单独区块锁定)。

防止用户解锁区块

如果你测试了本文讨论的代码,你可能已经意识到,你可以从编辑器界面解锁模板(或其他任何区块)中包含的区块。默认情况下,所有有编辑权限的用户都可以锁定或解锁区块,这样做可以绕过模板设置。

你可以使用 block_editor_settings_all 过滤器来控制能否锁定或解锁区块。

该过滤器将向初始化后的编辑器发送任何设置,这意味着在初始化时用于配置编辑器的任何编辑器设置都可以在发送前被 PHP WordPress 插件过滤。

该过滤器的回调函数需要两个参数:

  • $settings: 编辑器设置数组。
  • $context:  WP_Block_Editor_Context  类的一个实例,该对象包含正在渲染的区块编辑器的相关信息。

你需要做的就是过滤 $settings['canLockBlocks'] 设置为 true false ,如下例所示:

add_filter( 'block_editor_settings_all', 
function( $settings, $context ) {
if ( $context->post && 'book' === $context->post->post_type ) {
$settings['canLockBlocks'] = false;
}
return $settings;
}, 10, 2
);

通过对当前用户功能进行条件检查,您可以排除特定用户角色锁定/解锁区块的权限

在下面的示例中,我们要检查当前用户是否可以编辑他人的帖子(换句话说,如果当前用户的角色是编辑器或更高级别的角色):

add_filter( 'block_editor_settings_all', 
function( $settings, $context ) {
if ( $context->post && 'book' === $context->post->post_type ) {
$settings['canLockBlocks'] = current_user_can( 'edit_others_posts' );
}
return $settings;
}, 10, 2
);

下面的图片比较了管理员和作者的编辑器初始状态。首先是管理员:

管理员用户的编辑器初始状态

管理员用户的编辑器初始状态

现在,作者:

作者的编辑器初始状态

作者的编辑器初始状态

您还可以检查当前用户的任何条件。在下面的示例中,我们要阻止特定用户锁定/解锁区块:

add_filter( 'block_editor_settings_all', 
function( $settings, $context ) {
$user = wp_get_current_user();
if ( in_array( $user->user_email, [ 'email@example.com' ], true ) ) {
$settings['canLockBlocks'] = false;
}
return $settings;
}, 10, 2
);

您可以结合更多条件,对谁可以锁定/解锁模板中的区块,谁不可以锁定/解锁模板中的区块进行细化控制。这就是所谓的 “策划体验” 的一个方面。

但是,等等。您尝试过使用代码编辑器编辑帖子内容吗?您可能会惊讶地发现,不允许从用户界面解锁区块的用户仍然可以通过代码编辑器更改内容。

禁用特定用户角色的代码编辑器

默认情况下,所有可以编辑内容的用户都可以访问代码编辑器。这可能会覆盖您的锁定设置,某些用户可能会破坏或删除您的模板布局。

您也可以使用 block_editor_settings_all 过滤 codeEditingEnabled  设置,防止特定用户角色访问代码编辑器。以下是代码:

add_filter( 'block_editor_settings_all', 
function( $settings, $context ) {
if ( $context->post && 'book' === $context->post->post_type ) {
$settings['canLockBlocks'] = current_user_can( 'edit_others_posts' );
$settings['codeEditingEnabled'] = current_user_can( 'edit_others_posts' );
}
return $settings;
}, 10, 2
);

有了这段代码,没有 edit_others_posts 功能的用户将无法访问代码编辑器。下图显示了作者的选项工具栏。

无法访问代码编辑器的用户角色的选项工具栏

无法访问代码编辑器的用户角色的选项工具栏

这就是通过 PHP 构建区块模板所需的知识。现在,如果你是一名 Gutenberg 区块开发人员,并且喜欢使用 JavaScript,那么你可能更愿意选择另一种方法。

如何使用 JavaScript 创建模板

如果您决定使用 JavaScript,为文章添加区块模板的工作方式就不同了。你仍然可以创建一个模板,但需要创建一个自定义区块,并使用 InnerBlocks 组件,这在我们的古腾堡区块开发指南中已有讨论。

InnerBlocks 输出了一对组件,可用于区块实现,以启用嵌套区块内容。– Source: InnerBlocks

如何使用?

您可以在自定义区块中使用 InnerBlocks ,使用方法与其他 Gutenberg 组件相同。

首先,您需要将它与其他依赖项一起从软件包中包含进来:

import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';

接下来,你将定义 InnerBlocks 属性。在下面的示例中,我们将声明一个 TEMPLATE 常量,然后用它来设置 InnerBlocks 元素的 template 属性值:

const TEMPLATE = [
[ 'core/paragraph', { 'placeholder': 'Add paragraph...' } ],
[ 'core/columns', { verticalAlignment: 'center' }, 
[
[ 
'core/column', 
{ templateLock: 'all' }, 
[
[ 'core/image' ]
]
],
[ 
'core/column', 
{ templateLock: 'all' }, 
[
[ 
'core/heading', 
{'placeholder': 'Add H3...', 'level': 3}
], 
[ 
'core/paragraph', 
{'placeholder': 'Add paragraph...'} 
]
], 
]
]
]
];
registerBlockType( metadata.name, {
title: 'My Template',
category: 'widgets',
edit: ( props ) => {
return(
<div>
<InnerBlocks
template={ TEMPLATE }
templateLock="insert"
/>
</div>
)
},
save() {
const blockProps = useBlockProps.save();
return(
<div { ...blockProps }>
<InnerBlocks.Content />
</div>
)
}
} );

这段代码非常简单。你应该注意到,我们使用了两次 templateLock 属性,首先是在块级别,然后是在 InnerBlocks 元素内部。有关可用道具的完整列表,请参阅 InnerBlocks 参考资料和《区块编辑器手册》。

现在自己试试吧。

首先,使用本地开发环境创建一个本地 WordPress 安装。

然后,启动命令行工具,导航到 plugins 文件夹,并运行以下命令:

npx @wordpress/create-block template-block

你可以随意更改区块的名称。如果你想控制启动区块的方方面面,只需遵循我们的区块开发权威指南中提供的说明即可。

安装完成后,运行以下命令:

cd template-block
npm start

启动 WordPress 管理仪表盘并导航至插件屏幕。找到并激活 Template Block 插件。

在您最喜欢的代码编辑器中,打开 src 文件夹下的 index.js 文件。复制并粘贴上面的代码,保存 index.js,然后回到 WordPress 面板,创建一个新的帖子或页面。

打开区块插入器,向下滚动到 “小工具” 部分。在那里,你应该能找到你的自定义区块。

区块插入器中的自定义区块

区块插入器中的自定义区块

将其添加到帖子中,自定义内容,然后保存帖子。

自定义模板的列表视图

自定义模板的列表视图

如果切换到代码编辑器,你会看到以下标记:

<!-- wp:create-block/template-block -->
<div class="wp-block-create-block-template-block"><!-- wp:paragraph {"placeholder":"Add paragraph..."} -->
<p></p>
<!-- /wp:paragraph -->
<!-- wp:columns {"verticalAlignment":"center"} -->
<div class="wp-block-columns are-vertically-aligned-center"><!-- wp:column {"templateLock":"all"} -->
<div class="wp-block-column"><!-- wp:image -->
<figure class="wp-block-image"><img alt=""/></figure>
<!-- /wp:image --></div>
<!-- /wp:column -->
<!-- wp:column {"templateLock":"all"} -->
<div class="wp-block-column"><!-- wp:heading {"level":3,"placeholder":"Add H3..."} -->
<h3 class="wp-block-heading"></h3>
<!-- /wp:heading -->
<!-- wp:paragraph {"placeholder":"Add paragraph..."} -->
<p></p>
<!-- /wp:paragraph --></div>
<!-- /wp:column --></div>
<!-- /wp:columns --></div>
<!-- /wp:create-block/template-block -->

现在,请在您最喜欢的浏览器中预览效果。如果需要改进区块外观,只需更改 style.scss 文件中的样式即可。

一旦对定制感到满意,请停止进程并运行 npm run build 。项目的所有文件都将被压缩,并在新的 build 文件夹中供生产使用。

简单而强大,不是吗?

现在,你只需点击几下,就能创建高级的区块模板,并将其包含在内容中。

小结

在文章或自定义文章类型中添加块模板可以大大加快和改善 WordPress 网站的创建和编辑体验。区块模板在多用户网站上尤其有用,在这种网站上,多个用户都可以创建内容,而您需要他们遵守相同的格式。

这还可以让您创建统一的布局,而不必在每次创建新文章时手动添加块模式。想想评论或食谱网站,每个页面都应遵守相同的结构。

将您在创建静态动态自定义区块、区块样板和区块模板方面获得的知识结合起来,您就能始终为创建任何类型的 WordPress 网站找到最高效、最有效的解决方案。

现在就看你的了。您是否已经探索过区块模板?你觉得它们最适合用于哪种情况?请在下面的评论中分享您的经验。

评论留言