368 lines
11 KiB
Markdown
368 lines
11 KiB
Markdown
|
|
## 当前可用的 SlotFill 及示例
|
|||
|
|
|
|||
|
|
以下 SlotFill 可在 `edit-post` 或 `editor` 包中使用。具体用法及示例请参阅下列各项:
|
|||
|
|
|
|||
|
|
- [主仪表板按钮](/docs/reference-guides/slotfills/main-dashboard-button.md)
|
|||
|
|
- [插件区块设置菜单项](/docs/reference-guides/slotfills/plugin-block-settings-menu-item.md)
|
|||
|
|
- [插件文档设置面板](/docs/reference-guides/slotfills/plugin-document-setting-panel.md)
|
|||
|
|
- [插件更多菜单项](/docs/reference-guides/slotfills/plugin-more-menu-item.md)
|
|||
|
|
- [插件文章发布后面板](/docs/reference-guides/slotfills/plugin-post-publish-panel.md)
|
|||
|
|
- [插件文章状态信息](/docs/reference-guides/slotfills/plugin-post-status-info.md)
|
|||
|
|
- [插件文章发布前面板](/docs/reference-guides/slotfills/plugin-pre-publish-panel.md)
|
|||
|
|
- [插件侧边栏](/docs/reference-guides/slotfills/plugin-sidebar.md)
|
|||
|
|
- [插件侧边栏更多菜单项](/docs/reference-guides/slotfills/plugin-sidebar-more-menu-item.md)
|
|||
|
|
|
|||
|
|
# SlotFills 参考文档
|
|||
|
|
|
|||
|
|
Slot(插槽)与 Fill(填充)是已公开的组件,允许开发者将项目注入到 Gutenberg 管理体验中的某些预定义位置。
|
|||
|
|
更多详细信息请参阅 [SlotFill 组件文档](/packages/components/src/slot-fill/README.md)。
|
|||
|
|
|
|||
|
|
要使用这些组件,我们必须利用 [@wordpress/plugins](/packages/plugins/README.md) API 注册一个用于注入项目的插件。
|
|||
|
|
|
|||
|
|
## 使用概览
|
|||
|
|
|
|||
|
|
使用 SlotFills 需要完成以下四个步骤:
|
|||
|
|
|
|||
|
|
1. 从 `@wordpress/plugins` 包导入 `registerPlugin` 方法
|
|||
|
|
2. 从 `@wordpress/editor` 包导入所需的 SlotFill 组件
|
|||
|
|
3. 定义渲染内容的组件。需将修改/新增内容包裹在导入的 SlotFill 组件中
|
|||
|
|
4. 注册插件
|
|||
|
|
|
|||
|
|
以下是通过 `PluginPostStatusInfo` 插槽填充的示例:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
import { registerPlugin } from '@wordpress/plugins';
|
|||
|
|
import { PluginPostStatusInfo } from '@wordpress/editor';
|
|||
|
|
|
|||
|
|
const PluginPostStatusInfoTest = () => (
|
|||
|
|
<PluginPostStatusInfo>
|
|||
|
|
<p>文章状态信息插槽填充</p>
|
|||
|
|
</PluginPostStatusInfo>
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
registerPlugin( 'post-status-info-test', { render: PluginPostStatusInfoTest } );
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 条件化渲染 SlotFill 内容
|
|||
|
|
|
|||
|
|
除 [MainDashboardButton](/docs/reference-guides/slotfills/main-dashboard-button.md) 外,所有可用的 SlotFill 同时在文章编辑器和站点编辑器中公开,任何已注册的 Fill 都会在两种上下文中渲染。可通过多种方式实现条件化渲染。
|
|||
|
|
|
|||
|
|
### 限定填充内容至文章编辑器
|
|||
|
|
|
|||
|
|
通过检查当前文章类型对象的 `viewable` 属性是否为 `true`,可将填充内容限定在文章编辑器内。未设置为 `viewable` 的文章类型没有关联的文章编辑界面,这是判断用户不在文章编辑器中的有效依据。以下示例将在所有已注册文章类型的编辑界面中渲染内容:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
/**
|
|||
|
|
* WordPress 依赖项
|
|||
|
|
*/
|
|||
|
|
import { registerPlugin } from '@wordpress/plugins';
|
|||
|
|
import {
|
|||
|
|
PluginDocumentSettingPanel,
|
|||
|
|
store as editorStore,
|
|||
|
|
} from '@wordpress/editor';
|
|||
|
|
import { store as coreStore } from '@wordpress/core-data';
|
|||
|
|
import { useSelect } from '@wordpress/data';
|
|||
|
|
import { __ } from '@wordpress/i18n';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 作为插件组成部分的渲染组件
|
|||
|
|
*/
|
|||
|
|
const EditPostDocumentSettingPanel = () => {
|
|||
|
|
// 获取当前文章类型信息
|
|||
|
|
const isViewable = useSelect( ( select ) => {
|
|||
|
|
const postTypeName = select( editorStore ).getCurrentPostType();
|
|||
|
|
const postTypeObject = select( coreStore ).getPostType( postTypeName );
|
|||
|
|
return postTypeObject?.viewable;
|
|||
|
|
}, [] );
|
|||
|
|
|
|||
|
|
// 若文章类型不可查看,则不渲染填充内容
|
|||
|
|
if ( ! isViewable ) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<PluginDocumentSettingPanel
|
|||
|
|
name="custom-panel"
|
|||
|
|
title={ __( '文章编辑器示例' ) }
|
|||
|
|
className="custom-panel"
|
|||
|
|
>
|
|||
|
|
<p>{ __( '仅出现在文章编辑界面' ) }</p>
|
|||
|
|
</PluginDocumentSettingPanel>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
registerPlugin( 'example-post-edit-only', {
|
|||
|
|
render: EditPostDocumentSettingPanel,
|
|||
|
|
} );
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 限定填充内容至特定文章类型
|
|||
|
|
|
|||
|
|
以下示例在前例基础上创建允许渲染的文章类型白名单。此处填充内容仅在编辑页面时渲染:
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
/**
|
|||
|
|
* WordPress 依赖项
|
|||
|
|
*/
|
|||
|
|
import { registerPlugin } from '@wordpress/plugins';
|
|||
|
|
import {
|
|||
|
|
PluginDocumentSettingPanel,
|
|||
|
|
store as editorStore,
|
|||
|
|
} from '@wordpress/editor';
|
|||
|
|
import { store as coreStore } from '@wordpress/core-data';
|
|||
|
|
import { useSelect } from '@wordpress/data';
|
|||
|
|
import { __, sprintf } from '@wordpress/i18n';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 作为插件组成部分的渲染组件
|
|||
|
|
*/
|
|||
|
|
const RestrictPostTypes = () => {
|
|||
|
|
// 获取当前文章类型信息
|
|||
|
|
const { isViewable, postTypeName } = useSelect( ( select ) => {
|
|||
|
|
const postType = select( editorStore ).getCurrentPostType();
|
|||
|
|
const postTypeObject = select( coreStore ).getPostType( postType );
|
|||
|
|
return {
|
|||
|
|
isViewable: postTypeObject?.viewable,
|
|||
|
|
postTypeName: postType,
|
|||
|
|
};
|
|||
|
|
}, [] );
|
|||
|
|
|
|||
|
|
// 允许渲染插件的文章类型列表
|
|||
|
|
const allowedPostTypes = [ 'page' ];
|
|||
|
|
|
|||
|
|
// 若文章类型不可查看或不在允许列表中,则不渲染插件
|
|||
|
|
if ( ! isViewable || ! allowedPostTypes.includes( postTypeName ) ) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<PluginDocumentSettingPanel
|
|||
|
|
name="custom-panel"
|
|||
|
|
title={ __( '文章类型限制示例' ) }
|
|||
|
|
className="custom-panel"
|
|||
|
|
>
|
|||
|
|
<p>
|
|||
|
|
{ sprintf(
|
|||
|
|
__(
|
|||
|
|
'仅出现在允许列表中的文章类型上。%s'
|
|||
|
|
),
|
|||
|
|
allowedPostTypes.join( ', ' )
|
|||
|
|
) }
|
|||
|
|
</p>
|
|||
|
|
</PluginDocumentSettingPanel>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
registerPlugin( 'example-restrict-post-types', {
|
|||
|
|
render: RestrictPostTypes,
|
|||
|
|
} );
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 将填充内容限定在站点编辑器中显示
|
|||
|
|
|
|||
|
|
若要将填充内容限定在站点编辑器中显示,则需要采用反向逻辑。如果文章类型对象的 `viewable` 属性设置为 `true`,则不应渲染该填充内容。以下示例将在任意站点编辑器界面中渲染其内容。
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
/**
|
|||
|
|
* WordPress 依赖项
|
|||
|
|
*/
|
|||
|
|
import { registerPlugin } from '@wordpress/plugins';
|
|||
|
|
import {
|
|||
|
|
PluginDocumentSettingPanel,
|
|||
|
|
store as editorStore,
|
|||
|
|
} from '@wordpress/editor';
|
|||
|
|
import { store as coreStore } from '@wordpress/core-data';
|
|||
|
|
import { useSelect } from '@wordpress/data';
|
|||
|
|
import { __ } from '@wordpress/i18n';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 作为插件组成部分渲染的组件
|
|||
|
|
*/
|
|||
|
|
const SiteEditorDocumentSettingPanel = () => {
|
|||
|
|
// 获取当前文章类型信息
|
|||
|
|
const isViewable = useSelect( ( select ) => {
|
|||
|
|
const postTypeName = select( editorStore ).getCurrentPostType();
|
|||
|
|
const postTypeObject = select( coreStore ).getPostType( postTypeName );
|
|||
|
|
|
|||
|
|
// 可查看的文章类型指能在 WordPress 后台查看的类型,内部类型不会设置为可查看
|
|||
|
|
return postTypeObject?.viewable;
|
|||
|
|
}, [] );
|
|||
|
|
|
|||
|
|
// 若文章类型可查看,则不渲染填充内容
|
|||
|
|
if ( isViewable ) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<PluginDocumentSettingPanel
|
|||
|
|
name="custom-panel"
|
|||
|
|
title={ __( '站点编辑器示例' ) }
|
|||
|
|
className="custom-panel"
|
|||
|
|
>
|
|||
|
|
<p>{ __( '仅出现在站点编辑器中' ) }</p>
|
|||
|
|
</PluginDocumentSettingPanel>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
registerPlugin( 'example-site-editor', {
|
|||
|
|
render: SiteEditorDocumentSettingPanel,
|
|||
|
|
} );
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 将填充内容限定在站点编辑器的特定界面中
|
|||
|
|
|
|||
|
|
此示例在前例基础上,通过提供允许列表来控制填充内容在站点编辑器中的显示界面。
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
/**
|
|||
|
|
* WordPress 依赖项
|
|||
|
|
*/
|
|||
|
|
import { registerPlugin } from '@wordpress/plugins';
|
|||
|
|
import {
|
|||
|
|
PluginDocumentSettingPanel,
|
|||
|
|
store as editorStore,
|
|||
|
|
} from '@wordpress/editor';
|
|||
|
|
import { store as coreStore } from '@wordpress/core-data';
|
|||
|
|
import { useSelect } from '@wordpress/data';
|
|||
|
|
import { __, sprintf } from '@wordpress/i18n';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 作为插件组成部分渲染的组件
|
|||
|
|
*/
|
|||
|
|
const SiteEditorDocumentSettingPanel = () => {
|
|||
|
|
// 站点编辑器中的允许区域
|
|||
|
|
const allowedSiteEditorScreens = [
|
|||
|
|
'wp_template', // 模板
|
|||
|
|
'wp_block', // 模式
|
|||
|
|
'wp_template_part', // 模板部件
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
const { isViewable, postType } = useSelect( ( select ) => {
|
|||
|
|
const postTypeName = select( editorStore ).getCurrentPostType();
|
|||
|
|
const postTypeObject = select( coreStore ).getPostType( postTypeName );
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
// 可查看的文章类型指能在 WordPress 后台查看的类型,内部类型不会设置为可查看
|
|||
|
|
isViewable: postTypeObject?.viewable,
|
|||
|
|
postType: postTypeName,
|
|||
|
|
};
|
|||
|
|
}, [] );
|
|||
|
|
|
|||
|
|
// 若文章类型可查看或不在允许列表中,则不渲染插件
|
|||
|
|
if ( isViewable || ! allowedSiteEditorScreens.includes( postType ) ) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<PluginDocumentSettingPanel
|
|||
|
|
name="custom-panel"
|
|||
|
|
title={ __( '仅限站点编辑器界面' ) }
|
|||
|
|
className="custom-panel"
|
|||
|
|
>
|
|||
|
|
<p>
|
|||
|
|
{ sprintf(
|
|||
|
|
__(
|
|||
|
|
'仅显示在允许列表中的编辑器界面。%s'
|
|||
|
|
),
|
|||
|
|
allowedSiteEditorScreens.join( ',' )
|
|||
|
|
) }
|
|||
|
|
</p>
|
|||
|
|
</PluginDocumentSettingPanel>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
registerPlugin( 'example-site-editor-only', {
|
|||
|
|
render: SiteEditorDocumentSettingPanel,
|
|||
|
|
} );
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 运作原理
|
|||
|
|
|
|||
|
|
SlotFill 通过 `createSlotFill` 创建。这会生成 `Slot` 和 `Fill` 两个组件,随后用于创建在 `wp.plugins` 全局变量上导出的新组件。
|
|||
|
|
|
|||
|
|
**`PluginPostStatusInfo` SlotFill 的定义**([查看核心代码](https://github.com/WordPress/gutenberg/blob/HEAD/packages/editor/src/components/plugin-post-status-info/index.js#L55))
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
/**
|
|||
|
|
* 定义摘要面板的可扩展性插槽
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* WordPress 依赖项
|
|||
|
|
*/
|
|||
|
|
import { createSlotFill, PanelRow } from '@wordpress/components';
|
|||
|
|
|
|||
|
|
export const { Fill, Slot } = createSlotFill( 'PluginPostStatusInfo' );
|
|||
|
|
|
|||
|
|
const PluginPostStatusInfo = ( { children, className } ) => (
|
|||
|
|
<Fill>
|
|||
|
|
<PanelRow className={ className }>{ children }</PanelRow>
|
|||
|
|
</Fill>
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
PluginPostStatusInfo.Slot = Slot;
|
|||
|
|
|
|||
|
|
export default PluginPostStatusInfo;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这个新创建的 Slot 会在编辑器中暴露。以下示例来自核心代码,展示了摘要面板的实现。
|
|||
|
|
|
|||
|
|
可见 `<PluginPostStatusInfo.Slot>` 包裹了面板中所有要显示的项目。任何通过 SlotFill 添加的项目(参见前例)都会包含在 `fills` 参数中,并最终显示在组件末尾。
|
|||
|
|
|
|||
|
|
参见[核心代码](https://github.com/WordPress/gutenberg/tree/HEAD/packages/editor/src/components/sidebar/post-summary.js#L39)。
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
export default function PostSummary( { onActionPerformed } ) {
|
|||
|
|
const { isRemovedPostStatusPanel } = useSelect( ( select ) => {
|
|||
|
|
// 使用 isEditorPanelRemoved 来在面板被程序化移除时隐藏它
|
|||
|
|
// 不使用 isEditorPanelEnabled 是因为此面板不应通过 UI 禁用
|
|||
|
|
const { isEditorPanelRemoved } = select( editorStore );
|
|||
|
|
return {
|
|||
|
|
isRemovedPostStatusPanel: isEditorPanelRemoved( PANEL_NAME ),
|
|||
|
|
};
|
|||
|
|
}, [] );
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<PostPanelSection className="editor-post-summary">
|
|||
|
|
<PluginPostStatusInfo.Slot>
|
|||
|
|
{ ( fills ) => (
|
|||
|
|
<>
|
|||
|
|
<VStack spacing={ 4 }>
|
|||
|
|
<PostCardPanel
|
|||
|
|
onActionPerformed={ onActionPerformed }
|
|||
|
|
/>
|
|||
|
|
<PostFeaturedImagePanel withPanelBody={ false } />
|
|||
|
|
<PostExcerptPanel />
|
|||
|
|
<VStack spacing={ 1 }>
|
|||
|
|
<PostContentInformation />
|
|||
|
|
<PostLastEditedPanel />
|
|||
|
|
</VStack>
|
|||
|
|
{ ! isRemovedPostStatusPanel && (
|
|||
|
|
<VStack spacing={ 2 }>
|
|||
|
|
<VStack spacing={ 1 }>
|
|||
|
|
<PostStatusPanel />
|
|||
|
|
<PostSchedulePanel />
|
|||
|
|
<PostURLPanel />
|
|||
|
|
<PostAuthorPanel />
|
|||
|
|
<PostTemplatePanel />
|
|||
|
|
<PostDiscussionPanel />
|
|||
|
|
<PageAttributesPanel />
|
|||
|
|
<PostSyncStatus />
|
|||
|
|
<BlogTitle />
|
|||
|
|
<PostsPerPage />
|
|||
|
|
<SiteDiscussion />
|
|||
|
|
<PostFormatPanel />
|
|||
|
|
<PostStickyPanel />
|
|||
|
|
</VStack>
|
|||
|
|
<TemplateAreas />
|
|||
|
|
{ fills }
|
|||
|
|
</VStack>
|
|||
|
|
) }
|
|||
|
|
</VStack>
|
|||
|
|
</>
|
|||
|
|
) }
|
|||
|
|
</PluginPostStatusInfo.Slot>
|
|||
|
|
</PostPanelSection>
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
```
|