From 24ed8ace8171519294c859c6ab130adbdf164f20 Mon Sep 17 00:00:00 2001 From: Marcus Kazmierczak Date: Fri, 17 Dec 2021 15:52:26 -0800 Subject: [PATCH] Docs: Update plugin sidebar to new how to guide template (#37490) * Convert plugin sidebar tutorial to single page guide Updates the sidebar tutorial to a single page guide using the new how to template. This makes the guide easier to go through on a single page, cleans up block editor navigation reducing complexity in the navigation and moving the how to Plus adds a new gutenberg-examples code. * Update since style is only enqueued within block editor * Apply suggestions from code review Co-authored-by: Ryan Welcher Co-authored-by: Ryan Welcher --- docs/how-to-guides/plugin-sidebar.md | 382 ++++++++++++++++++ .../sidebar-tutorial/plugin-sidebar-0.md | 15 - .../plugin-sidebar-1-up-and-running.md | 59 --- .../plugin-sidebar-2-styles-and-controls.md | 99 ----- .../plugin-sidebar-3-register-meta.md | 23 -- .../plugin-sidebar-4-initialize-input.md | 105 ----- .../plugin-sidebar-5-update-meta.md | 82 ---- docs/manifest.json | 34 +- docs/toc.json | 20 +- 9 files changed, 385 insertions(+), 434 deletions(-) create mode 100644 docs/how-to-guides/plugin-sidebar.md delete mode 100644 docs/how-to-guides/sidebar-tutorial/plugin-sidebar-0.md delete mode 100644 docs/how-to-guides/sidebar-tutorial/plugin-sidebar-1-up-and-running.md delete mode 100644 docs/how-to-guides/sidebar-tutorial/plugin-sidebar-2-styles-and-controls.md delete mode 100644 docs/how-to-guides/sidebar-tutorial/plugin-sidebar-3-register-meta.md delete mode 100644 docs/how-to-guides/sidebar-tutorial/plugin-sidebar-4-initialize-input.md delete mode 100644 docs/how-to-guides/sidebar-tutorial/plugin-sidebar-5-update-meta.md diff --git a/docs/how-to-guides/plugin-sidebar.md b/docs/how-to-guides/plugin-sidebar.md new file mode 100644 index 0000000000000..7cba7657c20b9 --- /dev/null +++ b/docs/how-to-guides/plugin-sidebar.md @@ -0,0 +1,382 @@ +# Plugin Sidebar + +## Overview + +How to add a sidebar to your plugin. A sidebar is the region to the far right of the editor. Your plugin can add an additional icon next to the InspectorControls (gear icon) that can be expanded. + +![Example sidebar](https://raw.githubusercontent.com/WordPress/gutenberg/HEAD/docs/assets/sidebar-up-and-running.png) + +_Note: this tutorial covers a custom sidebar, if you are looking to add controls to the sidebar see the [Block Toolbar and Settings Sidebar](/docs/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar.md)_ + +## Before you start + +The tutorial assumes you have an existing plugin setup and are ready to add PHP and JavaScript code. Please, refer to [Getting started with JavaScript](/docs/how-to-guides/javascript/README.md) tutorial for an introduction to WordPress plugins and how to use JavaScript to extend the block editor. + +## Step-by-step guide + +### Step 1: Get a Sidebar up and Running + +The first step is to tell the editor that there is a new plugin that will have its own sidebar. Use the [registerPlugin](/packages/plugins/README.md), [PluginSidebar](/packages/edit-post/README.md#pluginsidebar), and [createElement](/packages/element/README.md) utilities provided by the `@wordpress/plugins`, `@wordpress/edit-post`, and `@wordpress/element` packages, respectively. + +Add the following code to a JavaScript file called `plugin-sidebar.js` and save it within your plugin's directory: + +```js +( function ( wp ) { + var registerPlugin = wp.plugins.registerPlugin; + var PluginSidebar = wp.editPost.PluginSidebar; + var el = wp.element.createElement; + + registerPlugin( 'my-plugin-sidebar', { + render: function () { + return el( + PluginSidebar, + { + name: 'my-plugin-sidebar', + icon: 'admin-post', + title: 'My plugin sidebar', + }, + 'Meta field' + ); + }, + } ); +} )( window.wp ); +``` + +For this code to work, those utilities need to be available in the browser, so you must specify `wp-plugins`, `wp-edit-post`, and `wp-element` as dependencies of your script. + +Here is the PHP code to register your script and specify the dependencies: + +```php + true, + 'single' => true, + 'type' => 'string', +) ); +``` + +To confirm, query the block editor store to see the field is loaded. After implementing, reload the editor page and open your browser's developer console. Use this JavaScript snippet in the console to confirm: + +```js +wp.data.select( 'core/editor' ).getCurrentPost().meta; +``` + +The function will return an object containing the registered meta field you registered. + +If the code returns `undefined` make sure your post type supports `custom-fields`. Either when [registering the post](https://developer.wordpress.org/reference/functions/register_post_type/#supports) or with [add_post_type_support function](https://developer.wordpress.org/reference/functions/add_post_type_support/). + +### Step 4: Initialize the Input Control + +With the field available in the editor store, it can now be surfaced to the UI. We extract the input control to a function to keep the code clean as we add functionality. + +```js +( function ( wp ) { + var registerPlugin = wp.plugins.registerPlugin; + var PluginSidebar = wp.editPost.PluginSidebar; + var el = wp.element.createElement; + var TextControl = wp.components.TextControl; + + var MetaBlockField = function () { + return el( TextControl, { + label: 'Meta Block Field', + value: 'Initial value', + onChange: function ( content ) { + console.log( 'content changed to ', content ); + }, + } ); + }; + + registerPlugin( 'my-plugin-sidebar', { + render: function () { + return el( + PluginSidebar, + { + name: 'my-plugin-sidebar', + icon: 'admin-post', + title: 'My plugin sidebar', + }, + el( + 'div', + { className: 'plugin-sidebar-content' }, + el( MetaBlockField ) + ) + ); + }, + } ); +} )( window.wp ); +``` + +We want to initialize the value in the `MetaBlockField` component with the value of `sidebar_plugin_meta_block_field`, and keep it updated when that value changes. + +The `useSelect` function is used to fetch data when the component loads and will update if the data changes. Here is the code update with `useSelect`: + +```js +( function ( wp ) { + var registerPlugin = wp.plugins.registerPlugin; + var PluginSidebar = wp.editPost.PluginSidebar; + var el = wp.element.createElement; + var Text = wp.components.TextControl; + var useSelect = wp.data.useSelect; + + var MetaBlockField = function () { + var metaFieldValue = useSelect( function ( select ) { + return select( 'core/editor' ).getEditedPostAttribute( + 'meta' + )[ 'sidebar_plugin_meta_block_field' ]; + }, [] ); + + return el( Text, { + label: 'Meta Block Field', + value: metaFieldValue, + onChange: function ( content ) { + console.log( 'content has changed to ', content ); + }, + } ); + }; + + registerPlugin( 'my-plugin-sidebar', { + render: function () { + return el( + PluginSidebar, + { + name: 'my-plugin-sidebar', + icon: 'admin-post', + title: 'My plugin sidebar', + }, + el( + 'div', + { className: 'plugin-sidebar-content' }, + el( MetaBlockField ) + ) + ); + }, + } ); +} )( window.wp ); +``` + +The `wp.data.useSelect` function is from the `@wordpress/data` package, so `wp-data` needs to be added as a dependency in the `wp_register_script` function in PHP. + +Note: The `getEditedPostAttribute` call is used to retrieve the most recent values of the post, including user editions that haven't been yet saved. + +Confirm it's working by updating the code, reloading, and opening the sidebar. The input's content is no longer `Initial value` but a void string. Users can't type values yet, but you can check that the component is updated if the value in the store changes. Open the browser's console, execute + +```js +wp.data + .dispatch( 'core/editor' ) + .editPost( { meta: { sidebar_plugin_meta_block_field: 'hello world!' } } ); +``` + +You can observe the content changing in the input component. + +### Step 5: Update the Meta Field When the Input's Content Changes + +The last step is to update the meta field when the input content changes. +The `useDispatch` function takes a store name as its only argument and returns methods that you can use to update the store, in this case we'll use `editPost` + +```js +( function ( wp ) { + var registerPlugin = wp.plugins.registerPlugin; + var PluginSidebar = wp.editPost.PluginSidebar; + var el = wp.element.createElement; + var TextControl = wp.components.TextControl; + var useSelect = wp.data.useSelect; + var useDispatch = wp.data.useDispatch; + + var MetaBlockField = function ( props ) { + var metaFieldValue = useSelect( function ( select ) { + return select( 'core/editor' ).getEditedPostAttribute( + 'meta' + )[ 'sidebar_plugin_meta_block_field' ]; + }, [] ); + + var editPost = useDispatch( 'core/editor' ).editPost; + + return el( TextControl, { + label: 'Meta Block Field', + value: metaFieldValue, + onChange: function ( content ) { + editPost( { + meta: { sidebar_plugin_meta_block_field: content }, + } ); + }, + } ); + }; + + registerPlugin( 'my-plugin-sidebar', { + render: function () { + return el( + PluginSidebar, + { + name: 'my-plugin-sidebar', + icon: 'admin-post', + title: 'My plugin sidebar', + }, + el( + 'div', + { className: 'plugin-sidebar-content' }, + el( MetaBlockField ) + ) + ); + }, + } ); +} )( window.wp ); +``` + +After the update, when the user types, the input control calls `editPost` and updates the editor store on each keystroke. + +Update the JavaScript, load the sidebar, and type in the input field. You can confirm it is saved by typing something in the input control and executing the JavaScript snippet in your browser's development console: + +```js +wp.data.select( 'core/editor' ).getEditedPostAttribute( 'meta' )[ + 'sidebar_plugin_meta_block_field' +]; +``` + +The message displayed should be what you typed in the input. + +When saving a post, you can confirm it is stored properly in the database by reloading after a save and confirming the input control is initialized with the last value you typed. + +## Additional resources + +Documentation for working with the [@wordpress/data package](/packages/data/README.md). + +Functions used in this guide: + +- [useSelect](/packages/data/README.md#useselect). +- [getEditedPostAttribute](/docs/reference-guides/data/data-core-editor.md#geteditedpostattribute) +- [useDispatch](/packages/data/README.md#usedispatch) + +## Conclusion + +You now have a custom sidebar that you can use to update `post_meta` content. + +A complete example is available, download the [plugin-sidebar example](https://github.com/WordPress/gutenberg-examples/tree/trunk/plugin-sidebar) from the [gutenberg-examples](https://github.com/WordPress/gutenberg-examples) repository. diff --git a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-0.md b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-0.md deleted file mode 100644 index dae2749604bce..0000000000000 --- a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-0.md +++ /dev/null @@ -1,15 +0,0 @@ -# Plugin Sidebar - -How to add a sidebar to your plugin. A sidebar is the region to the far right of the editor. Your plugin can add an additional icon next to the InspectorControls (gear icon) that can be expanded. - -![Example sidebar](https://raw.githubusercontent.com/WordPress/gutenberg/HEAD/docs/assets/sidebar-up-and-running.png) - -**Prerequisite:**: The tutorial assumes you have an existing plugin setup and ready to add PHP and JavaScript code. Please, refer to [Getting started with JavaScript](/docs/how-to-guides/javascript/) tutorial for an introduction to WordPress plugins and how to use JavaScript to extend the block editor. - -In the next sections, you're going to create a custom sidebar for a plugin that contains a text control so the user can update a value that is stored in the `post_meta` table. - -1. [Get a sidebar up and running](/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-1-up-and-running.md) -2. [Tweak the sidebar style and add controls](/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-2-styles-and-controls.md) -3. [Register a new meta field](/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-3-register-meta.md) -4. [Initialize the input control with the meta field value](/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-4-initialize-input.md) -5. [Update the meta field value when input's content changes](/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-5-update-meta.md) diff --git a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-1-up-and-running.md b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-1-up-and-running.md deleted file mode 100644 index 180eafb52e948..0000000000000 --- a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-1-up-and-running.md +++ /dev/null @@ -1,59 +0,0 @@ -# Get a Sidebar up and Running - -_Note: this tutorial covers a custom sidebar, Adding controls to the sidebar is covered in [Block Toolbar and Settings Sidebar](/docs/how-to-guides/block-tutorial/block-controls-toolbar-and-sidebar.md)_ - -The first step in the journey is to tell the editor that there is a new plugin that will have its own sidebar. You can do so by using the [registerPlugin](/packages/plugins/README.md), [PluginSidebar](/packages/edit-post/README.md#pluginsidebar), and [createElement](/packages/element/README.md) utilities provided by WordPress, to be found in the `@wordpress/plugins`, `@wordpress/edit-post`, and `@wordpress/element` [packages](/docs/reference-guides/packages.md), respectively. - -Add the following code to a JavaScript file called `plugin-sidebar.js` and save it within your plugin's directory: - -```js -( function ( wp ) { - var registerPlugin = wp.plugins.registerPlugin; - var PluginSidebar = wp.editPost.PluginSidebar; - var el = wp.element.createElement; - - registerPlugin( 'my-plugin-sidebar', { - render: function () { - return el( - PluginSidebar, - { - name: 'my-plugin-sidebar', - icon: 'admin-post', - title: 'My plugin sidebar', - }, - 'Meta field' - ); - }, - } ); -} )( window.wp ); -``` - -For this code to work, those utilities need to be available in the browser, so you tell WordPress to enqueue the packages that include them by introducing `wp-plugins`, `wp-edit-post`, and `wp-element` as dependencies of your script. - -Copy this code to a PHP file within your plugin's directory: - -```php - true, - 'single' => true, - 'type' => 'string', -) ); -``` - -To make sure the field has been loaded, query the block editor [internal data structures](/docs/reference-guides/data/), also known as _stores_. Open your browser's console, and execute this piece of code: - -```js -wp.data.select( 'core/editor' ).getCurrentPost().meta; -``` - -Before adding the `register_post_meta` function to the plugin, this code returns a void array, because WordPress hasn't been told to load any meta field yet. After registering the field, the same code will return an object containing the registered meta field you registered. - -If the code returns `undefined` make sure your post type supports `custom-fields`. Either when [registering the post](https://developer.wordpress.org/reference/functions/register_post_type/#supports) or with [add_post_type_support function](https://developer.wordpress.org/reference/functions/add_post_type_support/). diff --git a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-4-initialize-input.md b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-4-initialize-input.md deleted file mode 100644 index 1df2b7bfb3675..0000000000000 --- a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-4-initialize-input.md +++ /dev/null @@ -1,105 +0,0 @@ -# Initialize the Input Control - -Now that the field is available in the editor store, it can be surfaced to the UI. The first step will be to extract the input control to a separate function so you can expand its functionality while the code stays clear. - -```js -( function ( wp ) { - var registerPlugin = wp.plugins.registerPlugin; - var PluginSidebar = wp.editPost.PluginSidebar; - var el = wp.element.createElement; - var Text = wp.components.TextControl; - - var MetaBlockField = function () { - return el( Text, { - label: 'Meta Block Field', - value: 'Initial value', - onChange: function ( content ) { - console.log( 'content changed to ', content ); - }, - } ); - }; - - registerPlugin( 'my-plugin-sidebar', { - render: function () { - return el( - PluginSidebar, - { - name: 'my-plugin-sidebar', - icon: 'admin-post', - title: 'My plugin sidebar', - }, - el( - 'div', - { className: 'plugin-sidebar-content' }, - el( MetaBlockField ) - ) - ); - }, - } ); -} )( window.wp ); -``` - -Now you can focus solely on the `MetaBlockField` component. The goal is to initialize it with the value of `sidebar_plugin_meta_block_field`, but also to keep it updated when that value changes. - -WordPress has [some utilities to work with data](/packages/data/README.md) from the stores. The first you're going to use is [useSelect](/packages/data/README.md#useselect). - -The `useSelect` is used to fetch data for the current component and update it when the original data changes. Let's update the code to use it: - -```js -( function ( wp ) { - var registerPlugin = wp.plugins.registerPlugin; - var PluginSidebar = wp.editPost.PluginSidebar; - var el = wp.element.createElement; - var Text = wp.components.TextControl; - var useSelect = wp.data.useSelect; - - var MetaBlockField = function () { - var metaFieldValue = useSelect( function ( select ) { - return select( 'core/editor' ).getEditedPostAttribute( 'meta' )[ 'sidebar_plugin_meta_block_field' ]; - }, [] ); - - return el( Text, { - label: 'Meta Block Field', - value: metaFieldValue, - onChange: function ( content ) { - console.log( 'content has changed to ', content ); - }, - } ); - }; - - registerPlugin( 'my-plugin-sidebar', { - render: function () { - return el( - PluginSidebar, - { - name: 'my-plugin-sidebar', - icon: 'admin-post', - title: 'My plugin sidebar', - }, - el( - 'div', - { className: 'plugin-sidebar-content' }, - el( MetaBlockField ) - ) - ); - }, - } ); -} )( window.wp ); -``` - -Copy this code to the JavaScript file. Note that it now uses the `wp.data.useSelect` utility to be found in the `@wordpress/data` package. Go ahead and add `wp-data` as a dependency in the PHP script. - -This is how the code changes from the previous section: - -- The `MetaBlockField` component will be updated every time the original data changes. -- [getEditedPostAttribute](/docs/reference-guides/data/data-core-editor.md#geteditedpostattribute) is used to retrieve data instead of [getCurrentPost](/docs/reference-guides/data/data-core-editor.md#getcurrentpost) because it returns the most recent values of the post, including user editions that haven't been yet saved. - -Update the code and open the sidebar. The input's content is no longer `Initial value` but a void string. Users can't type values yet, but let's check that the component is updated if the value in the store changes. Open the browser's console, execute - -```js -wp.data - .dispatch( 'core/editor' ) - .editPost( { meta: { sidebar_plugin_meta_block_field: 'hello world!' } } ); -``` - -and observe how the contents of the input component change! diff --git a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-5-update-meta.md b/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-5-update-meta.md deleted file mode 100644 index 9a5a8c8be78df..0000000000000 --- a/docs/how-to-guides/sidebar-tutorial/plugin-sidebar-5-update-meta.md +++ /dev/null @@ -1,82 +0,0 @@ -# Update the Meta Field When the Input's Content Changes - -The last step in the journey is to update the meta field when the input content changes. To do that, you'll use another utility from the `@wordpress/data` package, [useDispatch](/packages/data/README.md#usedispatch). These utilities are also known as _hooks_. - -The `useDispatch` takes store name as its only argument and returns methods that you can use to update the store. - -```js -( function ( wp ) { - var registerPlugin = wp.plugins.registerPlugin; - var PluginSidebar = wp.editPost.PluginSidebar; - var el = wp.element.createElement; - var Text = wp.components.TextControl; - var useSelect = wp.data.useSelect; - var useDispatch = wp.data.useDispatch; - - var MetaBlockField = function ( props ) { - var metaFieldValue = useSelect( function ( select ) { - return select( 'core/editor' ).getEditedPostAttribute( 'meta' )[ 'sidebar_plugin_meta_block_field' ]; - }, [] ); - - var editPost = useDispatch( 'core/editor' ).editPost; - - return el( Text, { - label: 'Meta Block Field', - value: metaFieldValue, - onChange: function ( content ) { - editPost( { - meta: { sidebar_plugin_meta_block_field: content }, - } ); - }, - } ); - }; - - registerPlugin( 'my-plugin-sidebar', { - render: function () { - return el( - PluginSidebar, - { - name: 'my-plugin-sidebar', - icon: 'admin-post', - title: 'My plugin sidebar', - }, - el( - 'div', - { className: 'plugin-sidebar-content' }, - el( MetaBlockField ) - ) - ); - }, - } ); -} )( window.wp ); -``` - -Here's how it changed from the previous section: - -- The component now use `editPost` function returned by `useDispatch` hook. These functions are also known as _actions_. -- By calling `editPost` every time the user types something within the input control, we're effectively updating the editor store on each key stroke. - -Copy this new code to the JavaScript file, load the sidebar and see how the input value gets updated as you type. You may want to check that the internal data structures are updated as well. Type something in the input control, and execute the following instruction in your browser's console: - -```js -wp.data.select( 'core/editor' ).getEditedPostAttribute( 'meta' )[ - 'sidebar_plugin_meta_block_field' -]; -``` - -The message displayed should be what you typed in the input. - -Now, after doing some changes, hit the "Save draft" button or publish the post. Then, reload the editor page. The browser has now new content, fresh from the database. You want to confirm that what you typed was stored properly in the database, and has been reloaded in the current post data structure. Open the sidebar and make sure the input control is initialized with the last value you typed. - -One last check. At this point, because you haven't edited the input yet, the current post and the edited attributes should be the same. Confirm that by executing this code in your browser's console: - -```js -wp.data.select( 'core/editor' ).getCurrentPost()[ 'meta' ][ - 'sidebar_plugin_meta_block_field' -]; -wp.data.select( 'core/editor' ).getEditedPostAttribute( 'meta' )[ - 'sidebar_plugin_meta_block_field' -]; -``` - -This is it! You now have a custom sidebar that updates `post_meta` contents. diff --git a/docs/manifest.json b/docs/manifest.json index ba65b56b2f503..8a4583ec7bf6f 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -325,40 +325,10 @@ }, { "title": "Plugin Sidebar", - "slug": "plugin-sidebar-0", - "markdown_source": "../docs/how-to-guides/sidebar-tutorial/plugin-sidebar-0.md", + "slug": "plugin-sidebar", + "markdown_source": "../docs/how-to-guides/plugin-sidebar.md", "parent": "how-to-guides" }, - { - "title": "Get a Sidebar up and Running", - "slug": "plugin-sidebar-1-up-and-running", - "markdown_source": "../docs/how-to-guides/sidebar-tutorial/plugin-sidebar-1-up-and-running.md", - "parent": "plugin-sidebar-0" - }, - { - "title": "Tweak the sidebar style and add controls", - "slug": "plugin-sidebar-2-styles-and-controls", - "markdown_source": "../docs/how-to-guides/sidebar-tutorial/plugin-sidebar-2-styles-and-controls.md", - "parent": "plugin-sidebar-0" - }, - { - "title": "Register the Meta Field", - "slug": "plugin-sidebar-3-register-meta", - "markdown_source": "../docs/how-to-guides/sidebar-tutorial/plugin-sidebar-3-register-meta.md", - "parent": "plugin-sidebar-0" - }, - { - "title": "Initialize the Input Control", - "slug": "plugin-sidebar-4-initialize-input", - "markdown_source": "../docs/how-to-guides/sidebar-tutorial/plugin-sidebar-4-initialize-input.md", - "parent": "plugin-sidebar-0" - }, - { - "title": "Update the Meta Field When the Input's Content Changes", - "slug": "plugin-sidebar-5-update-meta", - "markdown_source": "../docs/how-to-guides/sidebar-tutorial/plugin-sidebar-5-update-meta.md", - "parent": "plugin-sidebar-0" - }, { "title": "Themes", "slug": "themes", diff --git a/docs/toc.json b/docs/toc.json index ecade3b1b0a77..ca79a760cbe7d 100644 --- a/docs/toc.json +++ b/docs/toc.json @@ -137,25 +137,7 @@ ] }, { "docs/how-to-guides/notices/README.md": [] }, - { - "docs/how-to-guides/sidebar-tutorial/plugin-sidebar-0.md": [ - { - "docs/how-to-guides/sidebar-tutorial/plugin-sidebar-1-up-and-running.md": [] - }, - { - "docs/how-to-guides/sidebar-tutorial/plugin-sidebar-2-styles-and-controls.md": [] - }, - { - "docs/how-to-guides/sidebar-tutorial/plugin-sidebar-3-register-meta.md": [] - }, - { - "docs/how-to-guides/sidebar-tutorial/plugin-sidebar-4-initialize-input.md": [] - }, - { - "docs/how-to-guides/sidebar-tutorial/plugin-sidebar-5-update-meta.md": [] - } - ] - }, + { "docs/how-to-guides/plugin-sidebar.md": [] }, { "docs/how-to-guides/themes/README.md": [ { "docs/how-to-guides/themes/block-theme-overview.md": [] },