-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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: Add an API to retrieve content-only inner blocks #30674
Comments
This will be an important server side function to retrieve a data-relational representation since the navigation block can have other blocks in the mix that are not relevant. |
Do we have an example of what this API looks like and what it might return (eg either a rest call / php or JS function signature)? This would help me understand the usecase |
I had in mind something similar to the nav menu walker but taking advantage of the built in object tree representation of nested blocks to be used in server-side context (could be exposed in REST as well), excluding any presentation specific elements. |
Regarding what constitutes the content to be returned by this API, I'm thinking of linking blocks in any flavor (Navigation link, Social links, Home link, Site Title/Logo...), but not other functional blocks like Search, even if it is not a presentation-specific element. Does that make sense, @mtias? |
Are there two parts to this task?
Without (1) how would we know where to find the blocks? |
I don't think we need (1) at the moment, as the Navigation block can be placed in other template parts or posts. I can see designs having a Navigation block in their Header and Footer template parts, or different headers with different navigations, and nothing prevents them from having more than one Navigation block instance per template part. Starting with (2) would allow wrapping items properly when rendering the frontend as suggested in #31951 (comment). Furthermore, it could also help render responsive menus by outputting different HTML for smaller screens excluding the non-content blocks. |
I think I described (1) incorrectly. I meant from any generic template part a function that would get the name of the template part and the name of the block that we're looking for and gets that block back. I don't think we have such a thing. |
I'm not sure using this for rendering is the right track, because it's shifting away from the block rendering paradigm (which should itself be able to support this use case). Perhaps this could be something that's not so much navigation block specific, but instead works on the basis of the HTML markup. That would ensure third-party blocks aren't left out of the mix. It could build a hierarchy of the links inside a The other thought I have if this path isn't considered viable is that this could take advantage of the |
Adding role attributes seems a natural fit, so does hard-coding certain blocks and their meaning, like links and nav links etc… @priethor or others, do we have an example of the format/structure of the data you would want from this hypothetical function or API call? Given an example nav block input, what do you want out, and what are you wanting to do with it? Create a |
Hi @dmsnell! Sitemaps and breadcrumbs are great examples of practical applications of this hypothetical API, whose goal is to provide the page hierarchy given a Navigation Block. There is no specific format in mind, but an equivalent to |
@priethor please pardon my ignorance on the issue, I've not used On the server we have access to a powerful tool with the function extract_nav_links($nav_blocks) {
$extract_link = function($previous_output, $block) {
// logic that takes a block and returns a nav link if one exists for that block
$this_link = extract_nav_link($block);
remove_filter('pre_render_block', $extract_link);
$child_links = array_filter(extract_nav_links($block['innerBlocks']));
add_filter('pre_render_block', $extract_link, 10, 2);
// we could have non-link placeholder nodes in the nav tree whose children have links (some kind of group)
// or we could have link nodes with no children (an actual nav link, URL, or logo with link)
// or we could have non-link material without children (search bar)
return !empty($this_link) || !empty($child_links)
? [ 'link' => $this_link, 'sub_links' => $child_links ]
: [];
}
add_filter('pre_render_block', $extract_link, 10, 2);
$links = array_filter(array_map('render_block', $nav_blocks));
remove_filter('pre_render_block', $extract_link);
return $links;
} I think something like this would get out what you are asking for. The important piece is function extract_nav_link($block) {
switch ($block['blockName']) {
case 'core/link':
return $block['attrs']['url'];
case 'core/navigation-link':
return $block['attrs']['url'];
}
// take a wild guess
if (isset($block['attrs']['url']) {
return $block['attrs']['url'];
}
return null;
} |
Thanks for the quick follow-up, @dmsnell ! Yeah, I think that would work 👍
From my perspective and totally open to discussion, a good first selection of blocks that make for a nav item would be:
The reason to include |
Give it a try @priethor and let me know if things go awry - I'm happy to help out but I don't have the time on my plate at the moment to try it myself and have any reasonable ability to know if it's right. A quick warning though: I don't make any guarantee that the code I wrote above is correct or syntactically valid. It's likely something in there is wrong, but conceptually it should be right. Those first blocks seem fine and you'd want to put them in the function extract_nav_link($block) {
$name = $block['blockName'];
$attrs = $block['attrs'];
switch ($name) {
case 'core/link':
return $attrs['href'];
case 'core/navigation-link':
return $attrs['url'];
case 'core/home-link':
return home_url(); // or whatever is appropriate
case 'core/site-logo':
case 'core/site-title':
return $attrs['isLink'] ? home_url() : null;
}
return nulll;
} |
Can we consider cutting this for 5.9 so that we can free up valuable @adamziel resources for other bits? I absolutely agree we need this API for block themes to compete with classic themes going forward, but for WP 5.9 I’m personally okay with saying “yes, this is a temporary downside of using a block theme”. We are labelling them "Beta" after all. |
I think postponing this to after 5.9 can be a good compromise, as it would also allow us to define the public API better before committing to it in core. |
Consider it punted! 🥾 |
This is essentially obsolete now that |
What problem does this address?
As of 10.4-RC1, the Navigation block allows different kinds of inner blocks, from the most basic Navigation Link to the Search block, including layout-building ones like the Spacer block.
Because of this, obtaining a structured, link-only page hierarchy from a Navigation block (for example, to create a sitemap) is not as simple as gathering all inner blocks, as it would require discarding presentation-only blocks and other non-content ones.
What is your proposed solution?
The Navigation block should provide an API to retrieve content-only inner blocks.
The text was updated successfully, but these errors were encountered: