From 136ff0d19e31b7b39b6428aebd9669ca067a77e6 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 15 Jun 2023 13:59:18 +0100 Subject: [PATCH] Add Navigation Menus to Template Parts screen sidebar in Browse Mode (#51492) * Proof of concept * Rename function Addresses https://github.com/WordPress/gutenberg/pull/51492#discussion_r1230769997 * Space docblocks * Update packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menus.js * Update packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menu.js * remove unneeded comment * Output a string when a navigation has no title --------- Co-authored-by: Ben Dwyer --- .../index.js | 5 +- .../navigation-menu-editor.js | 17 +++--- .../index.js | 57 +++++++++++++++++++ .../style.scss | 3 + ...template-part-navigation-menu-list-item.js | 28 +++++++++ .../template-part-navigation-menu-list.js | 21 +++++++ .../template-part-navigation-menu.js | 30 ++++++++++ .../template-part-navigation-menus.js | 33 +++++++++++ packages/edit-site/src/style.scss | 1 + 9 files changed, 182 insertions(+), 13 deletions(-) create mode 100644 packages/edit-site/src/components/sidebar-navigation-screen-template-part/style.scss create mode 100644 packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menu-list-item.js create mode 100644 packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menu-list.js create mode 100644 packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menu.js create mode 100644 packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menus.js diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/index.js index e3b8b2a85d672..576b96ab3f296 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/index.js @@ -9,7 +9,6 @@ import { import { __, sprintf } from '@wordpress/i18n'; import { useSelect, useDispatch } from '@wordpress/data'; import { decodeEntities } from '@wordpress/html-entities'; - import { store as noticesStore } from '@wordpress/notices'; /** @@ -19,8 +18,6 @@ import { SidebarNavigationScreenWrapper } from '../sidebar-navigation-screen-nav import ScreenNavigationMoreMenu from './more-menu'; import NavigationMenuEditor from './navigation-menu-editor'; -export const noop = () => {}; - export default function SidebarNavigationScreenNavigationMenu() { const { deleteEntityRecord, @@ -229,7 +226,7 @@ export default function SidebarNavigationScreenNavigationMenu() { 'Navigation menus are a curated collection of blocks that allow visitors to get around your site.' ) } > - + ); } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/navigation-menu-editor.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/navigation-menu-editor.js index 5e9c294ddd505..640c8751a51ac 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/navigation-menu-editor.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/navigation-menu-editor.js @@ -12,16 +12,17 @@ import { privateApis as routerPrivateApis } from '@wordpress/router'; */ import { unlock } from '../../lock-unlock'; import { store as editSiteStore } from '../../store'; +import NavigationMenuContent from '../sidebar-navigation-screen-navigation-menus/navigation-menu-content'; import { isPreviewingTheme, currentlyPreviewingTheme, } from '../../utils/is-previewing-theme'; -import NavigationMenuContent from '../sidebar-navigation-screen-navigation-menus/navigation-menu-content'; -import { noop } from '.'; const { useHistory } = unlock( routerPrivateApis ); -export default function NavigationMenuEditor( { navigationMenu } ) { +const noop = () => {}; + +export default function NavigationMenuEditor( { navigationMenuId } ) { const history = useHistory(); const onSelect = useCallback( @@ -63,16 +64,14 @@ export default function NavigationMenuEditor( { navigationMenu } ) { }, [] ); const blocks = useMemo( () => { - if ( ! navigationMenu ) { + if ( ! navigationMenuId ) { return []; } - return [ - createBlock( 'core/navigation', { ref: navigationMenu?.id } ), - ]; - }, [ navigationMenu ] ); + return [ createBlock( 'core/navigation', { ref: navigationMenuId } ) ]; + }, [ navigationMenuId ] ); - if ( ! navigationMenu || ! blocks?.length ) { + if ( ! navigationMenuId || ! blocks?.length ) { return null; } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-template-part/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-template-part/index.js index 0ced2bcd9f36b..7f6344b329222 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-template-part/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-template-part/index.js @@ -20,11 +20,14 @@ import { store as editSiteStore } from '../../store'; import SidebarButton from '../sidebar-button'; import { useAddedBy } from '../list/added-by'; +import TemplatePartNavigationMenus from './template-part-navigation-menus'; + function useTemplateTitleAndDescription( postType, postId ) { const { getDescription, getTitle, record } = useEditedEntityRecord( postType, postId ); + const currentTheme = useSelect( ( select ) => select( coreStore ).getCurrentTheme(), [] @@ -82,11 +85,25 @@ export default function SidebarNavigationScreenTemplatePart() { const { params } = useNavigator(); const { postType, postId } = params; const { setCanvasMode } = unlock( useDispatch( editSiteStore ) ); + + const { record } = useEditedEntityRecord( postType, postId ); + const { title, description } = useTemplateTitleAndDescription( postType, postId ); + const navigationBlocks = getBlocksOfTypeFromBlocks( + 'core/navigation', + record?.blocks + ); + + // Get a list of the navigation menu ids from the navigation blocks' + // ref attribute. + const navigationMenuIds = navigationBlocks?.map( ( block ) => { + return block.attributes.ref; + } ); + return ( } description={ description } + content={ + + } /> ); } + +/** + * Retrieves a list of specific blocks from a given tree of blocks. + * + * @param {string} targetBlock the name of the block to find. + * @param {Array} blocks a list of blocks from the template part entity. + * @return {Array} a list of any navigation blocks found in the blocks. + */ +function getBlocksOfTypeFromBlocks( targetBlock, blocks ) { + if ( ! targetBlock || ! blocks?.length ) return []; + + const findInBlocks = ( _blocks ) => { + if ( ! _blocks ) { + return []; + } + + const navigationBlocks = []; + + for ( const block of _blocks ) { + if ( block.name === targetBlock ) { + navigationBlocks.push( block ); + } + + if ( block?.innerBlocks ) { + const innerNavigationBlocks = findInBlocks( block.innerBlocks ); + + if ( innerNavigationBlocks.length ) { + navigationBlocks.push( ...innerNavigationBlocks ); + } + } + } + + return navigationBlocks; + }; + + return findInBlocks( blocks ); +} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-template-part/style.scss b/packages/edit-site/src/components/sidebar-navigation-screen-template-part/style.scss new file mode 100644 index 0000000000000..399975eccb096 --- /dev/null +++ b/packages/edit-site/src/components/sidebar-navigation-screen-template-part/style.scss @@ -0,0 +1,3 @@ +.edit-site-sidebar-navigation-screen-template-part-navigation-menu__title.components-heading { + margin-bottom: $grid-unit-10; +} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menu-list-item.js b/packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menu-list-item.js new file mode 100644 index 0000000000000..b685c766107a3 --- /dev/null +++ b/packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menu-list-item.js @@ -0,0 +1,28 @@ +/** + * WordPress dependencies + */ +import { useEntityProp } from '@wordpress/core-data'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import SidebarNavigationItem from '../sidebar-navigation-item'; +import { useLink } from '../routes/link'; + +export default function TemplatePartNavigationMenuListItem( { id } ) { + const [ title ] = useEntityProp( 'postType', 'wp_navigation', 'title', id ); + + const linkInfo = useLink( { + postId: id, + postType: 'wp_navigation', + } ); + + if ( ! id ) return null; + + return ( + + { title || __( '(no title)' ) } + + ); +} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menu-list.js b/packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menu-list.js new file mode 100644 index 0000000000000..4171b1e782575 --- /dev/null +++ b/packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menu-list.js @@ -0,0 +1,21 @@ +/** + * WordPress dependencies + */ +import { __experimentalItemGroup as ItemGroup } from '@wordpress/components'; +/** + * Internal dependencies + */ +import TemplatePartNavigationMenuListItem from './template-part-navigation-menu-list-item'; + +export default function TemplatePartNavigationMenuList( { menus } ) { + return ( + + { menus.map( ( menuId ) => ( + + ) ) } + + ); +} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menu.js b/packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menu.js new file mode 100644 index 0000000000000..4837ad99beadd --- /dev/null +++ b/packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menu.js @@ -0,0 +1,30 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { __experimentalHeading as Heading } from '@wordpress/components'; +import { useEntityProp } from '@wordpress/core-data'; + +/** + * Internal dependencies + */ +import NavigationMenuEditor from '../sidebar-navigation-screen-navigation-menu/navigation-menu-editor'; + +export default function TemplatePartNavigationMenu( { id } ) { + const [ title ] = useEntityProp( 'postType', 'wp_navigation', 'title', id ); + + if ( ! id ) return null; + + return ( + <> + + { title || __( 'Navigation' ) } + + + + ); +} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menus.js b/packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menus.js new file mode 100644 index 0000000000000..418b1d4423b20 --- /dev/null +++ b/packages/edit-site/src/components/sidebar-navigation-screen-template-part/template-part-navigation-menus.js @@ -0,0 +1,33 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { __experimentalHeading as Heading } from '@wordpress/components'; +/** + * Internal dependencies + */ +import TemplatePartNavigationMenu from './template-part-navigation-menu'; +import TemplatePartNavigationMenuList from './template-part-navigation-menu-list'; + +export default function TemplatePartNavigationMenus( { menus } ) { + if ( ! menus.length ) return null; + + // if there is a single menu then render TemplatePartNavigationMenu + if ( menus.length === 1 ) { + return ; + } + + // if there are multiple menus then render TemplatePartNavigationMenuList + return ( + <> + + { __( 'Navigation' ) } + + + + ); +} diff --git a/packages/edit-site/src/style.scss b/packages/edit-site/src/style.scss index 916d829153244..6dde831d7273f 100644 --- a/packages/edit-site/src/style.scss +++ b/packages/edit-site/src/style.scss @@ -33,6 +33,7 @@ @import "./components/sidebar-navigation-screen-navigation-menu/style.scss"; @import "./components/sidebar-navigation-screen-page/style.scss"; @import "./components/sidebar-navigation-screen-template/style.scss"; +@import "./components/sidebar-navigation-screen-template-part/style.scss"; @import "./components/sidebar-navigation-subtitle/style.scss"; @import "./components/site-hub/style.scss"; @import "./components/sidebar-navigation-screen-navigation-menus/style.scss";