| .. | ||
| main-dashboard-button.md | ||
| plugin-block-settings-menu-item.md | ||
| plugin-document-setting-panel.md | ||
| plugin-more-menu-item.md | ||
| plugin-post-publish-panel.md | ||
| plugin-post-status-info.md | ||
| plugin-pre-publish-panel.md | ||
| plugin-sidebar-more-menu-item.md | ||
| plugin-sidebar.md | ||
| README.md | ||
| title | post_status | comment_status | taxonomy | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| SlotFills 参考 | publish | open |
|
SlotFills 参考
Slot 和 Fill 是已公开的组件,允许开发者将项目注入到 Gutenberg 管理体验中的某些预定义位置。 更多详情请参阅 SlotFill 组件文档。
要使用它们,我们必须利用 @wordpress/plugins API 来注册一个插件,该插件将注入我们的项目。
使用概览
要访问 SlotFill 功能,我们需要完成以下四个步骤:
- 从
@wordpress/plugins包中导入registerPlugin方法。 - 从
@wordpress/editor包中导入所需的 SlotFill 组件。 - 定义一个组件来渲染我们的修改内容。我们的修改/添加内容将包裹在导入的 SlotFill 组件中。
- 注册插件。
以下是一个使用 PluginPostStatusInfo slotFill 的示例:
import { registerPlugin } from '@wordpress/plugins';
import { PluginPostStatusInfo } from '@wordpress/editor';
const PluginPostStatusInfoTest = () => (
<PluginPostStatusInfo>
<p>文章状态信息 SlotFill</p>
</PluginPostStatusInfo>
);
registerPlugin( 'post-status-info-test', { render: PluginPostStatusInfoTest } );
条件性渲染 SlotFill 内容
除 MainDashboardButton 外,所有可用的 SlotFill 均在文章编辑器和站点编辑器中提供,任何已注册的 Fill 都会在这两种上下文中渲染。有多种方法可以实现 Fill 的条件性渲染。
Restricting fills to the Post Editor
A fill can be restricted to the Post Editor by checking to see if the current post type object property viewable is set to true. Any post type not set to viewable, does not have an associated edit post screen and is a good indicator that the user is not in the Post Editor. The example below will render its content on the edit post screen for any registered post type.
/**
* WordPress dependencies
*/
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';
/**
* The component to be rendered as part of the plugin.
*/
const EditPostDocumentSettingPanel = () => {
// Retrieve information about the current post type.
const isViewable = useSelect( ( select ) => {
const postTypeName = select( editorStore ).getCurrentPostType();
const postTypeObject = select( coreStore ).getPostType( postTypeName );
return postTypeObject?.viewable;
}, [] );
// If the post type is not viewable, then do not render the plugin.
if ( ! isViewable ) {
return null;
}
return (
<PluginDocumentSettingPanel
name="custom-panel"
title={ __( 'Post Editor Example' ) }
className="custom-panel"
>
<p>{ __( 'Only appears in the Edit Post screen' ) }</p>
</PluginDocumentSettingPanel>
);
};
registerPlugin( 'example-post-edit-only', {
render: EditPostDocumentSettingPanel,
} );
Restricting fills to certain post types.
The following example expands on the example above by creating an allow list of post types where the fill should be rendered. In this case, the fill is only rendered when editing pages.
/**
* WordPress dependencies
*/
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';
/**
* The component to be rendered as part of the plugin.
*/
const RestrictPostTypes = () => {
// Retrieve information about the current post type.
const { isViewable, postTypeName } = useSelect( ( select ) => {
const postType = select( editorStore ).getCurrentPostType();
const postTypeObject = select( coreStore ).getPostType( postType );
return {
isViewable: postTypeObject?.viewable,
postTypeName: postType,
};
}, [] );
// The list of post types that are allowed to render the plugin.
const allowedPostTypes = [ 'page' ];
// If the post type is not viewable or not in the allowed list, do not render the plugin.
if ( ! isViewable || ! allowedPostTypes.includes( postTypeName ) ) {
return null;
}
return (
<PluginDocumentSettingPanel
name="custom-panel"
title={ __( 'Restrict Post Types Example' ) }
className="custom-panel"
>
<p>
{ sprintf(
__(
'Only appears on Post Types that are in the allowed list. %s'
),
allowedPostTypes.join( ', ' )
) }
</p>
</PluginDocumentSettingPanel>
);
};
registerPlugin( 'example-restrict-post-types', {
render: RestrictPostTypes,
} );
Restricting fills to the Side Editor
To restrict fills to the Site Editor, the reverse logic is true. If the post type object's viewable property is set to true, then the fill should not be rendered. The example below will render its content on any Site Editor screen.
/**
* WordPress dependencies
*/
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';
/**
* The component to be rendered as part of the plugin.
*/
const SiteEditorDocumentSettingPanel = () => {
// Retrieve information about the current post type.
const isViewable = useSelect( ( select ) => {
const postTypeName = select( editorStore ).getCurrentPostType();
const postTypeObject = select( coreStore ).getPostType( postTypeName );
// A viewable post type is one than can be viewed in the WordPress admin. Internal ones are not set to viewable.
return postTypeObject?.viewable;
}, [] );
// If the post type is viewable, do not render my fill
if ( isViewable ) {
return null;
}
return (
<PluginDocumentSettingPanel
name="custom-panel"
title={ __( 'Site Editor Example' ) }
className="custom-panel"
>
<p>{ __( 'Only appears in the Site Editor' ) }</p>
</PluginDocumentSettingPanel>
);
};
registerPlugin( 'example-site-editor', {
render: SiteEditorDocumentSettingPanel,
} );
Restricting fills to certain screens in the Site Editor.
This example builds on the example above by providing an allow list to control which screens a fill can be rendered within the Site Editor.
/**
* WordPress dependencies
*/
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';
/**
* The component to be rendered as part of the plugin.
*/
const SiteEditorDocumentSettingPanel = () => {
// Allowed areas in the Site Editor.
const allowedSiteEditorScreens = [
'wp_template', // Templates
'wp_block', // Patterns
'wp_template_part', // Template Parts
];
const { isViewable, postType } = useSelect( ( select ) => {
const postTypeName = select( editorStore ).getCurrentPostType();
const postTypeObject = select( coreStore ).getPostType( postTypeName );
return {
// A viewable post type is one than can be viewed in the WordPress admin. Internal ones are not set to viewable.
isViewable: postTypeObject?.viewable,
postType: postTypeName,
};
}, [] );
// If the post type is viewable, do not render my plugin.
if ( isViewable || ! allowedSiteEditorScreens.includes( postType ) ) {
return null;
}
return (
<PluginDocumentSettingPanel
name="custom-panel"
title={ __( 'Restricted to Site Editor screens' ) }
className="custom-panel"
>
<p>
{ sprintf(
__(
'Only appears on Editor Screens that are in the allowed list. %s'
),
allowedSiteEditorScreens.join( ', ' )
) }
</p>
</PluginDocumentSettingPanel>
);
};
registerPlugin( 'example-site-editor-only', {
render: SiteEditorDocumentSettingPanel,
} );
How do they work?
SlotFills are created using createSlotFill. This creates two components, Slot and Fill which are then used to create a new component that is exported on the wp.plugins global.
Definition of the PluginPostStatusInfo SlotFill (see core code)
/**
* Defines as extensibility slot for the Summary panel.
*/
/**
* WordPress dependencies
*/
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;
This new Slot is then exposed in the editor. The example below is from core and represents the Summary panel.
As we can see, the <PluginPostStatusInfo.Slot> is wrapping all of the items that will appear in the panel.
Any items that have been added via the SlotFill ( see the example above ), will be included in the fills parameter and be displayed in the end of the component.
See core code.
export default function PostSummary( { onActionPerformed } ) {
const { isRemovedPostStatusPanel } = useSelect( ( select ) => {
// We use isEditorPanelRemoved to hide the panel if it was programmatically removed. We do
// not use isEditorPanelEnabled since this panel should not be disabled through the 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>
);
}
Currently available SlotFills and examples
The following SlotFills are available in the edit-post or editor packages. Please refer to the individual items below for usage and example details: