WordPress一直是非常灵活和可定制的。块和站点编辑者正在扩大我们创建自定义体验的能力,而创建自定义块的能力只能增强该功能。
目前,create-block
实用程序仅允许一次创建一个块,并且不能为多块设置提供选项。例如,如果您想创建两个或多个相关的块,尤其是一个自定义块会使用另一个块来策划用户的体验,该怎么办?如果您的目标是使用Post Meta为用户提供额外的上下文怎么办?这些是常见的用例,也是WordPress始终出色的领域。
下面,您将学习如何使用create-block
公用事业。
目录
让我们通过设置使用评分系统来查看帖子或自定义帖子类型(CPT)的能力来保持这一点,并将其包含在可以在查询循环中使用的另一个自定义块中。当创作者发布评论(书籍,电影,产品)时,可以将其与您的内容一起使用,并且需要评级系统来显示其帖子。最终结果应该看起来像这样:
具体来说,您将构建:
- 带有三个特定内部块的评论卡块:
- 标题 (
core/post-title
) - 评分块(我们也将建立一个块)
- 摘录(
core/post-excerpt
)
- 标题 (
- 一个评分块,将:
- 将职位(或CPT)从一到五星或心脏评级
- 使用后元存储评级
- 使用邮政查询块中的块显示每个帖子的评分。
您需要建立本地环境,并带有一个终端 安装了nodejs 运行命令。如果您还没有设置本地环境,则可以使用 WP-NOW,localwp,或列出的另一个选项 这里 那将适合您的需求。
如果您想遵循完成的代码,则可以在 这个github回购 并将根据需要进行更新;欢迎PR!
设置多块插件
让我们从设置我们的项目结构开始。在您的终端中,CD进入您的wp-content/plugins
目录。如果您正在使用wp-now
您可以从喜欢的任何目录中工作。
脚手架插件文件
跑步npx @wordpress/create-block@latest post-review-blocks
。这将在一个名称的目录中脚打个插件post-review-blocks
。进入该目录并在您选择的代码编辑器中打开它。你应该看到一个post-review-blocks.php
文件。打开它,您的代码应该看起来如下(没有默认注释):
/**
* Plugin Name: Post Review Blocks
* Description: Example block scaffolded with Create Block tool.
* Requires at least: 6.1
* Requires PHP: 7.0
* Version: 0.1.0
* Author: The WordPress Contributors
* License: GPL-2.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: post-review-blocks
*
* @package CreateBlock
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
function create_block_post_review_blocks_block_init() {
register_block_type( __DIR__ . '/build );
}
add_action( 'init', 'create_block_post_review_blocks_block_init' );
插件本身应该具有这样的文件结构:
- build/
- src/
- .editorconfig
- .gitignore
- .package-lock.json
- .package.json
- post-review-blocks.php
- readme.md
您将在post-review-blocks.php
文件和src
本教程的目录和build
目录将自动构建。
脚手架
接下来,删除所有文件src
目录使得src
是空的,cd
进入src
如果您还没有那里。
运行以下两个命令:
npx @wordpress/create-block@latest review-card-block --no-plugin
npx @wordpress/create-block@latest rating-block --no-plugin --variant dynamic
这将创建我们多块设置所需的两个自定义块。注意 --no-plugin
两个命令。标志表明这只是创建块文件,而不是所有所需的插件文件。另外,您可以看到rating-block
将是一个“动态”块,呈现为PHP。为什么?这使您可以练习两者 静态和动态块。
现在,我们有两个街区src
文件夹:
rating-block
review-card-block
您可以照顾好几件事:
- 进入
block.json
文件rating-block
并更改“icon
”财产来自smiley
“ 到 ”star-filled
”。 - 在两个
block.json
每个块的文件,添加“keywords
”财产"keywords": ["rating", "review"]
。您的用户在搜索时会更容易发现新块。 - 在里面
post-review-blocks.php
文件,更新create_block_post_review_blocks_block_init
要注册两个块,这样:
function create_block_post_review_blocks_block_init() {
register_block_type( __DIR__ . '/build/rating-block' );
register_block_type( __DIR__ . '/build/review-card-block' );
}
add_action( 'init', 'create_block_post_review_blocks_block_init' );
构建块并激活插件
现在,从post-review-blocks
插件(“根”与package.json
文件),运行npm start
,这些块应在自己的子目录中建立build
。您可以在本教程的其余部分中将此脚本运行。另外,如果要运行其他命令或更改文件,则可以停止并重新启动它block.json
。该脚本需要运行以使其出现在编辑器中的任何更改。
构建成功后,请在WordPress仪表板中或通过WP-CLI激活插件wp plugin activate post-review-blocks
。
在这一点上,您可以通过创建新帖子并在我们使用的关键字之一中键入一个块来检查块正在注册并检查块:
成功!🎉
现在,您知道如何设置多块插件的结构。您可以在src
文件夹create-block
并在build
目录。
现在是时候添加元功能,分配内部块并限制可以使用块的位置了。
注册后元
打开post-review-blocks.php
再次,粘贴以下create_block_post_review_blocks_block_init
功能:
// Add some post meta
function register_review_rating_post_meta() {
$post_meta = array(
'_rating' => array( 'type' => 'integer' ),
'_ratingStyle' => array( 'type' => 'string' ),
);
foreach ( $post_meta as $meta_key => $args ) {
register_post_meta(
'post',
$meta_key,
array(
'show_in_rest' => true,
'single' => true,
'type' => $args['type'],
'auth_callback' => function() {
return current_user_can( 'edit_posts' );
}
)
);
}
}
add_action( 'init', 'register_review_rating_post_meta' );
此函数会登记两个您需要的元密钥:
_rating
_ratingStyle
这些需要注册。否则,当您更新我们的评分块时,将不会保存数据。您还会注意到这两个元密钥都带有下划线:_
。这“保护”了元的元素免于在邮政自定义字段部分中使用,并可能被该元框中的值覆盖。
最后,请注意show_in_rest
设置为真,auth_callback
检查以确保用户至少具有edit_posts
特权。如果META未在WordPress REST API中显示,则无法在块编辑器中进行编辑。
本教程范围之外的快速注意:要谨慎对待 REST API。如果您需要从公共API中过滤数据,请在其他地方使用PHP或选择其他方法来使用敏感数据。
建立评分块
该评分块使您的用户可以将帖子评分为1到5,并在显示星形表情符号(⭐)或心脏表情符号(❤️)之间进行选择。您可以将这些表情符号复制到您的代码中。通过此功能,该块实现了两个目标:
- 演示如何从元后拯救和拉出
- 允许在查询循环邮政模板中使用后元数据
有 许多应用程序 对于使用CPT的这种功能,包括:
- 员工目录与
email
或者position
元 - 与
rating
或者ISBN
元 - 配方索引
tastiness
或者prep_time
元
可能性很多!
好的,本节中的所有编辑都将在src/rating-block
目录。
添加基本CSS
以下CSS用于styles.scss
文件。打开该文件,删除其中的任何CSS,然后粘贴以下内容,从而在块周围增加填充物并确保恒星为黄色,心脏是红色的。
.wp-block-create-block-rating-block {
padding: 1rem 0;
}
.wp-block-create-block-rating-block span.rating-star {
color: yellow;
}
.wp-block-create-block-rating-block span.rating-heart {
color: red;
}
将其调整到您的喜好并保存文件。
添加属性和使用context到block.json文件
打开block.json
归档额定块并添加以下属性:
"usesContext": ["postId", "postType"],
"attributes": {
"rating": {
"type": "integer",
"default": 5
},
"ratingStyle": {
"type": "string",
"default": "star"
}
},
"example": {
"attributes": {
"rating": 4,
"ratingStyle": "star"
}
}
上面的JSON执行以下操作:
usesContext
:允许我们获得帖子ID和类型的值attributes
:标识要保存在块上的属性example
:提供添加时块的外观的预览
更新edit.js文件
有很多要解决的问题。您可以将其分为三个部分:
- 导入和作业
- 检索和存储后元的功能
- 编辑侧栏中的组件的返回方法
可以找到完整的文件 在github上。
删除文件中当前的内容。然后,在edit.js
文件,添加以下内容:
import { __ } from "@wordpress/i18n";
import { useEffect } from "@wordpress/element";
import { useBlockProps, InspectorControls } from "@wordpress/block-editor";
import { PanelBody, RangeControl, SelectControl } from "@wordpress/components";
import { useEntityProp } from "@wordpress/core-data";
import "./editor.scss";
本节设置了我们的导入:
__
是我们的国际化方法useEffect
允许您更新元数据useBlockProps
为您提供与之合作的块属性InspectorControls
允许您将控件添加到检查员的侧栏PanelBody
,RangeControl
,和SelectControl
都是为块的属性设置用户控件的所有组件useEntityProp
提供对元元的访问权限- 最后,导入SCSS文件
接下来,添加以下内容:
export default function Edit( {
attributes: { rating, ratingStyle },
setAttributes,
context: { postType, postId },
} ) {
const [meta, updateMeta] = useEntityProp(
"postType",
postType,
"meta",
postId,
);
// Add functionality code here
// Add return() method here
// Other code will go here, don't forget or delete the closing curly brace!
}
这是Edit
方法,它控制块编辑器中显示的内容。首先,您传递并分配以下内容:
rating
和ratingStyle
传递并分配到属性状态对象setAttributes
是一种方法attributes
状态对象更新postType
和邮政的通过usesContext
您在上面定义
接下来,您会看到状态对象meta
和updateMeta
方法正在从useEntityProp
方法,是 块使用以获取或更改元值。
好,到目前为止很好?现在用于功能!
代替“此处添加功能代码”的评论,添加以下方法:
useEffect( () => {
const initStyle = meta?._ratingStyle ? meta?._ratingStyle : "star";
setAttributes( {
rating: meta?._rating || 0,
ratingStyle: initStyle,
} );
}, [] );
const onChangeRating = ( val ) => {
updateMeta( {
...meta,
_rating: val,
} );
setAttributes( { rating: val } );
};
const onChangeRatingStyle = ( val ) => {
updateMeta( {
...meta,
_ratingStyle: val,
} );
setAttributes( { ratingStyle: val } );
};
const getRatingEmojis = () => {
let ratingEmojis = "";
for (let i = 0; i < rating; i++) {
ratingEmojis += ratingStyle === "star" ? "⭐" : "❤️";
}
return ratingEmojis;
};