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

Add basic pages block #28265

Merged
merged 16 commits into from
Feb 8, 2021
Merged

Add basic pages block #28265

merged 16 commits into from
Feb 8, 2021

Conversation

tellthemachines
Copy link
Contributor

@tellthemachines tellthemachines commented Jan 18, 2021

Description

Closes #23689 .

Adds a dynamic Pages block that updates with new pages and can be added inside a Navigation block or used on its own.

Update: this is now ready for review.

I am using wp_list_pages to output the list of pages, and have extended Walker_Page to add the chevron to items containing children. Apart from that, I have kept the default output classnames. If we'd rather be more consistent with other block classnames, I can further extend the walker to change the li and submenu ul classes, but can't do much more than that, e.g. the a elements aren't changeable. Cc @shaunandrews @jasmussen

Upadate 2: This is now querying the pages and building the nested list manually; classnames are semantically closer to the Navigation block but not context-aware. See here for more details.

The editor view is using ServerSideRender because there's a notable performance benefit relative to rendering REST API data with JS. This means there's an extra div wrapper around the block contents in the editor, which there doesn't seem to be any way to stop ServerSideRender from outputting.

When the block is nested inside a Nav block, all settings are inherited except for custom colors, because there's a problem with how inline styles are set for Nav block children that needs to be solved separately.

I haven't added any fixtures or other tests yet, will do that once we determine the markup is all correct 😅 Tests added/fixed.

Speaking of which, this block rendering a ul container is inconsistent with the current Nav block markup which expects all its children to be li elements. I'm expecting that to be fixed by #24644 / #24364. The Pages block shouldn't be contained in a li as it can be used separately from the Nav block.

How has this been tested?

Screenshots

Types of changes

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR.

@github-actions
Copy link

github-actions bot commented Jan 18, 2021

Size Change: +3.79 kB (0%)

Total Size: 1.37 MB

Filename Size Change
build/annotations/index.js 3.77 kB -1 B (0%)
build/api-fetch/index.js 3.4 kB -1 B (0%)
build/block-directory/index.js 9.08 kB -4 B (0%)
build/block-editor/index.js 124 kB +616 B (0%)
build/block-editor/style-rtl.css 12 kB +21 B (0%)
build/block-editor/style.css 12 kB +21 B (0%)
build/block-library/blocks/buttons/editor-rtl.css 233 B +6 B (+3%)
build/block-library/blocks/buttons/editor.css 233 B +6 B (+3%)
build/block-library/blocks/buttons/style-rtl.css 303 B +6 B (+2%)
build/block-library/blocks/buttons/style.css 303 B +6 B (+2%)
build/block-library/blocks/cover/editor-rtl.css 390 B -2 B (-1%)
build/block-library/blocks/cover/editor.css 389 B -4 B (-1%)
build/block-library/blocks/embed/style-rtl.css 396 B +21 B (+6%) 🔍
build/block-library/blocks/embed/style.css 395 B +20 B (+5%) 🔍
build/block-library/blocks/navigation/style-rtl.css 174 B -9 B (-5%)
build/block-library/blocks/navigation/style.css 174 B -9 B (-5%)
build/block-library/blocks/social-links/style-rtl.css 1.37 kB +1 B (0%)
build/block-library/editor-rtl.css 9.15 kB +88 B (+1%)
build/block-library/editor.css 9.13 kB +89 B (+1%)
build/block-library/index.js 145 kB +1.04 kB (+1%)
build/block-library/style-rtl.css 8.78 kB +160 B (+2%)
build/block-library/style.css 8.78 kB +164 B (+2%)
build/block-serialization-default-parser/index.js 1.88 kB -1 B (0%)
build/blocks/index.js 48.3 kB +14 B (0%)
build/components/index.js 270 kB +1.14 kB (0%)
build/compose/index.js 11.2 kB +3 B (0%)
build/core-data/index.js 16.8 kB -2 B (0%)
build/data-controls/index.js 828 B +1 B (0%)
build/data/index.js 8.86 kB +61 B (+1%)
build/date/index.js 31.8 kB +2 B (0%)
build/deprecated/index.js 768 B -1 B (0%)
build/dom-ready/index.js 571 B +1 B (0%)
build/dom/index.js 4.93 kB +1 B (0%)
build/edit-navigation/index.js 11.2 kB +29 B (0%)
build/edit-navigation/style-rtl.css 1.01 kB +73 B (+8%) 🔍
build/edit-navigation/style.css 1.01 kB +69 B (+7%) 🔍
build/edit-site/index.js 24.3 kB +132 B (+1%)
build/editor/index.js 41.8 kB +13 B (0%)
build/format-library/index.js 6.77 kB +8 B (0%)
build/hooks/index.js 2.28 kB +9 B (0%)
build/html-entities/index.js 623 B +1 B (0%)
build/i18n/index.js 3.73 kB -13 B (0%)
build/keycodes/index.js 1.93 kB -1 B (0%)
build/media-utils/index.js 5.36 kB +21 B (0%)
build/notices/index.js 1.85 kB +1 B (0%)
build/nux/index.js 3.41 kB -1 B (0%)
build/plugins/index.js 2.54 kB -1 B (0%)
build/redux-routine/index.js 2.84 kB +3 B (0%)
build/shortcode/index.js 1.7 kB -1 B (0%)
build/token-list/index.js 1.27 kB -1 B (0%)
build/url/index.js 3.02 kB +1 B (0%)
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 1.14 kB 0 B
build/autop/index.js 2.84 kB 0 B
build/blob/index.js 665 B 0 B
build/block-directory/style-rtl.css 1.01 kB 0 B
build/block-directory/style.css 1.01 kB 0 B
build/block-library/blocks/archives/editor-rtl.css 61 B 0 B
build/block-library/blocks/archives/editor.css 60 B 0 B
build/block-library/blocks/audio/editor-rtl.css 58 B 0 B
build/block-library/blocks/audio/editor.css 58 B 0 B
build/block-library/blocks/audio/style-rtl.css 103 B 0 B
build/block-library/blocks/audio/style.css 103 B 0 B
build/block-library/blocks/block/editor-rtl.css 161 B 0 B
build/block-library/blocks/block/editor.css 161 B 0 B
build/block-library/blocks/button/editor-rtl.css 475 B 0 B
build/block-library/blocks/button/editor.css 474 B 0 B
build/block-library/blocks/button/style-rtl.css 453 B 0 B
build/block-library/blocks/button/style.css 451 B 0 B
build/block-library/blocks/calendar/style-rtl.css 208 B 0 B
build/block-library/blocks/calendar/style.css 208 B 0 B
build/block-library/blocks/categories/editor-rtl.css 84 B 0 B
build/block-library/blocks/categories/editor.css 83 B 0 B
build/block-library/blocks/categories/style-rtl.css 79 B 0 B
build/block-library/blocks/categories/style.css 79 B 0 B
build/block-library/blocks/code/style-rtl.css 90 B 0 B
build/block-library/blocks/code/style.css 90 B 0 B
build/block-library/blocks/columns/editor-rtl.css 190 B 0 B
build/block-library/blocks/columns/editor.css 190 B 0 B
build/block-library/blocks/columns/style-rtl.css 421 B 0 B
build/block-library/blocks/columns/style.css 421 B 0 B
build/block-library/blocks/cover/style-rtl.css 1.25 kB 0 B
build/block-library/blocks/cover/style.css 1.25 kB 0 B
build/block-library/blocks/embed/editor-rtl.css 486 B 0 B
build/block-library/blocks/embed/editor.css 486 B 0 B
build/block-library/blocks/file/editor-rtl.css 199 B 0 B
build/block-library/blocks/file/editor.css 198 B 0 B
build/block-library/blocks/file/style-rtl.css 248 B 0 B
build/block-library/blocks/file/style.css 248 B 0 B
build/block-library/blocks/freeform/editor-rtl.css 2.45 kB 0 B
build/block-library/blocks/freeform/editor.css 2.45 kB 0 B
build/block-library/blocks/gallery/editor-rtl.css 679 B 0 B
build/block-library/blocks/gallery/editor.css 679 B 0 B
build/block-library/blocks/gallery/style-rtl.css 1.07 kB 0 B
build/block-library/blocks/gallery/style.css 1.06 kB 0 B
build/block-library/blocks/group/editor-rtl.css 318 B 0 B
build/block-library/blocks/group/editor.css 317 B 0 B
build/block-library/blocks/group/style-rtl.css 57 B 0 B
build/block-library/blocks/group/style.css 57 B 0 B
build/block-library/blocks/heading/editor-rtl.css 129 B 0 B
build/block-library/blocks/heading/editor.css 129 B 0 B
build/block-library/blocks/heading/style-rtl.css 76 B 0 B
build/block-library/blocks/heading/style.css 76 B 0 B
build/block-library/blocks/html/editor-rtl.css 281 B 0 B
build/block-library/blocks/html/editor.css 281 B 0 B
build/block-library/blocks/image/editor-rtl.css 717 B 0 B
build/block-library/blocks/image/editor.css 716 B 0 B
build/block-library/blocks/image/style-rtl.css 477 B 0 B
build/block-library/blocks/image/style.css 478 B 0 B
build/block-library/blocks/latest-comments/editor-rtl.css 159 B 0 B
build/block-library/blocks/latest-comments/editor.css 158 B 0 B
build/block-library/blocks/latest-comments/style-rtl.css 269 B 0 B
build/block-library/blocks/latest-comments/style.css 269 B 0 B
build/block-library/blocks/latest-posts/editor-rtl.css 137 B 0 B
build/block-library/blocks/latest-posts/editor.css 137 B 0 B
build/block-library/blocks/latest-posts/style-rtl.css 523 B 0 B
build/block-library/blocks/latest-posts/style.css 522 B 0 B
build/block-library/blocks/list/editor-rtl.css 65 B 0 B
build/block-library/blocks/list/editor.css 65 B 0 B
build/block-library/blocks/list/style-rtl.css 63 B 0 B
build/block-library/blocks/list/style.css 63 B 0 B
build/block-library/blocks/media-text/editor-rtl.css 191 B 0 B
build/block-library/blocks/media-text/editor.css 191 B 0 B
build/block-library/blocks/media-text/style-rtl.css 535 B 0 B
build/block-library/blocks/media-text/style.css 532 B 0 B
build/block-library/blocks/more/editor-rtl.css 434 B 0 B
build/block-library/blocks/more/editor.css 434 B 0 B
build/block-library/blocks/navigation-link/editor-rtl.css 392 B 0 B
build/block-library/blocks/navigation-link/editor.css 394 B 0 B
build/block-library/blocks/navigation-link/style-rtl.css 704 B 0 B
build/block-library/blocks/navigation-link/style.css 702 B 0 B
build/block-library/blocks/navigation/editor-rtl.css 1.38 kB 0 B
build/block-library/blocks/navigation/editor.css 1.37 kB 0 B
build/block-library/blocks/nextpage/editor-rtl.css 395 B 0 B
build/block-library/blocks/nextpage/editor.css 395 B 0 B
build/block-library/blocks/page-list/editor-rtl.css 214 B 0 B
build/block-library/blocks/page-list/editor.css 214 B 0 B
build/block-library/blocks/page-list/style-rtl.css 527 B 0 B
build/block-library/blocks/page-list/style.css 526 B 0 B
build/block-library/blocks/paragraph/editor-rtl.css 109 B 0 B
build/block-library/blocks/paragraph/editor.css 109 B 0 B
build/block-library/blocks/paragraph/style-rtl.css 273 B 0 B
build/block-library/blocks/paragraph/style.css 273 B 0 B
build/block-library/blocks/post-author/editor-rtl.css 209 B 0 B
build/block-library/blocks/post-author/editor.css 209 B 0 B
build/block-library/blocks/post-author/style-rtl.css 183 B 0 B
build/block-library/blocks/post-author/style.css 184 B 0 B
build/block-library/blocks/post-comments-form/style-rtl.css 249 B 0 B
build/block-library/blocks/post-comments-form/style.css 249 B 0 B
build/block-library/blocks/post-content/editor-rtl.css 139 B 0 B
build/block-library/blocks/post-content/editor.css 139 B 0 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B 0 B
build/block-library/blocks/post-excerpt/editor.css 73 B 0 B
build/block-library/blocks/post-featured-image/editor-rtl.css 338 B 0 B
build/block-library/blocks/post-featured-image/editor.css 338 B 0 B
build/block-library/blocks/post-featured-image/style-rtl.css 100 B 0 B
build/block-library/blocks/post-featured-image/style.css 100 B 0 B
build/block-library/blocks/preformatted/style-rtl.css 63 B 0 B
build/block-library/blocks/preformatted/style.css 63 B 0 B
build/block-library/blocks/pullquote/editor-rtl.css 183 B 0 B
build/block-library/blocks/pullquote/editor.css 183 B 0 B
build/block-library/blocks/pullquote/style-rtl.css 316 B 0 B
build/block-library/blocks/pullquote/style.css 316 B 0 B
build/block-library/blocks/query-loop/editor-rtl.css 90 B 0 B
build/block-library/blocks/query-loop/editor.css 89 B 0 B
build/block-library/blocks/query-loop/style-rtl.css 315 B 0 B
build/block-library/blocks/query-loop/style.css 317 B 0 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B 0 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B 0 B
build/block-library/blocks/query-pagination/editor-rtl.css 270 B 0 B
build/block-library/blocks/query-pagination/editor.css 262 B 0 B
build/block-library/blocks/query-pagination/style-rtl.css 168 B 0 B
build/block-library/blocks/query-pagination/style.css 168 B 0 B
build/block-library/blocks/query/editor-rtl.css 159 B 0 B
build/block-library/blocks/query/editor.css 160 B 0 B
build/block-library/blocks/quote/editor-rtl.css 61 B 0 B
build/block-library/blocks/quote/editor.css 61 B 0 B
build/block-library/blocks/quote/style-rtl.css 169 B 0 B
build/block-library/blocks/quote/style.css 169 B 0 B
build/block-library/blocks/rss/editor-rtl.css 201 B 0 B
build/block-library/blocks/rss/editor.css 202 B 0 B
build/block-library/blocks/rss/style-rtl.css 290 B 0 B
build/block-library/blocks/rss/style.css 290 B 0 B
build/block-library/blocks/search/editor-rtl.css 165 B 0 B
build/block-library/blocks/search/editor.css 165 B 0 B
build/block-library/blocks/search/style-rtl.css 342 B 0 B
build/block-library/blocks/search/style.css 344 B 0 B
build/block-library/blocks/separator/editor-rtl.css 99 B 0 B
build/block-library/blocks/separator/editor.css 99 B 0 B
build/block-library/blocks/separator/style-rtl.css 236 B 0 B
build/block-library/blocks/separator/style.css 236 B 0 B
build/block-library/blocks/shortcode/editor-rtl.css 504 B 0 B
build/block-library/blocks/shortcode/editor.css 504 B 0 B
build/block-library/blocks/site-logo/editor-rtl.css 201 B 0 B
build/block-library/blocks/site-logo/editor.css 201 B 0 B
build/block-library/blocks/site-logo/style-rtl.css 117 B 0 B
build/block-library/blocks/site-logo/style.css 117 B 0 B
build/block-library/blocks/social-link/editor-rtl.css 164 B 0 B
build/block-library/blocks/social-link/editor.css 165 B 0 B
build/block-library/blocks/social-links/editor-rtl.css 711 B 0 B
build/block-library/blocks/social-links/editor.css 712 B 0 B
build/block-library/blocks/social-links/style.css 1.37 kB 0 B
build/block-library/blocks/spacer/editor-rtl.css 302 B 0 B
build/block-library/blocks/spacer/editor.css 302 B 0 B
build/block-library/blocks/spacer/style-rtl.css 48 B 0 B
build/block-library/blocks/spacer/style.css 48 B 0 B
build/block-library/blocks/subhead/editor-rtl.css 99 B 0 B
build/block-library/blocks/subhead/editor.css 99 B 0 B
build/block-library/blocks/subhead/style-rtl.css 80 B 0 B
build/block-library/blocks/subhead/style.css 80 B 0 B
build/block-library/blocks/table/editor-rtl.css 489 B 0 B
build/block-library/blocks/table/editor.css 489 B 0 B
build/block-library/blocks/table/style-rtl.css 386 B 0 B
build/block-library/blocks/table/style.css 386 B 0 B
build/block-library/blocks/tag-cloud/editor-rtl.css 118 B 0 B
build/block-library/blocks/tag-cloud/editor.css 118 B 0 B
build/block-library/blocks/tag-cloud/style-rtl.css 94 B 0 B
build/block-library/blocks/tag-cloud/style.css 94 B 0 B
build/block-library/blocks/template-part/editor-rtl.css 680 B 0 B
build/block-library/blocks/template-part/editor.css 679 B 0 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B 0 B
build/block-library/blocks/text-columns/editor.css 95 B 0 B
build/block-library/blocks/text-columns/style-rtl.css 166 B 0 B
build/block-library/blocks/text-columns/style.css 166 B 0 B
build/block-library/blocks/verse/editor-rtl.css 62 B 0 B
build/block-library/blocks/verse/editor.css 62 B 0 B
build/block-library/blocks/verse/style-rtl.css 87 B 0 B
build/block-library/blocks/verse/style.css 87 B 0 B
build/block-library/blocks/video/editor-rtl.css 504 B 0 B
build/block-library/blocks/video/editor.css 503 B 0 B
build/block-library/blocks/video/style-rtl.css 193 B 0 B
build/block-library/blocks/video/style.css 193 B 0 B
build/block-library/common-rtl.css 1.01 kB 0 B
build/block-library/common.css 1.01 kB 0 B
build/block-library/theme-rtl.css 748 B 0 B
build/block-library/theme.css 748 B 0 B
build/block-serialization-spec-parser/index.js 3.06 kB 0 B
build/components/style-rtl.css 15.5 kB 0 B
build/components/style.css 15.5 kB 0 B
build/edit-post/index.js 307 kB 0 B
build/edit-post/style-rtl.css 6.79 kB 0 B
build/edit-post/style.css 6.78 kB 0 B
build/edit-site/style-rtl.css 4.04 kB 0 B
build/edit-site/style.css 4.04 kB 0 B
build/edit-widgets/index.js 20.1 kB 0 B
build/edit-widgets/style-rtl.css 3.2 kB 0 B
build/edit-widgets/style.css 3.2 kB 0 B
build/editor/editor-styles-rtl.css 543 B 0 B
build/editor/editor-styles.css 545 B 0 B
build/editor/style-rtl.css 3.89 kB 0 B
build/editor/style.css 3.89 kB 0 B
build/element/index.js 4.62 kB 0 B
build/escape-html/index.js 735 B 0 B
build/format-library/style-rtl.css 637 B 0 B
build/format-library/style.css 639 B 0 B
build/is-shallow-equal/index.js 699 B 0 B
build/keyboard-shortcuts/index.js 2.54 kB 0 B
build/list-reusable-blocks/index.js 3.15 kB 0 B
build/list-reusable-blocks/style-rtl.css 629 B 0 B
build/list-reusable-blocks/style.css 628 B 0 B
build/nux/style-rtl.css 731 B 0 B
build/nux/style.css 727 B 0 B
build/primitives/index.js 1.42 kB 0 B
build/priority-queue/index.js 791 B 0 B
build/reusable-blocks/index.js 2.92 kB 0 B
build/rich-text/index.js 13.4 kB 0 B
build/server-side-render/index.js 2.77 kB 0 B
build/viewport/index.js 1.86 kB 0 B
build/warning/index.js 1.14 kB 0 B
build/wordcount/index.js 1.22 kB 0 B

compressed-size-action

@jasmussen
Copy link
Contributor

Thanks so much for working on this!

@shaunandrews
Copy link
Contributor

Very cool to see this in the works! Here's what I see when the Pages block lives alone:

image

And here's how it looks when placed inside the Navigation block:

image

@tellthemachines
Copy link
Contributor Author

I've got most of the styles for displaying submenus as dropdowns in the nav block, but dropdown background colour isn't working yet because Pages isn't inheriting the styles from the parent yet.

Submenu icons is also not wired to the parent yet - but I'm not sure it makes sense to have it as a setting in the standalone Pages block, unless we provide the option to use dropdowns there, too. The problem is I can't think of a way to render the icons in Pages unless that exists as a setting 🤔

@jasmussen
Copy link
Contributor

Submenu icons is also not wired to the parent yet - but I'm not sure it makes sense to have it as a setting in the standalone Pages block, unless we provide the option to use dropdowns there, too. The problem is I can't think of a way to render the icons in Pages unless that exists as a setting 🤔

Can the pages block inherit whatever property is set on the Navigation Container? I.e. if the pages block is inside the navigation block, and the navigation block has the option toggled on, so does the Pages block?

@jasmussen
Copy link
Contributor

This is so good. So so good. Thank you for working on this. Here's what I see:

Screenshot 2021-01-21 at 08 47 04

That's the Pages block inside navigation. I then proceeded to create a new page, "Journal", and sure enough, it shows up automatically when I reload:

Screenshot 2021-01-21 at 08 47 31

This is the promise of the block itself, and it feels totally validated by this.

I need to do some deeper testing, specifically with regards to how subpages work. But just as an initial test, this is very promising.

Some small things:

Screenshot 2021-01-21 at 08 46 24

Can we make it so when you press "Add all pages", it adds just this one block, as opposed to all the individual menu links?

Screenshot 2021-01-21 at 08 46 54

We should probably rename this one from "Pages" to something else. "Page Listing" was suggested, that might be worth a try.

I'd also like to provide you with a new icon for this one, I shall return.

Finally, something is making the markup and visual appearance differ from individual menu items, compared to items from that page listing. I have a black underline in my theme that shows up for the page listing (see above), but it's gone for individual items:

Screenshot 2021-01-21 at 08 46 28

I'd like to dive in and see what that might be and how I can potentially fix it. It's probably a separate thing regardless, but thought I should mention it.

The vertical menu still shows up as horizontal:

Screenshot 2021-01-21 at 08 52 25

I can also click on the menu items:

Screenshot 2021-01-21 at 08 52 34

We can probably make the menu items inactive using CSS, pointer-events: none; — that's also necessary for the Page Listing block to be selectable at all.

I was able to select the page listing block using the block navigator:

Screenshot 2021-01-21 at 08 54 15

How hard would it be to add a button in the page listing block toolbar that says "Convert to individual menu items"? (Or a shorter phrase if we can think of one)

Thanks again for your work 🏅

@talldan
Copy link
Contributor

talldan commented Jan 21, 2021

Working really nicely so far.

I'd worry that the heavy reliance on server side rendering and the walker might end up being a limiting factor in future changes, like if we want to change the markup.

The alternative (making it work more like the query block does) would be pretty complicated though, so might be best to go for the simple solution first and see how well it works (which I think is pretty successful so far).

I echo most of what was said in the other feedback. TT1-Blocks has a couple of issues (pages always appear vertically, and submenus don't open). In TT1 normal, the submenus are a little narrow for longer menu names:
Screenshot 2021-01-21 at 5 59 42 pm

@tellthemachines
Copy link
Contributor Author

Can we make it so when you press "Add all pages", it adds just this one block, as opposed to all the individual menu links?

Done ✅

We should probably rename this one from "Pages" to something else. "Page Listing" was suggested, that might be worth a try.

Could it be "Page list" instead? "Listing" sounds more like a single listed item, so may be confusing.

I have a black underline in my theme that shows up for the page listing (see above), but it's gone for individual items:

In the editor, it's the default browser a styles being applied, and that doesn't happen for individual items because they aren't a but contenteditable divs. In the front end, it's generic theme styling for a (guessing that based on TT1), that is overridden for Navigation link blocks specifically. I guess we'll have to wait for a theme update to fix it once this block is merged.

The vertical menu still shows up as horizontal
I can also click on the menu items

Fixed, and fixed!

How hard would it be to add a button in the page listing block toolbar that says "Convert to individual menu items"?

I thought initially that it would be simple to transform a Pages block into a Links block once #24644 is done, but given that Pages should work as a standalone block, would we want that functionality to also apply when it isn't part of a Navigation? We don't have any way of conditionally rendering controls depending on the parent block (I think - because blocks aren't supposed to be aware of their parents) so not sure how we'd go about making it Navigation specific.

The alternative (making it work more like the query block does) would be pretty complicated though

I'm more worried both about the performance impact (which is hard to tell now because query only renders 10 items at a time - unless I'm missing something) and the duplication of markup (query loop has its ul and li structure repeated in both edit and index.php, which is not ideal, especially when we have more complex markup with nested lists).

TT1-Blocks has a couple of issues (pages always appear vertically, and submenus don't open

Hmm, I can't reproduce that by adding a Nav block with a Pages block inside the header in the site editor 🤔

@jasmussen
Copy link
Contributor

jasmussen commented Jan 22, 2021

Could it be "Page list" instead?

Go for it!

In the editor, it's the default browser a styles being applied, and that doesn't happen for individual items because they aren't a but contenteditable divs. In the front end, it's generic theme styling for a (guessing that based on TT1), that is overridden for Navigation link blocks specifically. I guess we'll have to wait for a theme update to fix it once this block is merged.

Thanks for the investigative work. Seems like it would be nice if we were able to change those contenteditable divs to contenteditable a tags. Not even sure if that's possible, and would need to be a separate thing regardless. Otherwise, fixable easily in an editor style. Thank you.

I thought initially that it would be simple to transform a Pages block into a Links block once #24644 is done, but given that Pages should work as a standalone block, would we want that functionality to also apply when it isn't part of a Navigation? We don't have any way of conditionally rendering controls depending on the parent block (I think - because blocks aren't supposed to be aware of their parents) so not sure how we'd go about making it Navigation specific.

Definitely best to try and avoid making anything Navigation specific if we can. But "navigation aware" might not be the end of the world if it's done in a clean way.

Specifically, I'm not sure that this Pages (or Page List) block has to work outside of the navigation block. I think that's a really nice benefit.

And yes, I think it would be totally fine to have that functionality also work when used on its own. I compare it to a gallery of 5 images, which you can transform to 5 individual image blocks. (I realize here the transformation from Page List to individual Paragraphs with links inside them would be an irreversible transformation, but I don't see that necessarily as a problem). Edit: I'm just realizing that they'd need to transform to Link blocks, which to your point probably wouldn't work outside the nav block? :thinkspin:

@talldan
Copy link
Contributor

talldan commented Jan 22, 2021

I thought initially that it would be simple to transform a Pages block into a Links block once #24644 is done, but given that Pages should work as a standalone block, would we want that functionality to also apply when it isn't part of a Navigation? We don't have any way of conditionally rendering controls depending on the parent block (I think - because blocks aren't supposed to be aware of their parents) so not sure how we'd go about making it Navigation specific.

This might not be an issue, I don't think the transform system will show a transform to a block that can't be inserted.

Worth double-checking, but an example is that you can't transform a Nav Link to a Group because Group isn't allowed in Navigation.

@jasmussen
Copy link
Contributor

I am so excited for this PR to land, it really improves things.

Instead of the "page" icon you're using for the new block, I created a new icon you can add as "pages":

Screenshot 2021-01-25 at 12 39 39

Here's the SVG:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 13.8h6v-1.5H7v1.5zM18 16V4c0-1.1-.9-2-2-2H6c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2zM5.5 16V4c0-.3.2-.5.5-.5h10c.3 0 .5.2.5.5v12c0 .3-.2.5-.5.5H6c-.3 0-.5-.2-.5-.5zM7 10.5h8V9H7v1.5zm0-3.3h8V5.8H7v1.4zM20.2 6v13c0 .7-.6 1.2-1.2 1.2H8v1.5h11c1.5 0 2.7-1.2 2.7-2.8V6h-1.5z" /></svg>

Let me know if you'd like me to push directly to your branch to add this.

@jasmussen
Copy link
Contributor

This one fixes #16635.

@tellthemachines
Copy link
Contributor Author

Ok, I think I've addressed all the feedback, so if everything is now OK I'll move onto adding some tests for this block.

The transform from Page List to Links is dependent on #24644, so let's do it as a separate PR later.

@jasmussen
Copy link
Contributor

So excited for this one, thanks again. I'm happy to push the icon change separately.

A quick question just to be sure — you mentioned how on the frontend and the page list, the links are links (a), and custom menu items have contenteditable divs. Not necessarily as part of this branch, but can we change those divs to contentedtiable a's as well? From a very quick codepen sanity check it doesn't seem impossible, but I'm very probably missing something.

The consistency in markup between menu items would really simplify some of the CSS!

@tellthemachines
Copy link
Contributor Author

I'm happy to push the icon change separately.

Whoops, I made the change and then forgot to push it 😳

Not necessarily as part of this branch, but can we change those divs to contentedtiable a's as well?

Let's try that as a separate task! I can't think offhand of reasons not to do it, but might be missing something.

@tellthemachines
Copy link
Contributor Author

I've added the tests, so this is ready for a final review now!

@jasmussen
Copy link
Contributor

Let's try that as a separate task! I can't think offhand of reasons not to do it, but might be missing something.

Awesome. Want me to ticket it?

I'm seeing jump when the page list loads:

Screenshot 2021-01-28 at 12 03 27

You can fix that with this CSS:

.wp-block-navigation .components-placeholder {
	min-height: 0;
	padding: 0;

	.components-spinner {
		margin-top: 0;
	}
}

Then it looks like this:

Screenshot 2021-01-28 at 12 08 33


I noticed submenus have no background:

Screenshot 2021-01-28 at 12 15 55

This is because the markup for the child blocks is this:

<ul class="children">
	<li class="page_item page-item-263"><a href="http://localhost:8888/?page_id=263">This is a subpage</a></li>
	<li class="page_item page-item-265"><a href="http://localhost:8888/?page_id=265">This is another subpage</a></li>
</ul>

This is compared to the markup of "classic" navigation submenus:

<ul class="wp-block-navigation__container">
   <li class="wp-block-navigation-link"><a class="wp-block-navigation-link__content" href="http://localhost:8888/?page_id=265"><span class="wp-block-navigation-link__label">This is another subpage</span></a></li>
   <li class="wp-block-navigation-link"><a class="wp-block-navigation-link__content" href="http://localhost:8888/?page_id=263"><span class="wp-block-navigation-link__label">This is a subpage</span></a></li>
</ul>

I know there's a goal to make this Page List block work outside of the navigation block. Can it be aware of its parent, and show the navigation-block appropriate CSS classes when it's used there?


Finally, I'm really missing that feature to convert a Page List block into menu items. Whether that's a transformation, or a button in the toolbar, "Convert to menu items", it's important that we land this feature. Doesn't necessarily have to be part of this PR specifically, but we should have some confidence that it's possible to do, so we can follow up with it.

Those were the three things I found. But the primary take-away: this is feeling so good, and it even feels sort of obvious and predictable. I think it will solve a bunch of headaches, thank you again for working on this!

@draganescu
Copy link
Contributor

Adding the new block in the navigation block produced this result on Edge:

Front end:

image

Back end:

image

Also clicking on the page items navigates to the page, which is different from the behavior of the other links in paragraphs or navigation menus, that don't navigate.

With children the styling is still different, is it intentional?

image

From the PR's description it looks like this is expected since I guess the differences in markup make this block appear different. Will a solution to #24644 / #24364. also fix these visual inconsistencies?

Copy link
Contributor

@talldan talldan left a comment

Choose a reason for hiding this comment

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

Others have done a fair amount of testing, so this review focuses mostly on code. Looks good so far.

I'm also still not sure about using the walker approach, we can always try different things once shipped if it feels like it's not working for us. I think that's one of the main reasons we should keep it behind a the GUTENBERG_PHASE flag for now (although I think it'll miss 5.7 anyway).

packages/block-library/src/index.js Show resolved Hide resolved
clientId,
'core/navigation'
)[ 0 ];
return getBlockAttributes( parentBlock );
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should be able to use block context instead of selecting from the navigation block's attributes via the block-editor store.

The good thing is it's a bit easier, it's just passed in as a prop:
https://developer.wordpress.org/block-editor/developers/block-api/block-context/#using-block-context

Looks like we should also make this change to nav link at some point as well.

packages/block-library/src/page-list/index.js Show resolved Hide resolved
packages/block-library/src/page-list/index.js Show resolved Hide resolved
.wp-block-page-list {
background-color: inherit;
}
// Make links unclickable in the editor
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the <Disabled> component was the previous way of doing this (see the Archives block). Not sure what the pros/cons are of the two ways.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, that won't work here because Disabled will prevent any dropdowns from opening. It works for Archives because there are no nesting levels there. It uses the same CSS to achieve the purpose though.

@tellthemachines
Copy link
Contributor Author

Mostly, I'm about to dive into issues of styling the CSS of the navigation block, including submenus. That means frontend and backend ideally looking identical the whole way through. This is why it would it would be so helpful if the CSS classes were the same whether a dropdown menu was inside the Page List block, or manually created.

That makes sense! I'm going to explore another way of rendering the markup server-side which will allow us more flexibility. Potentially we could use the "show submenu icon" context to ascertain whether the block is inside a Navigation block, though it feels slightly hacky to do so 😬 🤔

I recall a separate conversation about creating a "dropdown menu component". Could this effort let us explore having identical CSS classes, if not markup, frontend and editor?

Probably not in this case, because Page list doesn't have inner blocks. Its contents are not supposed to be editable, so we're generating the markup for the dropdowns server-side. That doesn't mean the classnames can't match though.

I'm thinking perhaps we could change the classname we're hooking the dropdown styles to in the Navigation block to something more generic, e.g. instead of wp-block-navigation__container maybe submenu__container? So we could use that class across different blocks, and potentially also in a future Dropdown block. Then we only need to specify styles for .wp-block-navigation .submenu__container and it'll also apply to any Page list that might be inside Navigation.

(submenu might not be the best word here - it would be good to describe the semantics of it more than the presentation, so I'm avoiding dropdown. Maybe childlist? Which blocks would we be able to use a Dropdown block inside of?)

Is adding a "Transform to Links" option out of scope for this PR? It'd be handy to be able to break up the Page List block into individual Link blocks so I could customize a label or remove an item.

Similar, can we add a "Transform to Navigation" option for the Page List block, which would then wrap it in a Navigation block. Perhaps best left for another PR?

Yeah, "Transform to Links" is waiting on #24644, so best do it as a separate task. We can do a follow-up PR to add all the transforms.

@jasmussen
Copy link
Contributor

Potentially we could use the "show submenu icon" context to ascertain whether the block is inside a Navigation block, though it feels slightly hacky to do so 😬 🤔

I believe that we will be seeing a lot more of this blocks being aware of their containers in the future. For example a task block could become a task list when inside a list block. Or perhaps more imminently, a nested Image block inside a Gallery block could gain new powers of awareness of parent properties such as "Open images in new tabs". CC: @glendaviesnz in case he has input here.

@tellthemachines
Copy link
Contributor Author

Alright, I got rid of the walker and we're now iterating through the pages and building the nested list manually, so it's easier to customise the markup to our hearts' content. But we're not able to use parent block context to conditionally render markup yet: it works on the front end, but isn't recognised when using ServerSideRender in the editor. I think this is because the REST API block-renderer endpoint isn't aware of block context.

I'll write up an issue so we can look into the best way of doing this. I'm not convinced that client-side rendering in the editor is in our best interest, as there's a noticeable performance degradation compared to server-side rendering.

In the meantime, I think we've exhausted the limits of what can be done in this PR. Final reviews welcome!

Copy link
Contributor

@talldan talldan left a comment

Choose a reason for hiding this comment

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

Blitz those final things and I reckon this can be merged.

Great job with the refactor away from the walker. I really like this block and think it'll probably be how a lot of people build menus, given how it just automatically works.

Any thoughts on next steps? Probably filtering the pages (category/tag) would be useful.

static $block_id = 0;
$block_id++;

$all_pages = get_pages();
Copy link
Contributor

@talldan talldan Feb 4, 2021

Choose a reason for hiding this comment

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

I noticed that my page with an order of 0 is appearing at the end (after items with an order greater than 0). It looks like we might need to use some of the params for get_pages (https://developer.wordpress.org/reference/functions/get_pages/).

Copy link
Contributor

Choose a reason for hiding this comment

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

Looking closer, I was unsure if this would work because the resulting array that is built below ($top_level_pages) uses a key rather than an array index. In JavaScript that would result in the array being ordered by the key (or if using an object not ordered at all), but it looks like that's not the case in PHP:
https://stackoverflow.com/questions/10914730/are-php-associative-arrays-ordered

You can put them in whatever order you like, even when using numbers. Weird!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah these are really objects, not arrays as we understand them in JS 😅

I'm not sure what the page order setting is supposed to do, apart from changing the order of display in wp-admin/edit.php?post_type=page. Trying to add all pages to a classic menu, the numbered ones are sitting between 0s too 🤷‍♀️

I'd expect get_pages to offer a way of sorting them by order but it doesn't seem to, and I'm following the default order get_pages returns them in (apparently ASC).

Copy link
Contributor

Choose a reason for hiding this comment

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

The pages widget does sort in the right order though, so probably good to replicate that, and it seems like an improvement over the old menus.

For get_pages, the sort_column argument should make sure the order is used for sorting. It's a shame there's no way to specify a secondary sort.

get_pages( array( sort_column => 'menu_order' ) );

Copy link
Contributor

@talldan talldan Feb 5, 2021

Choose a reason for hiding this comment

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

I did some more investigation into this, as I became intrigued by the hierarchical argument of get_pages, which is always true. I couldn't figure out what this did until I looked at the code.

It looks like if you do get_pages( array( 'sort_column' => 'menu_order' ) ), it by default returns all the pages in an order that takes the nesting into account. The return value is a flat array, but the nested items are in the correct position. It looks like it should be possible to simplify how the nesting works in this block.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure there's much simplification can be done, as we still need to nest child pages under parents to generate the proper markup, so we need the pages to be indexed by their ID, which they're not when output by get_pages. I can't think of an easier way of doing this, but suggestions welcome!

Copy link
Contributor

@talldan talldan Feb 8, 2021

Choose a reason for hiding this comment

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

Yeah, it is still pretty tricky. I expected hierarchical to build a nested array much like you've done in this PR. I think to render in this format, the rendering loop would have to walk ahead to the next items to determine if they're children, and then add the nesting markup when that's the case.

Does feel a bit like an unnecessary refactoring given what's in this PR works, so maybe not worth it.

It could still be a decent optimisation to set hierarchical option to false in the pages block, as get_pages does a whole bunch of work that's not needed:

packages/block-library/src/page-list/index.php Outdated Show resolved Hide resolved
packages/block-library/src/page-list/index.php Outdated Show resolved Hide resolved
packages/block-library/src/page-list/index.php Outdated Show resolved Hide resolved
packages/block-library/src/page-list/block.json Outdated Show resolved Hide resolved
Comment on lines 139 to 147
/**
* Renders the `core/page-list` block on server.
*
* @param array $attributes The block attributes.
* @param array $content The saved content.
* @param array $block The parsed block.
*
* @return string Returns the page list markup.
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like this became indented

@talldan talldan added [Type] Feature New feature to highlight in changelogs. New Block Suggestion for a new block labels Feb 5, 2021
Copy link
Contributor

@talldan talldan left a comment

Choose a reason for hiding this comment

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

Great work here 🎉

Lets just see if the ordering issue can be fixed quickly before merging, but if not it can be looked at in a follow-up as an improvement.


if ( $block->context && $block->context['showSubmenuIcon'] ) {
$css_classes .= ' show-submenu-icons';
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I would move this to it's own setter like block_core_page_add_context_classes( $context, $classes ).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would that include just this if statement, or the whole classname setting logic? The colours and font-size classes set above are also derived from context.

With the submenu icons in particular, I'm hoping we can remove this class soon, and just render the submenu icons whenever they are needed. The problem is we're server side rendering the block in the editor, and ServerSideRender doesn't recognise context. There's some more discussion on this problem in #28684 . Anyway, I'd leave this as is for now and revisit later pending the outcome of that discussion.

@jasmussen
Copy link
Contributor

🔥

@@ -148,6 +149,7 @@ export const __experimentalGetCoreBlocks = () => [
missing,
more,
nextpage,
pageList,
Copy link
Contributor

@youknowriad youknowriad Feb 15, 2021

Choose a reason for hiding this comment

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

So this block is stable and independent of the navigation block, which means it's going to be included in the next WP major (5.8) regardless of the status of the Navigation block, I just want to make sure this is a conscious decision.

Copy link
Contributor

Choose a reason for hiding this comment

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

@tellthemachines was the block meant to be tweaked with regards to syntax, or is it pretty much baked as is?

Copy link
Member

Choose a reason for hiding this comment

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

It seems we should keep this tied to the navigation block (and its child blocks) for a bit

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In making this an independent block, I was thinking of the Widgets editor, as we don't currently have another block that can reproduce the Pages widget functionality. Assuming we want the Widgets editor to have feature parity with the legacy widgets screen, this block will be needed.

I'm happy with its current syntax, and the fact that it gets whatever styling properties from Navigation block context means that when used standalone, it works just like the Categories or the Archives block, that don't have any styling options.

Related question: should Categories also work as a child of Navigation? There's definitely a use case for categories in menus.

"customBackgroundColor",
"fontSize",
"customFontSize",
"showSubmenuIcon"
Copy link
Contributor

Choose a reason for hiding this comment

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

It feels like "context" is being abused in the navigation block, what happens if I use this block independently and I want to customize these things?

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 only four months late to this PR, but it sounds like we should try to let Global Styles absorb some of this (cc @nosolosw, @mtias).

Copy link
Member

Choose a reason for hiding this comment

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

Looked a bit at this. It relates to the block support mechanism and parent/child relationship.

Braindump of what we have now:

  • a block wants to serialize styles to its wrapper => default supports mechanism
  • a block wants to serialize styles to any other node => support mechanism with skip serialization (but only for its own markup, can't affect children)
  • a block wants to serialize styles to children blocks or or a children wants to take styles from the parent => block context

One thing we could explore would be to allow blocks to automatically expose some block supports via context without having to declare context support explicitely. Was that what you had in mind, Miguel?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added the context in to match the Navigation Link block, so that all the links in the Navigation could be styled equally. When Page List is used as an independent block, those styling options aren't available. This seemed ok as the standalone block reproduces the functionality of the Pages widget, and similar blocks like Latest Posts also have limited styling.
As for the styling mechanism used I think we should go with the same strategy for both Navigation Link and Page List so that they work consistently inside the Navigation block, but I'm not super knowledgeable about how Global Styles work so not sure what it might look like!

Copy link
Contributor

Choose a reason for hiding this comment

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

One thing we could explore would be to allow blocks to automatically expose some block supports via context without having to declare context support explicitely. Was that what you had in mind, Miguel?

Actually, I'm much less concerned about explicitly including Global Styles / Block Supports keys under usesContext, than I am about manually replicating some of gutenberg_apply_colors_support as part of render_block_core_page_list (see block_core_page_list_build_css_colors). This is where I think it'd be best to see where, if anywhere, GS/BS could improve to accommodate scenarios like Page List.

Copy link
Member

Choose a reason for hiding this comment

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

In playing with this code I've noticed the block attributes and the block context have the same shape, so we can apply the same transformations on that data to create classes and styles ― it's a matter of finding how.

A small step in making both cases more similar could be #32807 (experimented only with colors to see how it feels).

"customBackgroundColor",
"fontSize",
"customFontSize",
"showSubmenuIcon"
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 only four months late to this PR, but it sounds like we should try to let Global Styles absorb some of this (cc @nosolosw, @mtias).

static $block_id = 0;
$block_id++;

$all_pages = get_pages( array( 'sort_column' => 'menu_order' ) );
Copy link
Contributor

Choose a reason for hiding this comment

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

@tellthemachines: Is there a discussion somewhere in GH about limiting this query with number?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't recall there being any discussion on that. I did test it with lots (several hundreds) of pages and it works ok because the block is server rendered. If we wanted to render it on the client side in the editor (I recall some talk about this at one point - possibly with @gwwar ?) it might be a different matter.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think some reasonable limit could be set for both server/client. Any client side implementation will hit issues much sooner (eg needing to fetch all results via API+ potentially adding a ton of navigation links).

There's should already be a limit for the page-list -> navigation links conversion, where we won't display the option if there are too many pages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Page List Affects the Page List Block New Block Suggestion for a new block [Type] Feature New feature to highlight in changelogs.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

New "Pages" Block: Display a list of links to a site's pages
10 participants