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

Show all template parts using the edited navigation #55782

Closed
wants to merge 16 commits into from

Conversation

draganescu
Copy link
Contributor

@draganescu draganescu commented Nov 1, 2023

Co-authored-by: Dennis Snell [email protected]

What

This PR shows which template parts use a navigation menu when the menu is edited in isolation in the site editor:

Screen recording

menu-used-in.mp4

Copy link

github-actions bot commented Nov 1, 2023

This pull request has changed or added PHP files. Please confirm whether these changes need to be synced to WordPress Core, and therefore featured in the next release of WordPress.

If so, it is recommended to create a new Trac ticket and submit a pull request to the WordPress Core Github repository soon after this pull request is merged.

If you're unsure, you can always ask for help in the #core-editor channel in WordPress Slack.

Thank you! ❤️

View changed files
❔ lib/init.php

Copy link

github-actions bot commented Nov 1, 2023

Flaky tests detected in c9ddbfa.
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/7607871618
📝 Reported issues:

@draganescu draganescu added [Type] Enhancement A suggestion for improvement. [Feature] Navigation Menus Any issue relating to Navigation Menus labels Nov 1, 2023
@draganescu
Copy link
Contributor Author

  • Should we generalize this so that it works for certain related post types in core: template parts using a navigation, templates using a template part, templates using a pattern, template parts using a pattern?
  • The field holds any "related" item, but maybe we should filter by current theme in the response? Currently this is handled by getEntityRecords.

This wp_id vs id in templates and template parts creates a bit of confusion, because it's the only record not addresable by record id. In this case for some reason I could not do an includes query using getEntityRecords. because the id is the theme//slug format not the record id.

Copy link

github-actions bot commented Nov 1, 2023

Size Change: +2.04 kB (0%)

Total Size: 1.7 MB

Filename Size Change
build/block-editor/content-rtl.css 4.4 kB +84 B (+2%)
build/block-editor/content.css 4.39 kB +84 B (+2%)
build/block-editor/index.min.js 248 kB +44 B (0%)
build/block-editor/style-rtl.css 15.4 kB +20 B (0%)
build/block-editor/style.css 15.4 kB +18 B (0%)
build/block-library/index.min.js 215 kB +86 B (0%)
build/components/index.min.js 235 kB +36 B (0%)
build/compose/index.min.js 12.6 kB -135 B (-1%)
build/data/index.min.js 8.96 kB -1 B (0%)
build/edit-post/index.min.js 24.9 kB +54 B (0%)
build/edit-site/index.min.js 196 kB +859 B (0%)
build/edit-site/style-rtl.css 15.2 kB +101 B (+1%)
build/edit-site/style.css 15.2 kB +106 B (+1%)
build/editor/index.min.js 61.7 kB +9 B (0%)
build/interactivity/index.min.js 13 kB +373 B (+3%)
build/preferences/index.min.js 2.82 kB +299 B (+12%) ⚠️
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 964 B
build/annotations/index.min.js 2.71 kB
build/api-fetch/index.min.js 2.33 kB
build/autop/index.min.js 2.11 kB
build/blob/index.min.js 590 B
build/block-directory/index.min.js 7.25 kB
build/block-directory/style-rtl.css 1.04 kB
build/block-directory/style.css 1.04 kB
build/block-editor/default-editor-styles-rtl.css 403 B
build/block-editor/default-editor-styles.css 403 B
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/audio/theme-rtl.css 138 B
build/block-library/blocks/audio/theme.css 138 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/block/editor-rtl.css 305 B
build/block-library/blocks/block/editor.css 305 B
build/block-library/blocks/button/editor-rtl.css 419 B
build/block-library/blocks/button/editor.css 417 B
build/block-library/blocks/button/style-rtl.css 632 B
build/block-library/blocks/button/style.css 631 B
build/block-library/blocks/buttons/editor-rtl.css 337 B
build/block-library/blocks/buttons/editor.css 337 B
build/block-library/blocks/buttons/style-rtl.css 332 B
build/block-library/blocks/buttons/style.css 332 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 B
build/block-library/blocks/categories/editor-rtl.css 113 B
build/block-library/blocks/categories/editor.css 112 B
build/block-library/blocks/categories/style-rtl.css 124 B
build/block-library/blocks/categories/style.css 124 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 421 B
build/block-library/blocks/columns/style.css 421 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 199 B
build/block-library/blocks/comment-template/style.css 198 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 840 B
build/block-library/blocks/comments/editor.css 839 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 636 B
build/block-library/blocks/cover/editor-rtl.css 647 B
build/block-library/blocks/cover/editor.css 650 B
build/block-library/blocks/cover/style-rtl.css 1.7 kB
build/block-library/blocks/cover/style.css 1.69 kB
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 98 B
build/block-library/blocks/details/style.css 98 B
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/embed/theme-rtl.css 138 B
build/block-library/blocks/embed/theme.css 138 B
build/block-library/blocks/file/editor-rtl.css 316 B
build/block-library/blocks/file/editor.css 316 B
build/block-library/blocks/file/style-rtl.css 280 B
build/block-library/blocks/file/style.css 281 B
build/block-library/blocks/file/view.min.js 322 B
build/block-library/blocks/footnotes/style-rtl.css 201 B
build/block-library/blocks/footnotes/style.css 199 B
build/block-library/blocks/form-input/editor-rtl.css 229 B
build/block-library/blocks/form-input/editor.css 228 B
build/block-library/blocks/form-input/style-rtl.css 343 B
build/block-library/blocks/form-input/style.css 343 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 343 B
build/block-library/blocks/form-submission-notification/editor.css 342 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/form/view.min.js 452 B
build/block-library/blocks/freeform/editor-rtl.css 2.61 kB
build/block-library/blocks/freeform/editor.css 2.61 kB
build/block-library/blocks/gallery/editor-rtl.css 957 B
build/block-library/blocks/gallery/editor.css 962 B
build/block-library/blocks/gallery/style-rtl.css 1.75 kB
build/block-library/blocks/gallery/style.css 1.75 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 654 B
build/block-library/blocks/group/editor.css 654 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 189 B
build/block-library/blocks/heading/style.css 189 B
build/block-library/blocks/html/editor-rtl.css 340 B
build/block-library/blocks/html/editor.css 341 B
build/block-library/blocks/image/editor-rtl.css 834 B
build/block-library/blocks/image/editor.css 833 B
build/block-library/blocks/image/style-rtl.css 1.61 kB
build/block-library/blocks/image/style.css 1.6 kB
build/block-library/blocks/image/theme-rtl.css 137 B
build/block-library/blocks/image/theme.css 137 B
build/block-library/blocks/image/view.min.js 2.02 kB
build/block-library/blocks/latest-comments/style-rtl.css 357 B
build/block-library/blocks/latest-comments/style.css 357 B
build/block-library/blocks/latest-posts/editor-rtl.css 213 B
build/block-library/blocks/latest-posts/editor.css 212 B
build/block-library/blocks/latest-posts/style-rtl.css 478 B
build/block-library/blocks/latest-posts/style.css 478 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 505 B
build/block-library/blocks/media-text/style.css 503 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 671 B
build/block-library/blocks/navigation-link/editor.css 672 B
build/block-library/blocks/navigation-link/style-rtl.css 103 B
build/block-library/blocks/navigation-link/style.css 103 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation/editor-rtl.css 2.26 kB
build/block-library/blocks/navigation/editor.css 2.26 kB
build/block-library/blocks/navigation/style-rtl.css 2.25 kB
build/block-library/blocks/navigation/style.css 2.23 kB
build/block-library/blocks/navigation/view.min.js 1.1 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 401 B
build/block-library/blocks/page-list/editor.css 401 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 235 B
build/block-library/blocks/paragraph/editor.css 235 B
build/block-library/blocks/paragraph/style-rtl.css 335 B
build/block-library/blocks/paragraph/style.css 335 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 508 B
build/block-library/blocks/post-comments-form/style.css 508 B
build/block-library/blocks/post-date/style-rtl.css 61 B
build/block-library/blocks/post-date/style.css 61 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 141 B
build/block-library/blocks/post-excerpt/style.css 141 B
build/block-library/blocks/post-featured-image/editor-rtl.css 666 B
build/block-library/blocks/post-featured-image/editor.css 662 B
build/block-library/blocks/post-featured-image/style-rtl.css 345 B
build/block-library/blocks/post-featured-image/style.css 345 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 409 B
build/block-library/blocks/post-template/style.css 408 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-time-to-read/style-rtl.css 69 B
build/block-library/blocks/post-time-to-read/style.css 69 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 135 B
build/block-library/blocks/pullquote/editor.css 135 B
build/block-library/blocks/pullquote/style-rtl.css 354 B
build/block-library/blocks/pullquote/style.css 354 B
build/block-library/blocks/pullquote/theme-rtl.css 168 B
build/block-library/blocks/pullquote/theme.css 168 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 288 B
build/block-library/blocks/query-pagination/style.css 284 B
build/block-library/blocks/query-title/style-rtl.css 63 B
build/block-library/blocks/query-title/style.css 63 B
build/block-library/blocks/query/editor-rtl.css 486 B
build/block-library/blocks/query/editor.css 486 B
build/block-library/blocks/query/style-rtl.css 312 B
build/block-library/blocks/query/style.css 308 B
build/block-library/blocks/query/view.min.js 647 B
build/block-library/blocks/quote/style-rtl.css 237 B
build/block-library/blocks/quote/style.css 237 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 140 B
build/block-library/blocks/read-more/style.css 140 B
build/block-library/blocks/rss/editor-rtl.css 149 B
build/block-library/blocks/rss/editor.css 149 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 184 B
build/block-library/blocks/search/editor.css 184 B
build/block-library/blocks/search/style-rtl.css 602 B
build/block-library/blocks/search/style.css 602 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/search/view.min.js 475 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 234 B
build/block-library/blocks/separator/style.css 234 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 329 B
build/block-library/blocks/shortcode/editor.css 329 B
build/block-library/blocks/site-logo/editor-rtl.css 760 B
build/block-library/blocks/site-logo/editor.css 760 B
build/block-library/blocks/site-logo/style-rtl.css 204 B
build/block-library/blocks/site-logo/style.css 204 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 116 B
build/block-library/blocks/site-title/editor.css 116 B
build/block-library/blocks/site-title/style-rtl.css 57 B
build/block-library/blocks/site-title/style.css 57 B
build/block-library/blocks/social-link/editor-rtl.css 184 B
build/block-library/blocks/social-link/editor.css 184 B
build/block-library/blocks/social-links/editor-rtl.css 682 B
build/block-library/blocks/social-links/editor.css 681 B
build/block-library/blocks/social-links/style-rtl.css 1.49 kB
build/block-library/blocks/social-links/style.css 1.49 kB
build/block-library/blocks/spacer/editor-rtl.css 359 B
build/block-library/blocks/spacer/editor.css 359 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 395 B
build/block-library/blocks/table/editor.css 395 B
build/block-library/blocks/table/style-rtl.css 646 B
build/block-library/blocks/table/style.css 645 B
build/block-library/blocks/table/theme-rtl.css 157 B
build/block-library/blocks/table/theme.css 157 B
build/block-library/blocks/tag-cloud/style-rtl.css 251 B
build/block-library/blocks/tag-cloud/style.css 253 B
build/block-library/blocks/template-part/editor-rtl.css 403 B
build/block-library/blocks/template-part/editor.css 403 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/term-description/style-rtl.css 111 B
build/block-library/blocks/term-description/style.css 111 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 99 B
build/block-library/blocks/verse/style.css 99 B
build/block-library/blocks/video/editor-rtl.css 552 B
build/block-library/blocks/video/editor.css 555 B
build/block-library/blocks/video/style-rtl.css 191 B
build/block-library/blocks/video/style.css 191 B
build/block-library/blocks/video/theme-rtl.css 139 B
build/block-library/blocks/video/theme.css 139 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.11 kB
build/block-library/common.css 1.11 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/editor-rtl.css 12.3 kB
build/block-library/editor.css 12.3 kB
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-library/style-rtl.css 14.7 kB
build/block-library/style.css 14.7 kB
build/block-library/theme-rtl.css 700 B
build/block-library/theme.css 705 B
build/block-serialization-default-parser/index.min.js 1.13 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/blocks/index.min.js 51.6 kB
build/commands/index.min.js 15.5 kB
build/commands/style-rtl.css 947 B
build/commands/style.css 942 B
build/components/style-rtl.css 12.1 kB
build/components/style.css 12.1 kB
build/core-commands/index.min.js 2.73 kB
build/core-data/index.min.js 72.7 kB
build/customize-widgets/index.min.js 12.1 kB
build/customize-widgets/style-rtl.css 1.36 kB
build/customize-widgets/style.css 1.36 kB
build/data-controls/index.min.js 651 B
build/date/index.min.js 17.9 kB
build/deprecated/index.min.js 462 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.69 kB
build/edit-post/classic-rtl.css 571 B
build/edit-post/classic.css 571 B
build/edit-post/style-rtl.css 5.68 kB
build/edit-post/style.css 5.68 kB
build/edit-widgets/index.min.js 17.4 kB
build/edit-widgets/style-rtl.css 4.44 kB
build/edit-widgets/style.css 4.43 kB
build/editor/style-rtl.css 5.48 kB
build/editor/style.css 5.48 kB
build/element/index.min.js 4.87 kB
build/escape-html/index.min.js 548 B
build/format-library/index.min.js 7.98 kB
build/format-library/style-rtl.css 500 B
build/format-library/style.css 500 B
build/hooks/index.min.js 1.57 kB
build/html-entities/index.min.js 454 B
build/i18n/index.min.js 3.61 kB
build/interactivity/file.min.js 442 B
build/interactivity/image.min.js 2.15 kB
build/interactivity/navigation.min.js 1.23 kB
build/interactivity/query.min.js 791 B
build/interactivity/search.min.js 610 B
build/is-shallow-equal/index.min.js 535 B
build/keyboard-shortcuts/index.min.js 1.76 kB
build/keycodes/index.min.js 1.49 kB
build/list-reusable-blocks/index.min.js 2.11 kB
build/list-reusable-blocks/style-rtl.css 865 B
build/list-reusable-blocks/style.css 865 B
build/media-utils/index.min.js 2.92 kB
build/modules/importmap-polyfill.min.js 12.2 kB
build/notices/index.min.js 964 B
build/nux/index.min.js 2.01 kB
build/nux/style-rtl.css 775 B
build/nux/style.css 771 B
build/patterns/index.min.js 5.43 kB
build/patterns/style-rtl.css 564 B
build/patterns/style.css 564 B
build/plugins/index.min.js 1.81 kB
build/preferences-persistence/index.min.js 2.08 kB
build/preferences/style-rtl.css 725 B
build/preferences/style.css 728 B
build/primitives/index.min.js 994 B
build/priority-queue/index.min.js 1.52 kB
build/private-apis/index.min.js 1.02 kB
build/react-i18n/index.min.js 631 B
build/react-refresh-entry/index.min.js 9.46 kB
build/react-refresh-runtime/index.min.js 6.78 kB
build/redux-routine/index.min.js 2.71 kB
build/reusable-blocks/index.min.js 2.74 kB
build/reusable-blocks/style-rtl.css 265 B
build/reusable-blocks/style.css 265 B
build/rich-text/index.min.js 10.4 kB
build/router/index.min.js 1.79 kB
build/server-side-render/index.min.js 1.96 kB
build/shortcode/index.min.js 1.4 kB
build/style-engine/index.min.js 2.06 kB
build/token-list/index.min.js 587 B
build/url/index.min.js 3.83 kB
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react-dom.min.js 41.8 kB
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 967 B
build/warning/index.min.js 259 B
build/widgets/index.min.js 7.22 kB
build/widgets/style-rtl.css 1.18 kB
build/widgets/style.css 1.18 kB
build/wordcount/index.min.js 1.03 kB

compressed-size-action

@draganescu draganescu marked this pull request as ready for review November 1, 2023 22:04
@draganescu
Copy link
Contributor Author

I am thinking a better approach here is to extend the search endpoint to support a has_blocks param for post search with optional filtering by attribute name/value.

This has_blocks param should not augment WP_Query but instead be treated separately as:

  • get all posts (of type) limit to a decent default batch
  • loop through the batch
  • parse blocks
  • find blocks of name (and attributes of value)
  • return found posts

This is a very expensive operation, the default limits should be low. On the other hand it's perfectly cache-able. This would allow the generalisation of the feature here to apply to multiple scenarios:

  • find all pages that contain the slider block with red background
  • find all products which contain a discount block with value set to 10
  • find all templates with a query block that has page length 2 🤷🏻

@getdave
Copy link
Contributor

getdave commented Nov 7, 2023

Great exploration. Perhaps it would be useful to bring this up in REST API channels and discuss options with them if you haven't already?

@draganescu
Copy link
Contributor Author

I took a week pause from this work due to other work, will resume now.

@draganescu draganescu self-assigned this Nov 23, 2023
@draganescu
Copy link
Contributor Author

I've tested the idea of a controller that searches all posts based on

  • post type
  • block name
  • block attribute name
  • block attribute value

The main blocker is that it's hard to optimize this sort of search. That controller pages through the DB until it has found enough matching posts. If we want all by default it's not feasible.

I think the other option - also in this PR - with just registering extra rest response fields that expose these relationships between posts based on blocks (template_part using wp_navigation with ref of certain value) is best.

I will continue on this path. I need to see what place is best for registering / adding the extra field.

Copy link
Member

@dmsnell dmsnell left a comment

Choose a reason for hiding this comment

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

There's quite a timebomb locked inside of this logic. Someone is going to come along and want to add a cache as well. It would be good to provide some guidance on how that could go well or go wrong.

I've suggested a "bandaid" which addresses the inner loop without addressing the broader issue, of needing to scan through a site's posts.

At a minimum it seems like there should be some hard constraints built into this: a time limit imposed when searching, possibly the max number of posts to scan.

If we're relying on this in the editor I could imagine it being a really hard pause when loading for a site with thousands or tens of thousands of posts. We have no guarantee that posts contained the searched-for block exist in the "front" of the query either; it could be 3000 posts and then the first one with our block.

Mitigating this might imply something even more inherent, such as ensuring that the editor expects a progressively loading and asynchronous response. That is, setup an API call and show a spinner and start showing matching posts as they come in, but have the API call poll until it's done. This might involve creating a cursor to associate the search.

@dmsnell
Copy link
Member

dmsnell commented Nov 28, 2023

As an idea of an interface that recognizes that this could take tens of seconds or minutes or longer to response, we could create an actual search resource which can be later polled for streaming results.

> POST /wp/v2/block-search?block_name=core/cover
< 200 {"results": "/wp/v2/block-search/akdlk35d6sd5"}

first matching posts…

> GET /wp/v2/block-search/akdlk35d6sd5
< 200 OK {"posts": […], "next-results": "/wp/v2/block-search/akdlk35d6sd5"}

still thinking about it, scanning through posts but not finding any matches…

> GET /wp/v2/block-search/akdlk35d6sd5
< 200 OK {"posts": [], "next-results": "/wp/v2/block-search/akdlk35d6sd5"}

all posts have been scanned and there is nothing left to scan…

> GET /wp/v2/block-search/akdlk35d6sd5
< 200 OK {"posts": […]}

This gives the client the information it needs to start showing a UI, to grab the next batch of matched posts, to know when to continue polling, and when to stop. There's a problem here in that we don't have guarantees about how long it will take to find, say, the next five posts, so an API response might come at some time-based interval (say, give up and return after 3 seconds) but which should still indicate that the client needs to continue to poll.

Obviously there are concurrency issues with posts being updated in the background, plus the fact that we want to avoid making this query multiple times from the client, but we also need to recognize that with time, the same query might produce different inherent results.

@draganescu
Copy link
Contributor Author

I know fully well the time bomb that is why I am moving slowly here :). Thanks for all the super valuable consideration.

@draganescu
Copy link
Contributor Author

@dmsnell I wonder if the original approach of the PR which aims only to show which template part uses a navigation block, and does that only to scan through template parts, and adds a rest field to the wp_navigation resource only is a way forward to fix the problem at hand.

Then I can start a PR for a more generic locator resource that implements the optimisations and documentation you mentioned above.

@dmsnell
Copy link
Member

dmsnell commented Nov 28, 2023

PR which aims only to show which template part uses a navigation block, and does that only to scan through template parts

if it didn't involve creating a new public resource/endpoint/value I would think that's a fair proposal, but there's a risk here in that this only really kicks the can down the road, proverbially. a site with hundreds of template parts will exhibit the same problem and people will say "Gutenberg is not suitable for large agency work."

I recently explored using chunked responses to stream the reply of a long-running API call, but I'm pretty sure that's unworkable with WordPress' "REST" facilities, and it would probably end up timing out at the kinds of delays I would expect this endpoint to return.

creating the generic resource locator may not be as hard as it seems. we might be able to build it with a transient and it only needs to store the offset and query parameters to generate the next query batch/page. that transient can disappear after five minutes and everything will be fine; clients should expect that these cursors might fail or disappear.

@paaljoachim
Copy link
Contributor

paaljoachim commented Dec 6, 2023

Thank you for working on this @draganescu Andrei!

It is very helpful to be able to click into a Navigation to get information on where it is being used.

Next up.
It would be helpful to perhaps have an icon showing header template part beside the Navigation name in the main Navigation list. So one can at quick glance see where the various menus are being used. Then being able to switch the location a menu uses right there in the sidebar without having to go into canvas view.

@draganescu
Copy link
Contributor Author

@paaljoachim that's a good suggestion, but not for this PR, it'd be great to make an issue with a mockup to illustrate your idea which I like quite a lot.

@dmsnell

if it didn't involve creating a new public resource/endpoint/value I would think that's a fair proposal, but there's a risk here in that this only really kicks the can down the road, proverbially. a site with hundreds of template parts will exhibit the same problem and people will say "Gutenberg is not suitable for large agency work."

I think register a field, in the site editor or by the navigation block itself, it does not expose anything other way to access this underperformat-by-design feature. I am not too afraid of hundreds of template parts. I could even bail at 50, sorted desc by most recent (b/c you want to see this info in current parts) and filter this number so people who trust their servers can bump it.

I will proceed to remove the public resource and register the rest field in the response for wp_template_part as it originally proposed (see this commit range)

@paaljoachim
Copy link
Contributor

An issue for brainstorming how to switch menu locations in the Navigation sidebar:
#56858

@dmsnell
Copy link
Member

dmsnell commented Dec 7, 2023

I could even bail at 50, sorted desc by most recent (b/c you want to see this info in current parts) and filter this number so people who trust their servers can bump it.

This might mean settling for responses with zero results, because we can't guarantee that we will find fifty without scanning through hundreds or thousands of posts before we get the first fifty containing the block.

@draganescu
Copy link
Contributor Author

This might mean settling for responses with zero results, because we can't guarantee that we will find fifty without scanning through hundreds or thousands of posts before we get the first fifty containing the block.

No, I meant scan only 50. And yes, emtpy results for this particular problem it's fine.

@draganescu draganescu force-pushed the try/navigation-relation-meta branch 2 times, most recently from 8972455 to d4482f3 Compare January 15, 2024 15:05
Comment on lines +134 to +139
$wp_template_part_posts = get_posts(
array(
'post_type' => 'wp_template_part',
'posts_per_page' => -1,
)
);
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'll want to use WP_Query here with the various parameters that optimise the query performance such as no_found_rows...etc.

lib/init.php Outdated

if ( ! function_exists( 'html_contains_block' ) ) {
/**
* Recursively find a block by attribute.
Copy link
Member

Choose a reason for hiding this comment

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

Algorithmically this is no longer recursive, nor is it conceptually. I'm not sure this is helpful to mention "recursive" because it might lead someone astray trying to figure out how it's recursive.

We might say something more to the point about the goal:

Returns whether the given HTML contains a block of the given type
and, if provided, a given attribute and attribute value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah copy pasta sorry!

lib/init.php Outdated Show resolved Hide resolved
lib/init.php Show resolved Hide resolved
lib/init.php Outdated Show resolved Hide resolved
lib/init.php Outdated Show resolved Hide resolved
lib/init.php Outdated Show resolved Hide resolved
lib/init.php Outdated
// Don't parse JSON if it's not possible for the attribute to exist.
if ( ! str_contains( $matches['attrs'][0], "\"{$attribute_name}\":" ) ) {
continue;
}
Copy link
Member

Choose a reason for hiding this comment

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

interesting note, but I believe this check can fail if the key is using non-latin1 characters. I wonder if it would actually be better to omit this optimization (which again, sorry for recommending it and then recommending its removal) for now, or note the discrepancy as a clue for someone in the future. we have to avoid situations like {"\u0061ge": 42} failing to match for age

lib/init.php Show resolved Hide resolved
$wp_template_part_posts = get_posts(
array(
'post_type' => 'wp_template_part',
'posts_per_page' => -1,
Copy link
Member

Choose a reason for hiding this comment

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

it looks like we abandoned all limits here, but this is being added to the query for template parts. there could still be a kind of time-bomb in here because some sites will have hundreds if not thousands of template parts, and we're not able to limit our search. this means that for every request to fetch template parts, we will be processing every template part in the database.

it'd be great if we could impose an arbitrary limit or only add this if a specific query arg requests it so that we don't accidentally make the trivial case obstructively slow, when someone doesn't need to know what template parts use the given menu.

if we limit to an arbitrary amount it would seem like we could add some kind of next-page link or cursor id to continue the search on-demand.

Copy link
Contributor

Choose a reason for hiding this comment

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

@dmsnell I thought this was only called to get the field value when the REST query is for wp_navigation posts? The get_callback invokes this function to get the field value for the template_parts_that_use_menu field.

How is it being added to the query for template parts? Maybe I missed something?

If I'm correct, then we could still further optimise this approach by only including the field if certain query params are provided. We don't need it for standard requests. I don't know the best REST etiquette for that but some REST maintainers might be able to assist.

Copy link
Member

Choose a reason for hiding this comment

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

when the REST query is for wp_navigation posts?

yeah that was my mistake. still, my point is that we're time-bombing the API and I can imagine a handful of normal cases where all we want is the list of wp_navigation posts. making the field opt-in would remove that burden and only charge the cost of computation when it's wanted.

this could go really bad on real sites with lots of template parts. say we have a site with a thousand template parts and one navigation menu. even with that single nav menu, we still have to scan all thousand template part posts every time we request the list of nav menus.

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's set a hard limit on the number of items returned in the query. However we want to avoid situations where there are a lot of template parts which causes us to miss the key template parts for the site.

To avoid this we could also consider optimising for common template parts such as header and footer to ensure these are always checked first. It's likely to serve the 80% use case.

Copy link
Member

Choose a reason for hiding this comment

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

we want to avoid situations where there are a lot of template parts which causes us to miss the key template parts for the site.

doing what we're trying to do here I think is going to require a search index, and one we'll likely need to build and maintain ourselves. I just don't see it being practical to scan the database every time we want to grab wp_navigation items.

that can be done, but it's probably easier to do on its own.

serve the 80% use case

if we have and can get a header and footer quickly then that would seem like a good idea

Copy link
Contributor

Choose a reason for hiding this comment

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

to scan the database every time we want to grab wp_navigation items.

I agree which is why I think this comes back around to limiting the scope of this change to it's own endpoint for the block editor only.

This way we do not register this field on the Posts Controller responses at all.

We can easily introduce a new private Core Data selector which queries this endpoint only when necessary.

This will avoid hitting the DB each time there is a query for wp_navigation to Posts Controller.

If we want to apply further safety limits we can do that as well.

lib/init.php Outdated Show resolved Hide resolved
lib/init.php Outdated Show resolved Hide resolved
lib/init.php Outdated Show resolved Hide resolved
$wp_template_part_posts = get_posts(
array(
'post_type' => 'wp_template_part',
'posts_per_page' => -1,
Copy link
Contributor

Choose a reason for hiding this comment

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

@dmsnell I thought this was only called to get the field value when the REST query is for wp_navigation posts? The get_callback invokes this function to get the field value for the template_parts_that_use_menu field.

How is it being added to the query for template parts? Maybe I missed something?

If I'm correct, then we could still further optimise this approach by only including the field if certain query params are provided. We don't need it for standard requests. I don't know the best REST etiquette for that but some REST maintainers might be able to assist.

lib/init.php Outdated Show resolved Hide resolved
lib/init.php Outdated Show resolved Hide resolved
*
* @return bool True if block is found, false otherwise
*/
function html_contains_block( $html, $block_name, $attribute_name = null, $attribute_value = null ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I forgot to include in previous review but I think it would be wise to have some tests for this function. You could use a PHPUnit data provider to pass in various combinations of values to ensure you've covered a range of scenarios.

One such example would be what @dmsnell said about Latin characters.

@draganescu
Copy link
Contributor Author

Excellent, I am happy this is on track now. I will:

  • address the feedback about comments and optimisations
  • try to move this in private methods (if possile via extending the posts controller)
  • add some tests

@getdave
Copy link
Contributor

getdave commented Jan 17, 2024

...if possile via extending the posts controller

I have previously received feedback from REST maintainers that extending existing REST endpoints in arbritary ways for specific posts is not considered best practise. This is because (as you know) Gutenberg is not the only consumer of the API.

You may find that a dedicated block editor specific endpoint (such as we implemented for Navigation Fallbacks) would be a better approach. Certainly this is what I was previously advised.

@draganescu
Copy link
Contributor Author

Thanks for the useful info @getdave - I'll need to see how that applies to this particular situation. Either way I have no attachment to how more I have it to what which is to hide the html seek function for a while until we figure out the best tweaks to it.

* "my_plugin/my_block".
* @param string $attribute_name If provided, the block must also
* contain this attribute.
* @param string $attribute_value If provided, the given attribute's
Copy link
Member

Choose a reason for hiding this comment

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

nitpick: we'll want to add ?string (I'm pretty sure vs. string|null) before merging

$pattern = sprintf(
'~<!--\s+?wp:%s\s+(?P<attrs>{(?:(?:[^}]+|}+(?=})|(?!}\s+/?-->).)*+)?}\s+)?/?-->~s',
preg_quote( str_replace( 'core/', '', $block_name ), '~' )
);
Copy link
Member

Choose a reason for hiding this comment

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

you probably already know this, but we need to expand this a bit because then we'd overlook posts containing core/template, for example. although the editor prunes the core/ namespace, it's perfectly valid to have it written in the HTML.

given the fact that we're only looking for a single block type I recommend we hard-code the regex pattern to match the sought block name. we can do that by breaking apart the block name into its parts, different than the code I shared above about joining them.

// check my string-index math
$solidus_at       = strpos( $block_name, '/' );
$sought_namespace = false === $solidus_at ? 'core' : substr( $block_name, 0, $solidus_at );
$sought_name      = false === $solidus_at ? $block_name : substr( $block_name, $solidus_at + 1 );

$pattern = sprintf(
	'~<!--\s+?wp:((?:%s/)?%s\s+...~',
	preg_quote( $sought_namespace, '~' ),
	preg_quote( $sought_name, '~' )
);

@draganescu
Copy link
Contributor Author

I am going to close this for now and come back to it with a better plan or this plan but a fresh implementation.

@draganescu draganescu closed this Mar 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Navigation Menus Any issue relating to Navigation Menus [Type] Enhancement A suggestion for improvement.
Projects
Development

Successfully merging this pull request may close these issues.

4 participants