Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new section to the SlotFill reference to show how to conditionally render Fills . #64807

Merged
merged 3 commits into from
Aug 26, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
233 changes: 233 additions & 0 deletions docs/reference-guides/slotfills/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,239 @@ const PluginPostStatusInfoTest = () => (
registerPlugin( 'post-status-info-test', { render: PluginPostStatusInfoTest } );
```

## Conditionally rendering SlotFill content

With the exception of [MainDashboardButton](/docs/reference-guides/slotfills/main-dashboard-button.md), every available SlotFill is exposed in both the Post Editor and Site Editor and any Fill that is registered will be rendered in both contexts. There are a number of approaches that can be implemented to conditionally render Fills.

### 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.

```js
/**
* 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 my the fill.
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.

```js
/**
* 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.

```js
/**
* 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.

```js
/**
* 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.
Expand Down
Loading