first commit

This commit is contained in:
2025-10-22 01:33:45 +08:00
commit 2080fa3878
251 changed files with 47081 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
# 钩子参考
[钩子](https://developer.wordpress.org/plugins/hooks/)是一种让代码片段相互交互/修改的机制。它们为插件和主题提供了一种与编辑器交互的方式同时WordPress核心程序本身也广泛使用这种机制。
钩子主要分为两种类型:[动作钩子](https://developer.wordpress.org/plugins/hooks/actions/)和[过滤器钩子](https://developer.wordpress.org/plugins/hooks/filters/)。除了PHP的动作钩子和过滤器钩子外WordPress还提供了在JavaScript中注册和执行钩子的机制。该功能也以[@wordpress/hooks](https://www.npmjs.com/package/@wordpress/hooks)软件包的形式发布于npm平台可供通用场景使用。
您还可以了解更多关于这两种API的信息[PHP](https://developer.wordpress.org/reference/)和[JavaScript](/packages/hooks/README.md)。

View File

@@ -0,0 +1,44 @@
# 自动补全
`editor.Autocomplete.completers` 过滤器用于扩展和覆盖区块所使用的自动补全程序列表。
`@wordpress/block-editor` 中的 `Autocomplete` 组件会应用此过滤器。`@wordpress/components` 包提供了基础的 `Autocomplete` 组件,但该组件不会应用此类过滤器。不过,区块通常应使用 `@wordpress/block-editor` 提供的组件。
### 示例
以下示例演示如何使用 `editor.Autocomplete.completers` 过滤器添加首字母缩写补全程序。你可以在 `@wordpress/components` 包中找到关于自动补全程序接口的完整文档。
```jsx
// 我们的补全程序
const acronymCompleter = {
name: 'acronyms',
triggerPrefix: '::',
options: [
{ letters: 'FYI', expansion: '供您参考' },
{ letters: 'AFAIK', expansion: '据我所知' },
{ letters: 'IIRC', expansion: '如果我没记错' },
],
getOptionKeywords( { letters, expansion } ) {
const expansionWords = expansion.split( /\s+/ );
return [ letters, ...expansionWords ];
},
getOptionLabel: acronym => acronym.letters,
getOptionCompletion: ( { letters, expansion } ) => (
<abbr title={ expansion }>{ letters }</abbr>
),
};
// 过滤器函数
function appendAcronymCompleter( completers, blockName ) {
return blockName === 'my-plugin/foo' ?
[ ...completers, acronymCompleter ] :
completers;
}
// 添加过滤器
wp.hooks.addFilter(
'editor.Autocomplete.completers',
'my-plugin/autocompleters/acronym',
appendAcronymCompleter
);
```

View File

@@ -0,0 +1,583 @@
## 管理区块分类
### `block_categories_all`
<div class="callout callout-warning">
在 WordPress 5.8 之前,这个钩子名为 <code>block_categories</code>(现已弃用)。如需支持旧版 WordPress可能需要检测应使用的过滤器。您可以通过检查 5.8 版本引入的 <code>WP_Block_Editor_Context</code> 类是否存在,来判断 <code>block_categories</code> 是否可安全使用。
</div>
可通过 `block_categories_all` 过滤器对默认区块分类列表进行筛选。您可以在服务器端通过返回分类列表的函数实现此功能,该列表将用于区块注册和在插入器中分组区块。您还可以使用第二个参数 `$editor_context` 根据其内容进行筛选。
```php
// my-plugin.php
function example_filter_block_categories_when_post_provided( $block_categories, $editor_context ) {
if ( ! empty( $editor_context->post ) ) {
array_push(
$block_categories,
array(
'slug' => 'custom-category',
'title' => __( '自定义分类', 'custom-plugin' ),
'icon' => null,
)
);
}
return $block_categories;
}
add_filter( 'block_categories_all', 'example_filter_block_categories_when_post_provided', 10, 2 );
```
### `wp.blocks.updateCategory`
您还可以通过设置 `icon` 属性为区块分类显示图标。该值可以是 [WordPress Dashicon](https://developer.wordpress.org/resource/dashicons/) 的标识符。
您也可以设置 SVG 格式的自定义图标。为此,图标需要在前端渲染并设置,以便利用 WordPress 的 SVG 功能,确保移动端兼容性并提升图标的可访问性。
要为前例中的分类设置 SVG 图标,请在编辑器中添加以下 JavaScript 代码示例(调用 `wp.blocks.updateCategory`
```js
( function () {
var el = React.createElement;
var SVG = wp.primitives.SVG;
var circle = el( 'circle', {
cx: 10,
cy: 10,
r: 10,
fill: 'red',
stroke: 'blue',
strokeWidth: '10',
} );
var svgIcon = el(
SVG,
{ width: 20, height: 20, viewBox: '0 0 20 20' },
circle
);
wp.blocks.updateCategory( 'my-category', { icon: svgIcon } );
} )();
```
# 区块过滤器
WordPress 提供了多个 API允许您修改现有区块的行为。
## 注册机制
WordPress 中的区块通常通过服务端和客户端使用 `block.json` 元数据完成注册。您可以使用以下过滤器在 PHP 服务端注册和 JavaScript 客户端注册期间修改或扩展区块设置。了解更多信息,请参阅[区块注册指南](https://developer.wordpress.org/block-editor/getting-started/fundamentals/registration-of-a-block/)。
### `block_type_metadata`
在通过 PHP 服务端注册区块类型时,过滤从 `block.json` 文件加载的原始元数据。该过滤器允许在元数据处理前进行修改。
此过滤器的回调函数接收一个参数:
- `$metadata` (`array`): 从 `block.json` 加载的用于注册区块类型的元数据。
以下示例将所有区块的 `apiVersion` 设置为 `2`
```php
function example_filter_metadata_registration( $metadata ) {
$metadata['apiVersion'] = 2;
return $metadata;
};
add_filter( 'block_type_metadata', 'example_filter_metadata_registration' );
```
下面是一个更复杂的示例,用于禁用标题区块的背景色和渐变支持。`block_type_metadata` 过滤器非常适合用于[优化编辑器体验](https://developer.wordpress.org/block-editor/how-to-guides/curating-the-editor-experience/)
```php
function example_disable_heading_background_color_and_gradients( $metadata ) {
// 仅对标题区块应用此过滤器
if ( ! isset( $metadata['name'] ) || 'core/heading' !== $metadata['name'] ) {
return $metadata;
}
// 检查是否存在 supports 键
if ( isset( $metadata['supports'] ) && isset( $metadata['supports']['color'] ) ) {
// 移除背景色和渐变支持
$metadata['supports']['color']['background'] = false;
$metadata['supports']['color']['gradients'] = false;
}
return $metadata;
}
add_filter( 'block_type_metadata', 'example_disable_heading_background_color_and_gradients' );
```
### `block_type_metadata_settings`
过滤根据已处理的区块类型元数据确定的设置。通过该过滤器可以应用默认处理流程未覆盖的区块元数据自定义修改。
此过滤器的回调函数接收两个参数:
- `$settings` (`array`): 注册区块类型时确定的设置数组
- `$metadata` (`array`): 从 `block.json` 文件加载的元数据
以下示例将所有区块的 `apiVersion` 数值增加 `1`
```php
function example_filter_metadata_registration( $settings, $metadata ) {
$settings['api_version'] = $metadata['apiVersion'] + 1;
return $settings;
};
add_filter( 'block_type_metadata_settings', 'example_filter_metadata_registration', 10, 2 );
```
### `register_block_type_args`
在区块类型正式于服务端注册之前,过滤区块的参数数组 (`$args`)。
此过滤器的回调函数接收两个参数:
- `$args` (`array`): 注册区块类型的参数数组
- `$block_type` (`string`): 包含命名空间的区块类型名称
`register_block_type_args` 是可用粒度最细的 PHP 过滤器,对服务端注册的所有区块均有效。服务端定义的所有设置都会以高于客户端设置的优先级传播到客户端。
以下代码将禁用段落、标题、列表和列表项区块的颜色控制功能:
```php
function example_disable_color_for_specific_blocks( $args, $block_type ) {
// 需要修改的区块类型列表
$block_types_to_modify = [
'core/paragraph',
'core/heading',
'core/list',
'core/list-item'
];
// 检查当前区块类型是否在列表中
if ( in_array( $block_type, $block_types_to_modify, true ) ) {
// 禁用颜色控制
$args['supports']['color'] = array(
'text' => false,
'background' => false,
'link' => false,
);
}
return $args;
}
add_filter( 'register_block_type_args', 'example_disable_color_for_specific_blocks', 10, 2 );
```
### `blocks.registerBlockType`
用于在使用 JavaScript 在客户端注册区块时过滤区块设置。该过滤器接收区块设置、已注册区块的名称,以及 null 或已弃用的区块设置(当应用于已注册的弃用情况时)作为参数。此过滤器也会应用于区块的每个弃用设置。
以下示例确保列表区块保存时使用规范的生成类名 (`wp-block-list`)
```js
function addListBlockClassName( settings, name ) {
if ( name !== 'core/list' ) {
return settings;
}
return {
...settings,
supports: {
...settings.supports,
className: true,
},
};
}
wp.hooks.addFilter(
'blocks.registerBlockType',
'my-plugin/class-names/list-block',
addListBlockClassName
);
```
## 前端
以下 PHP 过滤器可用于更改区块在前端的输出。
### `render_block`
过滤任何区块的前端内容。此过滤器不会影响区块在编辑器中的行为。
该过滤器的回调函数接收三个参数:
- `$block_content` (`string`):区块内容。
- `$block` (`array`):完整的区块,包括名称和属性。
- `$instance` (`WP_Block`):区块实例。
以下示例在前端为所有段落区块添加 `example-class` 类。此处使用 [HTML API](https://make.wordpress.org/core/2023/03/07/introducing-the-html-api-in-wordpress-6-2/) 来轻松添加类,而不依赖正则表达式。
```php
function example_add_custom_class_to_paragraph_block( $block_content, $block ) {
// 检查区块是否为段落区块。
if ( 'core/paragraph' === $block['blockName'] ) {
// 使用 HTML API 向区块内容添加自定义类。
$processor = new WP_HTML_Tag_Processor( $block_content );
if ( $processor->next_tag( 'p' ) ) {
$processor->add_class( 'example-class' );
}
return $processor->get_updated_html();
}
return $block_content;
}
add_filter( 'render_block', 'example_add_custom_class_to_paragraph_block', 10, 2 );
```
### `render_block_{namespace/block}`
过滤指定区块的前端内容。这是 `render_block` 的简化形式,适用于仅需修改特定区块类型的情况。
该过滤器的回调函数接收三个参数:
- `$block_content` (`string`):区块内容。
- `$block` (`array`):完整的区块,包括名称和属性。
- `$instance` (`WP_Block`):区块实例。
以下示例在前端为所有段落区块添加 `example-class` 类。与上述 `render_block` 示例相比,此处无需在修改内容前检查区块类型。同样使用 [HTML API](https://make.wordpress.org/core/2023/03/07/introducing-the-html-api-in-wordpress-6-2/) 替代正则表达式。
```php
function example_add_custom_class_to_paragraph_block( $block_content, $block ) {
// 使用 HTML API 向区块内容添加自定义类。
$processor = new WP_HTML_Tag_Processor( $block_content );
if ( $processor->next_tag( 'p' ) ) {
$processor->add_class( 'example-class' );
}
return $processor->get_updated_html();
}
add_filter( 'render_block_core/paragraph', 'example_add_custom_class_to_paragraph_block', 10, 2 );
```
## 编辑器
以下 JavaScript 过滤器可用于在编辑器中更改区块的行为。
### `blocks.getSaveElement`
一个应用于区块 `save` 函数结果的过滤器。此过滤器用于替换或扩展元素,例如使用 `React.cloneElement` 修改元素的属性、替换其子元素或返回一个全新的元素。
该过滤器的回调函数接收三个参数:
- `element` (`Object`):待修改并返回的元素。
- `blockType` (`Object`):区块类型定义对象。
- `attributes` (`Object`):区块的属性。
以下示例将封面区块包装在一个外部容器 `div` 中。
```js
function wrapCoverBlockInContainer( element, blockType, attributes ) {
// 如果元素未定义,跳过处理。
if ( ! element ) {
return;
}
// 仅应用于封面区块。
if ( blockType.name !== 'core/cover' ) {
return element;
}
// 返回包装在 div 中的元素。
return <div className="cover-block-wrapper">{ element }</div>;
}
wp.hooks.addFilter(
'blocks.getSaveElement',
'my-plugin/wrap-cover-block-in-container',
wrapCoverBlockInContainer
);
```
### `blocks.getSaveContent.extraProps`
这是一个应用于所有在 `save` 函数中返回 WP 元素的区块过滤器。该过滤器用于向 `save` 函数的根元素添加额外属性。例如,您可以添加 className、id 或该元素任何有效的属性。
此过滤器的回调函数接收三个参数:
- `props``Object`):当前 `save` 元素的属性,将被修改并返回。
- `blockType``Object`):区块类型定义对象。
- `attributes``Object`):区块的属性。
以下示例为所有区块默认添加红色背景:
```js
function addBackgroundColorStyle( props ) {
return {
...props,
style: { backgroundColor: 'red' },
};
}
wp.hooks.addFilter(
'blocks.getSaveContent.extraProps',
'my-plugin/add-background-color-style',
addBackgroundColorStyle
);
```
**注意:** 如果此过滤器在下次编辑文章时修改了现有内容,将会出现[区块验证](/docs/reference-guides/block-api/block-edit-save.md#validation)错误。编辑器会验证存储在文章中的内容是否与 `save()` 函数输出的内容匹配。
为避免此验证错误,请使用服务器端的 `render_block` 来修改现有文章内容,而不是使用此过滤器。请参阅 [render_block 文档](https://developer.wordpress.org/reference/hooks/render_block/)。
### `blocks.getBlockDefaultClassName`
为区块生成的 HTML 类遵循 `wp-block-{name}` 命名规则。此过滤器允许提供替代的类名。
```js
// 我们的过滤器函数。
function setBlockCustomClassName( className, blockName ) {
return blockName === 'core/code' ? 'my-plugin-code' : className;
}
// 添加过滤器。
wp.hooks.addFilter(
'blocks.getBlockDefaultClassName',
'my-plugin/set-block-custom-class-name',
setBlockCustomClassName
);
```
### `blocks.switchToBlockType.transformedBlock`
用于过滤区块转换中的单个转换结果。由于转换是多对多而非一对一的,因此所有原始区块都会被传递。
### `blocks.getBlockAttributes`
在区块属性默认解析之后、验证之前调用,允许插件及时操作属性值,以便进行验证和/或在编辑器中渲染区块的初始值。
此过滤器的回调函数接受 4 个参数:
- `blockAttributes``Object`):所有区块属性。
- `blockType``Object`):区块类型。
- `innerHTML``string`):原始区块内容。
- `attributes``object`):已知的区块属性(来自分隔符)。
在以下示例中,我们使用 `blocks.getBlockAttributes` 过滤器锁定页面中所有段落区块的位置。
```js
// 我们的过滤器函数
function lockParagraphs( blockAttributes, blockType, innerHTML, attributes ) {
if('core/paragraph' === blockType.name) {
blockAttributes['lock'] = {move: true}
}
return blockAttributes;
}
// 添加过滤器
wp.hooks.addFilter(
'blocks.getBlockAttributes',
'my-plugin/lock-paragraphs',
lockParagraphs
);
```
### `editor.BlockEdit`
用于修改区块的 `edit` 组件。它接收原始的区块 `BlockEdit` 组件并返回一个新的包装组件。
以下示例为所有区块添加一个新的检查器面板。
```js
const { createHigherOrderComponent } = wp.compose;
const { InspectorControls } = wp.blockEditor;
const { PanelBody } = wp.components;
const withMyPluginControls = createHigherOrderComponent( ( BlockEdit ) => {
return ( props ) => {
return (
<>
<BlockEdit key="edit" { ...props } />
<InspectorControls>
<PanelBody>我的自定义控件</PanelBody>
</InspectorControls>
</>
);
};
}, 'withMyPluginControls' );
wp.hooks.addFilter(
'editor.BlockEdit',
'my-plugin/with-inspector-controls',
withMyPluginControls
);
```
请注意,由于此钩子对**所有区块**运行,使用它可能会导致性能下降,尤其是在区块选择指标方面。
为了缓解此问题,请考虑是否可以将您执行的任何工作调整为仅在特定条件下运行。
例如,假设您添加的组件仅在区块**被选中时**需要渲染。在这种情况下,您可以使用区块的“选中”状态(`props.isSelected`)来条件化您的渲染。
以下示例为所有区块添加一个新的检查器面板,但仅在区块被选中时显示。
```js
const withMyPluginControls = createHigherOrderComponent( ( BlockEdit ) => {
return ( props ) => {
return (
<>
<BlockEdit { ...props } />
{ props.isSelected && (
<InspectorControls>
<PanelBody>我的自定义控件</PanelBody>
</InspectorControls>
) }
</>
);
};
}, 'withMyPluginControls' );
```
### `editor.BlockListBlock`
用于修改包含块编辑组件及所有工具栏的块包装组件。该钩子接收原始的 `BlockListBlock` 组件并返回新的包装组件。
以下示例为所有块添加唯一类名:
```js
const { createHigherOrderComponent } = wp.compose;
const withClientIdClassName = createHigherOrderComponent(
( BlockListBlock ) => {
return ( props ) => {
return (
<BlockListBlock
{ ...props }
className={ 'block-' + props.clientId }
/>
);
};
},
'withClientIdClassName'
);
wp.hooks.addFilter(
'editor.BlockListBlock',
'my-plugin/with-client-id-class-name',
withClientIdClassName
);
```
可通过返回组件的 `wrapperProps` 属性为块包装组件添加新属性,如下例所示:
```js
const { createHigherOrderComponent } = wp.compose;
const withMyWrapperProp = createHigherOrderComponent( ( BlockListBlock ) => {
return ( props ) => {
const wrapperProps = {
...props.wrapperProps,
'data-my-property': 'the-value',
};
return <BlockListBlock { ...props } wrapperProps={ wrapperProps } />;
};
}, 'withMyWrapperProp' );
wp.hooks.addFilter(
'editor.BlockListBlock',
'my-plugin/with-my-wrapper-prop',
withMyWrapperProp
);
```
### `editor.postContentBlockTypes`
用于修改即使在锁定模板内使用也应启用的块列表。所有将数据保存到文章的块都应添加至此。文章特色图片块即为一例:该块虽常用于模板,但在模板锁定时仍应允许选择图片。
以下示例启用虚构块 `namespace/example`
```js
const addExampleBlockToPostContentBlockTypes = ( blockTypes ) => {
return [ ...blockTypes, 'namespace/example' ];
};
wp.hooks.addFilter(
'editor.postContentBlockTypes',
'my-plugin/post-content-block-types',
addExampleBlockToPostContentBlockTypes
);
```
## 移除区块
### 使用禁用列表
添加区块十分简单,移除区块同样便捷。插件或主题开发者可通过 JavaScript 禁用列表来“取消注册”区块。
将以下代码置于 `my-plugin.js` 文件中:
```js
// my-plugin.js
import { unregisterBlockType } from '@wordpress/blocks';
import domReady from '@wordpress/dom-ready';
domReady( function () {
unregisterBlockType( 'core/verse' );
} );
```
随后通过以下函数在编辑器中加载此脚本:
```php
<?php
// my-plugin.php
function my_plugin_deny_list_blocks() {
wp_enqueue_script(
'my-plugin-deny-list-blocks',
plugins_url( 'my-plugin.js', __FILE__ ),
array( 'wp-blocks', 'wp-dom-ready', 'wp-edit-post' )
);
}
add_action( 'enqueue_block_editor_assets', 'my_plugin_deny_list_blocks' );
```
<div class="callout callout-warning">
取消注册区块时,可能存在<a href="https://en.wikipedia.org/wiki/Race_condition">竞态条件</a>:即注册区块与取消注册区块的代码执行顺序冲突。为确保取消注册代码最后执行,需将注册区块的组件指定为依赖项(本例中为 <code>wp-edit-post</code>)。此外,使用 <code>wp.domReady()</code> 可确保取消注册代码在 DOM 加载完成后执行。
</div>
### 使用允许列表
若需仅保留允许列表中的区块,可调整上述脚本如下:
```js
// my-plugin.js
var allowedBlocks = [
'core/paragraph',
'core/image',
'core/html',
'core/freeform',
];
wp.blocks.getBlockTypes().forEach( function ( blockType ) {
if ( allowedBlocks.indexOf( blockType.name ) === -1 ) {
wp.blocks.unregisterBlockType( blockType.name );
}
} );
```
## 从插入器中隐藏区块
### `allowed_block_types_all`
<div class="callout callout-warning">
在 WordPress 5.8 之前,此钩子名为 <code>allowed_block_types</code>(现已弃用)。如需支持旧版 WordPress可能需要通过检测 <code>WP_Block_Editor_Context</code> 类5.8 版本引入)是否存在来判断应使用的过滤器。
</div>
在服务器端,可通过 `allowed_block_types_all` 过滤器筛选插入器中显示的区块列表。可返回 true支持所有区块类型、false不支持任何区块类型或允许的区块类型名称数组。还可使用第二个参数 `$editor_context` 根据内容筛选区块类型。
```php
<?php
// my-plugin.php
function example_filter_allowed_block_types_when_post_provided( $allowed_block_types, $editor_context ) {
if ( ! empty( $editor_context->post ) ) {
return array( 'core/paragraph', 'core/heading' );
}
return $allowed_block_types;
}
add_filter( 'allowed_block_types_all', 'example_filter_allowed_block_types_when_post_provided', 10, 2 );
```

View File

@@ -0,0 +1,246 @@
### `media.crossOrigin`
此过滤器用于为外部来源的媒体元素(即 `<audio>``<img>``<link>``<script>``<video>`)设置或修改 `crossOrigin` 属性。关于 `crossOrigin` 属性的详细信息、其取值以及如何应用于各元素,请参阅此[文章](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin)。
一个实际应用的例子是在图片块的转换功能中,允许跨域图片在 `<canvas>` 中使用。示例如下:
```js
import { addFilter } from '@wordpress/hooks';
addFilter(
'media.crossOrigin',
'my-plugin/with-cors-media',
// 回调函数接受第二个参数 `mediaSrc`,它引用了实际外部媒体的 URL
// 如果您想基于此 URL 决定 crossOrigin 的值,这将非常有用。
( crossOrigin, mediaSrc ) => {
if ( mediaSrc.startsWith( 'https://example.com' ) ) {
return 'use-credentials';
}
return crossOrigin;
}
);
```
## 编辑器 REST API 预加载路径
您可以使用 [`block_editor_rest_api_preload_paths`](https://developer.wordpress.org/reference/hooks/block_editor_rest_api_preload_paths/) 来过滤 REST API 路径数组,这些路径将用于预加载块编辑器中常用的数据。示例如下:
```php
add_filter( 'block_editor_rest_api_preload_paths', 'example_filter_block_editor_rest_api_preload_paths_when_post_provided', 10, 2 );
function example_filter_block_editor_rest_api_preload_paths_when_post_provided( $preload_paths, $editor_context ) {
if ( ! empty( $editor_context->post ) ) {
array_push( $preload_paths, array( '/wp/v2/blocks', 'OPTIONS' ) );
}
return $preload_paths;
}
```
## 记录错误
用户界面某部分的 JavaScript 错误不应导致整个应用崩溃。为了解决用户的问题React 库使用了 ["错误边界"](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) 的概念。错误边界是 React 组件,可以捕获其子组件树中任何位置的 JavaScript 错误,并显示备用 UI而不是崩溃的组件树。
`editor.ErrorBoundary.errorLogged` 操作允许您接入 [错误边界](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary),并让您访问错误对象。
您可以使用此操作获取由错误边界处理的错误对象。例如,您可能希望将它们发送到外部错误跟踪工具。示例如下:
```js
import { addAction } from '@wordpress/hooks';
addAction(
'editor.ErrorBoundary.errorLogged',
'mu-plugin/error-capture-setup',
( error ) => {
// error 是异常的错误对象。
// 您可以将其输出到控制台或发送到外部错误跟踪工具。
console.log ( error );
}
);
```
# 编辑器钩子
WordPress 提供了多个 API允许您修改编辑器体验。
## 编辑器设置
修改编辑器最常用的方式之一是通过 [`block_editor_settings_all`](https://developer.wordpress.org/reference/hooks/block_editor_settings_all/) PHP 过滤器,该过滤器在设置发送到初始化的编辑器之前应用。这个过滤器允许插件和主题作者对编辑器的行为进行广泛控制。
<div class="callout callout-warning">
在 WordPress 5.8 之前,这个钩子被称为 <code>block_editor_settings</code>,现已被弃用。如果您需要支持旧版本的 WordPress可能需要一种检测应使用哪个过滤器的方法。您可以通过检查是否存在在 5.8 版本中引入的 <code>WP_Block_Editor_Context</code> 类来判断 <code>block_editor_settings</code> 是否可以安全使用。
</div>
`block_editor_settings_all` 钩子向回调函数传递两个参数:
- `$settings` 编辑器可配置设置的数组。
- `$context` [`WP_Block_Editor_Context`](https://developer.wordpress.org/reference/classes/wp_block_editor_context/) 的实例,该对象包含有关当前编辑器的信息。
以下示例修改了最大上传文件大小。将此代码添加到插件或主题的 `functions.php` 文件中进行测试。
```php
add_filter( 'block_editor_settings_all', 'example_filter_block_editor_settings_when_post_provided', 10, 2 );
function example_filter_block_editor_settings_when_post_provided( $editor_settings, $editor_context ) {
if ( ! empty( $editor_context->post ) ) {
$editor_settings['maxUploadFileSize'] = 12345;
}
return $editor_settings;
}
```
编辑器设置有数十种,无法在此文档文章中一一列举,但以下是一些使用 `block_editor_settings_all` 过滤器可以实现的功能示例。
<div class="callout callout-info">
要查看所有可用的设置,请打开编辑器,然后在浏览器的 <a href="https://developer.wordpress.org/advanced-administration/debug/debug-javascript/#open-the-developer-tools">开发者工具</a> 中打开控制台。输入命令 <code>wp.data.select( 'core/block-editor' ).getSettings()</code> 以显示所有编辑器设置的当前值。
</div>
### 限制代码编辑器访问
`codeEditingEnabled` 默认为 `true`,控制用户是否**除了**可视化编辑器之外还可以访问代码编辑器。在某些情况下,您可能不希望某些用户能够访问此视图。
如果此设置设为 `false`,用户将无法在可视化和代码编辑器之间切换。设置菜单中的选项将不可用,并且切换编辑器类型的键盘快捷键将不会触发。以下是一个示例:
```php
add_filter( 'block_editor_settings_all', 'example_restrict_code_editor' );
function example_restrict_code_editor( $settings ) {
$can_active_plugins = current_user_can( 'activate_plugins' );
// 对无法激活插件的用户(非管理员)禁用代码编辑器。
if ( ! $can_active_plugins ) {
$settings[ 'codeEditingEnabled' ] = false;
}
return $settings;
}
```
### 限制可视化编辑器访问
`codeEditingEnabled` 设置类似,`richEditingEnabled` 允许您控制谁可以访问可视化编辑器。如果设为 `true`,用户可以使用可视化编辑器编辑内容。
此设置默认为 [`user_can_richedit`](https://developer.wordpress.org/reference/functions/user_can_richedit/) 函数的返回值。它会检查用户是否可以访问可视化编辑器以及用户的浏览器是否支持它。
### 设置默认图片尺寸
在编辑器中,图片默认设置为 `large` 图片尺寸。您可以使用 `imageDefaultSize` 设置修改此选项,如果您配置了自己的自定义图片尺寸,这将特别有用。以下示例将默认图片尺寸更改为 `medium`
```php
add_filter( 'block_editor_settings_all', 'example_set_default_image_size' );
function example_set_default_image_size( $settings ) {
$settings['imageDefaultSize'] = 'medium';
return $settings;
}
```
### 停用 Openverse
默认情况下,所有 WordPress 站点均启用了 [Openverse](https://openverse.org/) 集成功能,该功能由 `enableOpenverseMediaCategory` 设置项控制。如需停用 Openverse请应用以下过滤器
```php
add_filter( 'block_editor_settings_all', 'example_disable_openverse' );
function example_disable_openverse( $settings ) {
$settings['enableOpenverseMediaCategory'] = false;
return $settings;
}
```
### 停用字体库
字体库允许用户在站点上安装新字体,该功能默认启用并由 `fontLibraryEnabled` 设置项控制。如需停用字体库,请应用以下过滤器:
```php
add_filter( 'block_editor_settings_all', 'example_disable_font_library' );
function example_disable_font_library( $settings ) {
$settings['fontLibraryEnabled'] = false;
return $settings;
}
```
### 停用区块检查器标签页
大多数区块会在检查器中显示[两个标签页](https://make.wordpress.org/core/2023/03/07/introduction-of-block-inspector-tabs/),一个用于设置,另一个用于样式。您可通过 `blockInspectorTabs` 设置项禁用这些标签页:
```php
add_filter( 'block_editor_settings_all', 'example_disable_inspector_tabs_by_default' );
function example_disable_inspector_tabs_by_default( $settings ) {
$settings['blockInspectorTabs'] = array( 'default' => false );
return $settings;
}
```
您还可以调整具体哪些区块启用检查器标签页。以下示例展示了如何为特定区块禁用标签页:
```php
add_filter( 'block_editor_settings_all', 'example_disable_tabs_for_my_custom_block' );
function example_disable_tabs_for_my_custom_block( $settings ) {
$current_tab_settings = _wp_array_get( $settings, array( 'blockInspectorTabs' ), array() );
$settings['blockInspectorTabs'] = array_merge(
$current_tab_settings,
array( 'my-plugin/my-custom-block' => false )
);
return $settings;
}
```
## 区块目录
区块目录允许用户直接在编辑器中从 WordPress.org [插件目录](https://wordpress.org/plugins/browse/block/)安装新的区块插件。您可通过移除加载该功能的操作 `wp_enqueue_editor_block_directory_assets` 来禁用此功能。具体操作如下:
```php
remove_action( 'enqueue_block_editor_assets', 'wp_enqueue_editor_block_directory_assets' );
```
## 区块模式
远程模式(例如来自 WordPress.org [模式目录](https://wordpress.org/patterns/)的模式)默认会在编辑器中向用户开放。此功能由默认值为 `true``should_load_remote_block_patterns` 参数控制。您可通过将过滤器设置为 false`__return_false`)来禁用远程模式:
```php
add_filter( 'should_load_remote_block_patterns', '__return_false' );
```
## 编辑器功能
以下过滤器可用于扩展编辑器功能。
### `editor.PostFeaturedImage.imageSize`
此过滤器可用于修改文章特色图片组件中显示的图片尺寸。默认值为 `'post-thumbnail'`,当媒体对象中不存在指定尺寸时,会自动回退到 `full` 原图尺寸。该过滤器仿照经典编辑器中的 `admin_post_thumbnail_size` 过滤器设计。
```js
import { addFilter } from '@wordpress/hooks';
const withImageSize = function ( size, mediaId, postId ) {
return 'large';
};
addFilter(
'editor.PostFeaturedImage.imageSize',
'my-plugin/with-image-size',
withImageSize
);
```
### `editor.PostPreview.interstitialMarkup`
您还可以过滤生成预览时显示的过渡提示信息。示例如下:
```js
import { addFilter } from '@wordpress/hooks';
const customPreviewMessage = function () {
return '<b>正在生成文章预览!</b>';
};
addFilter(
'editor.PostPreview.interstitialMarkup',
'my-plugin/custom-preview-message',
customPreviewMessage
);
```

View File

@@ -0,0 +1,42 @@
# 全局样式过滤器
WordPress 6.1 引入了一些服务端过滤器,用于挂接到不同数据层提供的 `theme.json` 数据:
- `wp_theme_json_data_default`:挂接到 WordPress 提供的默认数据
- `wp_theme_json_data_blocks`:挂接到区块提供的数据
- `wp_theme_json_data_theme`:挂接到主题提供的数据
- `wp_theme_json_data_user`:挂接到用户提供的数据
每个过滤器都会接收到一个包含对应层级数据的 `WP_Theme_JSON_Data` 类实例。要提供新数据,过滤器回调函数需要使用 `update_with( $new_data )` 方法,其中 `$new_data` 是有效的类 `theme.json` 结构。与任何 `theme.json` 一样,新数据需要声明所使用的 `theme.json``version`,以便在版本不同时能正确迁移到运行时版本。
_示例:_
以下是如何为主题传递新调色板并禁用文本颜色用户界面的方法:
```php
function wpdocs_filter_theme_json_theme( $theme_json ){
$new_data = array(
'version' => 2,
'settings' => array(
'color' => array(
'text' => false,
'palette' => array( /* 新调色板 */
array(
'slug' => 'foreground',
'color' => 'black',
'name' => __( '前景色', 'theme-domain' ),
),
array(
'slug' => 'background',
'color' => 'white',
'name' => __( '背景色', 'theme-domain' ),
),
),
),
),
);
return $theme_json->update_with( $new_data );
}
add_filter( 'wp_theme_json_data_theme', 'wpdocs_filter_theme_json_theme' );
```

View File

@@ -0,0 +1,109 @@
# 国际化过滤器
国际化函数(`__()``_x()``_n()``_nx()`)可为代码中的字符串提供翻译支持。若需覆盖这些函数的返回值,可通过以下可过滤钩子实现:
- `i18n.gettext`
- `i18n.gettext_with_context`
- `i18n.ngettext`
- `i18n.ngettext_with_context`
## 过滤器参数
这些过滤器的参数设置与其对应的 PHP 函数保持一致。
### i18n.gettext
```jsx
function i18nGettextCallback( translation, text, domain ) {
return translation;
}
```
### i18n.gettext_with_context
```jsx
function i18nGettextWithContextCallback( translation, text, context, domain ) {
return translation;
}
```
### i18n.ngettext
```jsx
function i18nNgettextCallback( translation, single, plural, number, domain ) {
return translation;
}
```
### i18n.ngettext_with_context
```jsx
function i18nNgettextWithContextCallback(
translation,
single,
plural,
number,
context,
domain
) {
return translation;
}
```
## 基础示例
以下是通过 `i18n.gettext` 过滤器覆盖特定翻译的简单示例:
```jsx
// 定义过滤器回调函数
function myPluginGettextFilter( translation, text, domain ) {
if ( text === 'Create Reusable block' ) {
return '保存至 MyOrg 区块库';
}
return translation;
}
// 添加过滤器
wp.hooks.addFilter(
'i18n.gettext',
'my-plugin/override-add-to-reusable-blocks-label',
myPluginGettextFilter
);
```
## 使用"文本域"专属过滤器
出于性能考虑,建议优先使用针对特定文本域的过滤器(这样回调函数仅会在相关文本域的字符串处理时执行)。
若需绑定到文本域专属过滤器,请在标准过滤器名称后追加下划线及文本域名称。例如,当过滤文本域为 "woocommerce" 的字符串时,可使用以下过滤器:
- `i18n.gettext_woocommerce`
- `i18n.gettext_with_context_woocommerce`
- `i18n.ngettext_woocommerce`
- `i18n.ngettext_with_context_woocommerce```
使用示例如下:
```jsx
// 定义过滤器回调函数
function myPluginGettextFilter( translation, text, domain ) {
if ( text === 'Youve fulfilled all your orders' ) {
return '所有包裹已整理完毕,准备出发。干得漂亮!';
}
return translation;
}
// 添加过滤器
wp.hooks.addFilter(
'i18n.gettext_woocommerce',
'my-plugin/override-fulfilled-all-orders-text',
myPluginGettextFilter
);
```
_注意_:若需过滤文本域为 `undefined` 的字符串(例如 WordPress 核心字符串),需使用 "default" 来构建过滤器名称:
- `i18n.gettext_default`
- `i18n.gettext_with_context_default`
- `i18n.ngettext_default`
- `i18n.ngettext_with_context_default`

View File

@@ -0,0 +1,36 @@
# 解析器过滤器
当编辑器与区块交互时这些区块会以数据结构的形式存储在内存中包含若干基本属性和特征。在保存工作文章时我们会将这些数据结构序列化为特定的HTML结构并将生成的字符串存储到WordPress数据库文章的`post_content`属性中。当我们将文章重新加载到编辑器中时需要进行反向转换从序列化的HTML格式重建这些数据结构。
将序列化HTML加载到编辑器的过程由*区块解析器*执行。该转换的正式规范编码在`@wordpress/block-serialization-spec-parser`包内的解析表达式语法PEG中。编辑器提供了该语法的默认解析器实现但可能存在多种原因需要将其替换为自定义实现。我们可以通过相应的过滤器注入自定义解析器实现。
## 服务端解析器
如果插件希望以结构化形式而非纯HTML字符串形式处理文章可以通过解析器实现这一需求。
## 客户端解析器
编辑器在交互式处理文章时使用客户端解析器。后端将纯HTML字符串形式发送到浏览器随后编辑器执行首次解析以完成初始化。
## 过滤器
要替换服务端解析器,请使用`block_parser_class`过滤器。该过滤器会转换解析器类的字符串类名,此类需包含`parse`方法。
*示例:*
```php
class EmptyParser {
public function parse( $post_content ) {
// 返回空文档
return array();
}
}
function wpdocs_select_empty_parser( $prev_parser_class ) {
return 'EmptyParser';
}
add_filter( 'block_parser_class', 'wpdocs_select_empty_parser', 10, 1 );
```
> **注意**:目前暂不支持替换客户端解析器。