168 lines
5.2 KiB
Markdown
168 lines
5.2 KiB
Markdown
|
|
# 上下文
|
|||
|
|
|
|||
|
|
区块上下文是一项功能,允许祖先区块提供可供其自身层次结构内的后代区块使用的值。这些后代区块可以继承这些值,而无需依赖硬编码值,也无需明确知晓提供这些值的区块。
|
|||
|
|
|
|||
|
|
这在全站编辑中尤其有用。例如,某个区块的内容可能取决于显示它的文章上下文。博客目录模板可能显示许多不同文章的摘要。通过使用区块上下文,仍然可以有一个单一的“文章摘要”区块,根据继承的文章ID显示文章内容。
|
|||
|
|
|
|||
|
|
如果您熟悉 [React Context](https://react.dev/learn/passing-data-deeply-with-context),区块上下文采用了许多相同的理念。实际上,客户端区块编辑器对区块上下文的实现是 React Context 的一个非常简单的应用。区块上下文在服务器端 `render_callback` 实现中也受支持,如下面的示例所示。
|
|||
|
|
|
|||
|
|
## 定义区块上下文
|
|||
|
|
|
|||
|
|
区块上下文在区块的注册设置中定义。一个区块可以提供一个上下文值,或者使用它希望继承的值。
|
|||
|
|
|
|||
|
|
### 提供区块上下文
|
|||
|
|
|
|||
|
|
区块可以通过在其注册设置中分配一个 `providesContext` 属性来提供上下文值。这是一个将上下文名称映射到区块自身某个属性的对象。该属性值对应的值将提供给后代区块,并可以通过相同的上下文名称引用。目前,区块上下文仅支持源自区块自身属性的值。未来可能会增强以支持其他上下文值来源。
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
attributes: {
|
|||
|
|
recordId: {
|
|||
|
|
type: 'number',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
providesContext: {
|
|||
|
|
'my-plugin/recordId': 'recordId',
|
|||
|
|
},
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
有关完整示例,请参阅下面的部分。
|
|||
|
|
|
|||
|
|
#### 包含命名空间
|
|||
|
|
|
|||
|
|
如上例所示,建议您在上下文键的名称中包含命名空间,以避免与其他插件或 WordPress 提供的默认上下文值发生潜在冲突。上下文命名空间应特定于您的插件,并且在大多数情况下可以与区块本身的名称相同。
|
|||
|
|
|
|||
|
|
### 使用区块上下文
|
|||
|
|
|
|||
|
|
区块可以通过在其注册设置中分配一个 `usesContext` 属性来从祖先提供者继承上下文值。这应分配为区块希望继承的上下文名称数组。
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
registerBlockType('my-plugin/record-title', {
|
|||
|
|
title: 'Record Title',
|
|||
|
|
category: 'widgets',
|
|||
|
|
|
|||
|
|
usesContext: ['my-plugin/recordId'],
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 使用区块上下文
|
|||
|
|
|
|||
|
|
一旦区块定义了它希望继承的上下文,就可以在 `edit`(JavaScript)和 `render_callback`(PHP)的实现中访问它。它作为上下文值的对象(JavaScript)或关联数组(PHP)提供,这些值已为区块定义。请注意,只有在区块明确定义了希望继承该值的情况下,上下文值才会可用。
|
|||
|
|
|
|||
|
|
注意:区块上下文不适用于 `save`。
|
|||
|
|
|
|||
|
|
### JavaScript
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
registerBlockType('my-plugin/record-title', {
|
|||
|
|
|
|||
|
|
edit({ context }) {
|
|||
|
|
return 'The record ID: ' + context['my-plugin/recordId'];
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### PHP
|
|||
|
|
|
|||
|
|
区块的上下文值可以从 `$block` 参数的 `context` 属性中获取,该参数作为第三个参数传递给 `render_callback` 函数。
|
|||
|
|
|
|||
|
|
```php
|
|||
|
|
register_block_type( 'my-plugin/record-title', array(
|
|||
|
|
'render_callback' => function( $attributes, $content, $block ) {
|
|||
|
|
return 'The current record ID is: ' . $block->context['my-plugin/recordId'];
|
|||
|
|
},
|
|||
|
|
) );
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 示例
|
|||
|
|
|
|||
|
|
1. 创建一个 `record` 区块。
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
npm init @wordpress/block --namespace my-plugin record
|
|||
|
|
cd record
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. 编辑 `src/index.js`。在 `registerBlockType` 函数中插入 `recordId` 属性和 `providesContext` 属性,并在底部添加 `record-title` 区块的注册:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
registerBlockType( 'my-plugin/record', {
|
|||
|
|
// ... 省略 ...
|
|||
|
|
|
|||
|
|
attributes: {
|
|||
|
|
recordId: {
|
|||
|
|
type: 'number',
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
providesContext: {
|
|||
|
|
'my-plugin/recordId': 'recordId',
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @see ./edit.js
|
|||
|
|
*/
|
|||
|
|
edit: Edit,
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @see ./save.js
|
|||
|
|
*/
|
|||
|
|
save,
|
|||
|
|
} );
|
|||
|
|
|
|||
|
|
registerBlockType( 'my-plugin/record-title', {
|
|||
|
|
title: 'Record Title',
|
|||
|
|
category: 'widgets',
|
|||
|
|
|
|||
|
|
usesContext: [ 'my-plugin/recordId' ],
|
|||
|
|
|
|||
|
|
edit( { context } ) {
|
|||
|
|
return 'The record ID: ' + context[ 'my-plugin/recordId' ];
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
save() {
|
|||
|
|
return null;
|
|||
|
|
},
|
|||
|
|
} );
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. 编辑 `record` 区块的 `src/edit.js`。将 `Edit` 函数替换为以下代码:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
import { TextControl } from '@wordpress/components';
|
|||
|
|
import { InnerBlocks } from '@wordpress/block-editor';
|
|||
|
|
|
|||
|
|
export default function Edit( props ) {
|
|||
|
|
const MY_TEMPLATE = [ [ 'my-plugin/record-title', {} ] ];
|
|||
|
|
const {
|
|||
|
|
attributes: { recordId },
|
|||
|
|
setAttributes,
|
|||
|
|
} = props;
|
|||
|
|
return (
|
|||
|
|
<div>
|
|||
|
|
<TextControl
|
|||
|
|
__nextHasNoMarginBottom
|
|||
|
|
__next40pxDefaultSize
|
|||
|
|
label={ __( 'Record ID' ) }
|
|||
|
|
value={ recordId }
|
|||
|
|
onChange={ ( val ) =>
|
|||
|
|
setAttributes( { recordId: Number( val ) } )
|
|||
|
|
}
|
|||
|
|
/>
|
|||
|
|
<InnerBlocks template={ MY_TEMPLATE } templateLock="all" />
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
4. 编辑 `record` 区块的 `src/save.js`。将 `save` 函数替换为以下代码:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
export default function save( props ) {
|
|||
|
|
return <p>The record ID: { props.attributes.recordId }</p>;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
5. 创建一篇新文章并添加 `record` 区块。如果您在文本框中输入一个数字,您会看到其下方的 `record-title` 区块中显示相同的数字。
|
|||
|
|
|
|||
|
|

|