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

Navigation: Handle block menu items #24846

Merged
Merged
Show file tree
Hide file tree
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
62 changes: 44 additions & 18 deletions packages/block-library/src/navigation/placeholder.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/**
* External dependencies
*/
import { some } from 'lodash';
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import { createBlock } from '@wordpress/blocks';
import { createBlock, parse } from '@wordpress/blocks';
import {
Button,
CustomSelectControl,
Expand Down Expand Up @@ -76,26 +77,51 @@ function getSelectedMenu( selectedCreateOption ) {
/**
* A recursive function that maps menu item nodes to blocks.
*
* @param {Object[]} nodes An array of menu items.
*
* @param {Object[]} menuItems An array of menu items.
* @return {WPBlock[]} An array of blocks.
*/
function mapMenuItemsToBlocks( nodes ) {
return nodes.map( ( { title, type, link: url, id, children } ) => {
const innerBlocks =
children && children.length ? mapMenuItemsToBlocks( children ) : [];
function mapMenuItemsToBlocks( menuItems ) {
return menuItems.map( ( menuItem ) => {
if ( menuItem.type === 'block' ) {
const [ block ] = parse( menuItem.content.raw );

return createBlock(
'core/navigation-link',
{
type,
id,
url,
label: ! title.rendered ? __( '(no title)' ) : title.rendered,
opensInNewTab: false,
},
innerBlocks
);
if ( ! block ) {
return createBlock( 'core/freeform', {
Copy link
Contributor

Choose a reason for hiding this comment

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

While this seems to work in testing, I think it'd be safest to also add core/freeform to the allowedBlocks of the nav block innerBlocks component.

In testing you can actually hack any block into the inner blocks of another block using the code editor (is this a bug?), but probably best not to rely on this behavior.

Copy link
Member Author

@noisysocks noisysocks Sep 25, 2020

Choose a reason for hiding this comment

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

I do wonder if, instead, we should simply fail (loudly?) in this case. It's undefined behaviour for the menu item to have 0 or > 1 blocks in it and probably indicates a bug elsewhere. Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh right, I think I've misunderstood what it's for. It actually looks like parse gives you a freeform block anyway if it's valid HTML that doesn't contain a block.

I think you're right, it should probably fail, but in a way that still makes the navigation recoverable. Not sure what the best option would be.

content: menuItem.content,
} );
}

return block;
}

const attributes = {
label: ! menuItem.title.rendered
? __( '(no title)' )
: menuItem.title.rendered,
opensInNewTab: menuItem.target === '_blank',
};

if ( menuItem.url ) {
attributes.url = menuItem.url;
}

if ( menuItem.description ) {
attributes.description = menuItem.description;
}

if ( menuItem.xfn?.length && some( menuItem.xfn ) ) {
attributes.rel = menuItem.xfn.join( ' ' );
}

if ( menuItem.classes?.length && some( menuItem.classes ) ) {
attributes.className = menuItem.classes.join( ' ' );
}

Copy link
Member Author

@noisysocks noisysocks Aug 28, 2020

Choose a reason for hiding this comment

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

Ideally we'd also set id and type here so that the URL can be dynamic. Need to think about these attributes some more, though. I've added a note to come back to this in #18345.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm unclear on the reasoning behind dropping these attributes, what's the background?

Copy link
Member Author

Choose a reason for hiding this comment

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

So the existing code in master has a few problems:

  • We're setting the type attribute to be menuItem.type, but this is incorrect because the attribute should be one of 'page', 'post', 'category', 'tag', or undefined and menuItem.type returns 'post_object' or 'taxonomy' IIRC.

  • We're setting id to menuItem.id, but this is incorrect because for a link to dynamically render its URL it will need the ID of the post, not the ID of the menu item. It should probably be set to menuItem.object_id.

Instead of fixing these issues, though, I added a note to address them when we address #18345 as there's some thinking to be done around what attributes are needed for dynamically rendering a link. IMO we should be storing three things with the block: the menu item type, the object type, the object ID. See #18345 (comment).

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the explanation, sounds like it's not something to tackle here.

It'd be good to rewrite the description on the issue with these details. 👍

const innerBlocks = menuItem.children?.length
? mapMenuItemsToBlocks( menuItem.children )
: [];

return createBlock( 'core/navigation-link', attributes, innerBlocks );
} );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,36 @@

exports[`Navigation Creating from existing Menus allows a navigation block to be created from existing menus 1`] = `
"<!-- wp:navigation {\\"orientation\\":\\"horizontal\\"} -->
<!-- wp:navigation-link {\\"label\\":\\"Home\\",\\"type\\":\\"custom\\",\\"id\\":94} /-->
<!-- wp:navigation-link {\\"label\\":\\"Home\\",\\"url\\":\\"http://localhost:8889/\\"} /-->
<!-- wp:navigation-link {\\"label\\":\\"Accusamus quo repellat illum magnam quas\\",\\"type\\":\\"post_type\\",\\"id\\":95} -->
<!-- wp:navigation-link {\\"label\\":\\"Debitis cum consequatur sit doloremque\\",\\"type\\":\\"post_type\\",\\"id\\":96} /-->
<!-- wp:navigation-link {\\"label\\":\\"Accusamus quo repellat illum magnam quas\\",\\"url\\":\\"http://localhost:8889/?page_id=41\\"} -->
<!-- wp:navigation-link {\\"label\\":\\"Debitis cum consequatur sit doloremque\\",\\"url\\":\\"http://localhost:8889/?page_id=51\\"} /-->
<!-- /wp:navigation-link -->
<!-- wp:navigation-link {\\"label\\":\\"Est ea vero non nihil officiis in\\",\\"type\\":\\"post_type\\",\\"id\\":97} -->
<!-- wp:navigation-link {\\"label\\":\\"Fuga odio quis tempora\\",\\"type\\":\\"post_type\\",\\"id\\":98} -->
<!-- wp:navigation-link {\\"label\\":\\"In consectetur repellendus eveniet maiores aperiam\\",\\"type\\":\\"post_type\\",\\"id\\":99} -->
<!-- wp:navigation-link {\\"label\\":\\"Mollitia maiores consequatur ea dolorem blanditiis\\",\\"type\\":\\"post_type\\",\\"id\\":100} -->
<!-- wp:navigation-link {\\"label\\":\\"Necessitatibus nisi qui qui necessitatibus quaerat possimus\\",\\"type\\":\\"post_type\\",\\"id\\":101} /-->
<!-- wp:navigation-link {\\"label\\":\\"Est ea vero non nihil officiis in\\",\\"url\\":\\"http://localhost:8889/?page_id=53\\"} -->
<!-- wp:navigation-link {\\"label\\":\\"Fuga odio quis tempora\\",\\"url\\":\\"http://localhost:8889/?page_id=56\\"} -->
<!-- wp:navigation-link {\\"label\\":\\"In consectetur repellendus eveniet maiores aperiam\\",\\"url\\":\\"http://localhost:8889/?page_id=15\\"} -->
<!-- wp:navigation-link {\\"label\\":\\"Mollitia maiores consequatur ea dolorem blanditiis\\",\\"url\\":\\"http://localhost:8889/?page_id=45\\"} -->
<!-- wp:navigation-link {\\"label\\":\\"Necessitatibus nisi qui qui necessitatibus quaerat possimus\\",\\"url\\":\\"http://localhost:8889/?page_id=27\\"} /-->
<!-- /wp:navigation-link -->
<!-- /wp:navigation-link -->
<!-- /wp:navigation-link -->
<!-- /wp:navigation-link -->
<!-- wp:navigation-link {\\"label\\":\\"Nulla omnis autem dolores eligendi\\",\\"type\\":\\"post_type\\",\\"id\\":102} /-->
<!-- wp:navigation-link {\\"label\\":\\"Nulla omnis autem dolores eligendi\\",\\"url\\":\\"http://localhost:8889/?page_id=43\\"} /-->
<!-- wp:navigation-link {\\"label\\":\\"Sample Page\\",\\"type\\":\\"post_type\\",\\"id\\":103} /-->
<!-- wp:navigation-link {\\"label\\":\\"Sample Page\\",\\"url\\":\\"http://localhost:8889/?page_id=2\\"} /-->
<!-- wp:navigation-link {\\"label\\":\\"Beatae qui labore voluptas eveniet officia quia voluptas qui porro sequi et aut est\\",\\"type\\":\\"taxonomy\\",\\"id\\":104} -->
<!-- wp:navigation-link {\\"label\\":\\"Et minus itaque velit tempore hic quisquam saepe quas asperiores\\",\\"type\\":\\"taxonomy\\",\\"id\\":105} -->
<!-- wp:navigation-link {\\"label\\":\\"Et quas a et mollitia et voluptas optio voluptate quia quo unde aut in nostrum iste impedit quisquam id aut\\",\\"type\\":\\"taxonomy\\",\\"id\\":106} -->
<!-- wp:navigation-link {\\"label\\":\\"Illo quis sit impedit itaque expedita earum deserunt magni doloremque velit eum id error\\",\\"type\\":\\"taxonomy\\",\\"id\\":107} /-->
<!-- wp:navigation-link {\\"label\\":\\"Beatae qui labore voluptas eveniet officia quia voluptas qui porro sequi et aut est\\",\\"description\\":\\"Ratione nemo ut aut ullam sed assumenda quis est exercitationem\\",\\"url\\":\\"http://localhost:8889/?cat=7\\"} -->
<!-- wp:navigation-link {\\"label\\":\\"Et minus itaque velit tempore hic quisquam saepe quas asperiores\\",\\"description\\":\\"Vel fuga enim rerum perspiciatis sapiente mollitia magni ut molestiae labore quae quia quia libero perspiciatis voluptatem quidem deleniti eveniet laboriosam doloribus dolor laborum accusantium modi ducimus itaque rerum cum nostrum\\",\\"url\\":\\"http://localhost:8889/?cat=19\\"} -->
<!-- wp:navigation-link {\\"label\\":\\"Et quas a et mollitia et voluptas optio voluptate quia quo unde aut in nostrum iste impedit quisquam id aut\\",\\"description\\":\\"Quas sit labore earum omnis eos sint iste est possimus harum aut soluta sint optio quos distinctio inventore voluptate non ut aliquam ad ut voluptates fugiat numquam magnam modi repellendus modi laudantium et debitis officia est voluptatum quidem unde molestiae animi vero fuga accusamus nam\\",\\"url\\":\\"http://localhost:8889/?cat=6\\"} -->
<!-- wp:navigation-link {\\"label\\":\\"Illo quis sit impedit itaque expedita earum deserunt magni doloremque velit eum id error\\",\\"description\\":\\"Doloremque vero sunt officiis iste voluptatibus voluptas molestiae sint asperiores recusandae amet praesentium et explicabo nesciunt similique voluptatum laudantium amet officiis quas distinctio quis enim nihil tempora\\",\\"url\\":\\"http://localhost:8889/?cat=16\\"} /-->
<!-- /wp:navigation-link -->
<!-- /wp:navigation-link -->
<!-- /wp:navigation-link -->
<!-- wp:navigation-link {\\"label\\":\\"WordPress.org\\",\\"type\\":\\"custom\\",\\"id\\":108} -->
<!-- wp:navigation-link {\\"label\\":\\"Google\\",\\"type\\":\\"custom\\",\\"id\\":109} /-->
<!-- wp:navigation-link {\\"label\\":\\"WordPress.org\\",\\"url\\":\\"https://wordpress.org\\"} -->
<!-- wp:navigation-link {\\"label\\":\\"Google\\",\\"url\\":\\"https://google.com\\"} /-->
<!-- /wp:navigation-link -->
<!-- /wp:navigation -->"
`;
Expand Down