Skip to content

Commit

Permalink
Add Navigation Menus to Template Parts screen sidebar in Browse Mode (#…
Browse files Browse the repository at this point in the history
…51492)

* Proof of concept

* Rename function

Addresses #51492 (comment)

* 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 <ben@scruffian.com>
  • Loading branch information
getdave and scruffian authored Jun 15, 2023
1 parent 14dc7d2 commit 136ff0d
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand All @@ -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,
Expand Down Expand Up @@ -229,7 +226,7 @@ export default function SidebarNavigationScreenNavigationMenu() {
'Navigation menus are a curated collection of blocks that allow visitors to get around your site.'
) }
>
<NavigationMenuEditor navigationMenu={ navigationMenu } />
<NavigationMenuEditor navigationMenuId={ navigationMenu?.id } />
</SidebarNavigationScreenWrapper>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
[]
Expand Down Expand Up @@ -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 (
<SidebarNavigationScreen
title={ title }
Expand All @@ -98,6 +115,46 @@ export default function SidebarNavigationScreenTemplatePart() {
/>
}
description={ description }
content={
<TemplatePartNavigationMenus menus={ navigationMenuIds } />
}
/>
);
}

/**
* 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 );
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.edit-site-sidebar-navigation-screen-template-part-navigation-menu__title.components-heading {
margin-bottom: $grid-unit-10;
}
Original file line number Diff line number Diff line change
@@ -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 (
<SidebarNavigationItem withChevron { ...linkInfo }>
{ title || __( '(no title)' ) }
</SidebarNavigationItem>
);
}
Original file line number Diff line number Diff line change
@@ -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 (
<ItemGroup className="edit-site-sidebar-navigation-screen-template-part-navigation-menu-list">
{ menus.map( ( menuId ) => (
<TemplatePartNavigationMenuListItem
key={ menuId }
id={ menuId }
/>
) ) }
</ItemGroup>
);
}
Original file line number Diff line number Diff line change
@@ -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 (
<>
<Heading
className="edit-site-sidebar-navigation-screen-template-part-navigation-menu__title"
size="12"
upperCase={ true }
>
{ title || __( 'Navigation' ) }
</Heading>
<NavigationMenuEditor navigationMenuId={ id } />
</>
);
}
Original file line number Diff line number Diff line change
@@ -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 <TemplatePartNavigationMenu id={ menus[ 0 ] } />;
}

// if there are multiple menus then render TemplatePartNavigationMenuList
return (
<>
<Heading
className="edit-site-sidebar-navigation-screen-template-part-navigation-menu__title"
size="12"
upperCase={ true }
>
{ __( 'Navigation' ) }
</Heading>
<TemplatePartNavigationMenuList menus={ menus } />
</>
);
}
1 change: 1 addition & 0 deletions packages/edit-site/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down

1 comment on commit 136ff0d

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in 136ff0d.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/5279095004
📝 Reported issues:

Please sign in to comment.