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

Edit Site: Remove templateIds prop from NavigateToLink #21877

Merged
merged 5 commits into from
May 13, 2020

Conversation

ockham
Copy link
Contributor

@ockham ockham commented Apr 24, 2020

Description

Instead of iterating over templateIds, fetching each corresponding template from the REST API, and then locally filtering for the matching template slug, use one network fetch with the slug passed as a query param (You can verify that that works by running wp.data.select('core').getEntityRecords('postType', 'wp_template', { slug: 'front-page' } ) in the browser console -- twice, to make it resolve properly.)

This is preparatory work for another PR that will decouple edit-site even further from the settings variable that is at the moment directly passed from PHP, and will use the REST API instead.

Update 2020-05-13: This also fixes a bug in #21981, where previously, a matching template (specified via { slug: 'front-page'; resolved: true }) would return an empty array. To verify, try the following (similar to #21981, but including the cases I failed to test for):

We'll compare the results the wp_template collections REST API endpoint gives to $settings['templateIds']. To that end, apply the following patch and re-build the app (npm run build):

diff --git a/packages/edit-site/src/index.js b/packages/edit-site/src/index.js
index e6dec20771..ea72bee4c9 100644
--- a/packages/edit-site/src/index.js
+++ b/packages/edit-site/src/index.js
@@ -26,6 +26,7 @@ export function initialize( id, settings ) {
        if ( process.env.GUTENBERG_PHASE === 2 ) {
                __experimentalRegisterExperimentalCoreBlocks( settings );
        }
+       console.log( 'settings', settings );
        render( <Editor settings={ settings } />, document.getElementById( id ) );
 }

Next, in wp-admin, navigate to the Appearance > Templates section, and create a few dummy templates whose names are not actually part of the template hierarchy (e.g. some-template etc).

Now go to Full-Site Editing and open your browser console. You should see the output of the settings variable there. Compare the templateIds property to the output of the following commands you run in the console (twice each!). Icons ✔️ and ❌ indicate whether the output is expected to match settings.templateIds, or not.

  • ✔️ (new) wp.data.select('core').getEntityRecords('postType', 'wp_template', { slug: 'front-page' } ) should return the wp_template CPT whose slug is front-page.
  • ✔️ (new) wp.data.select('core').getEntityRecords('postType', 'wp_template', { slug: 'front-page', resolved: true } ) should also return the wp_template CPT whose slug is front-page, as it is part of the template hierarchy.
  • wp.data.select('core').getEntityRecords('postType', 'wp_template' ) should return the list of all wp_template CPTs, including those that are not part of the template hierarchy.
  • ✔️ wp.data.select('core').getEntityRecords('postType', 'wp_template', { resolved: true } ) should return the list of templates that match the template hierarchy.
  • wp.data.select('core').getEntityRecords('postType', 'wp_template', { slug: 'some-template' } ) should return the wp_template CPT whose slug is some-template.
  • ✔️ wp.data.select('core').getEntityRecords('postType', 'wp_template', { slug: 'some-template', resolved: true } ) should return an empty array, as some-template is not part of the template hierarchy.

This highlights that we need unit tests for these functions, which we'll hopefully be able to run more easily once #20090 is in 🙂

How has this been tested?

In case you're not familiar with this feature: This is present when editing a template part that contains a link to a URL that's part of the current website. Specifically, it's a button in the link editing popover that takes you to the template that corresponds to that URL. (If that's still confusiong, the instructions and screenshots below should make this clearer.)

  • Activate the site editor experiment (and demo templates).
  • Navigate to the site editor.
  • Add a new single template for the current theme. You can add a bit of content there, or just leave it empty.
  • Go back to the front-page theme.
  • In the header template part, add a link to /, and one to /?p=1.
  • In the template switcher, open the header template part for direct editing.
  • Highlight each of the links, and click the button in the top right corner.
  • Verify that for the / link, you're taken back to the front-page link, whereas for the /?p=1 link, you're taken to the single template.

Screenshots

navigate-to-link

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 Apr 24, 2020

Size Change: +3.28 kB (0%)

Total Size: 831 kB

Filename Size Change
build/annotations/index.js 3.62 kB -3 B (0%)
build/block-directory/index.js 6.59 kB -2 B (0%)
build/block-editor/index.js 104 kB +231 B (0%)
build/block-editor/style-rtl.css 10.8 kB +236 B (2%)
build/block-editor/style.css 10.8 kB +238 B (2%)
build/block-library/editor-rtl.css 7.25 kB +134 B (1%)
build/block-library/editor.css 7.25 kB +134 B (1%)
build/block-library/index.js 116 kB +499 B (0%)
build/block-library/style-rtl.css 7.48 kB +102 B (1%)
build/block-library/style.css 7.49 kB +101 B (1%)
build/blocks/index.js 48.1 kB +15 B (0%)
build/components/index.js 182 kB +1.36 kB (0%)
build/components/style-rtl.css 17.1 kB +95 B (0%)
build/components/style.css 17 kB +99 B (0%)
build/compose/index.js 6.68 kB +16 B (0%)
build/core-data/index.js 11.4 kB -1 B
build/data-controls/index.js 1.29 kB +2 B (0%)
build/data/index.js 8.43 kB +5 B (0%)
build/date/index.js 5.47 kB +1 B
build/edit-post/index.js 28 kB +28 B (0%)
build/edit-site/index.js 12.1 kB -19 B (0%)
build/edit-widgets/index.js 8.37 kB -3 B (0%)
build/editor/index.js 44.3 kB +6 B (0%)
build/element/index.js 4.65 kB +2 B (0%)
build/escape-html/index.js 733 B -1 B
build/format-library/index.js 7.63 kB +2 B (0%)
build/is-shallow-equal/index.js 712 B +2 B (0%)
build/nux/index.js 3.4 kB +2 B (0%)
build/plugins/index.js 2.56 kB +2 B (0%)
build/redux-routine/index.js 2.85 kB +1 B
build/rich-text/index.js 14.8 kB -3 B (0%)
build/token-list/index.js 1.28 kB +1 B
build/wordcount/index.js 1.18 kB +1 B
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 1.02 kB 0 B
build/api-fetch/index.js 4.08 kB 0 B
build/autop/index.js 2.82 kB 0 B
build/blob/index.js 620 B 0 B
build/block-directory/style-rtl.css 764 B 0 B
build/block-directory/style.css 764 B 0 B
build/block-library/theme-rtl.css 683 B 0 B
build/block-library/theme.css 685 B 0 B
build/block-serialization-default-parser/index.js 1.88 kB 0 B
build/block-serialization-spec-parser/index.js 3.1 kB 0 B
build/deprecated/index.js 772 B 0 B
build/dom-ready/index.js 568 B 0 B
build/dom/index.js 3.1 kB 0 B
build/edit-navigation/index.js 5.59 kB 0 B
build/edit-navigation/style-rtl.css 618 B 0 B
build/edit-navigation/style.css 617 B 0 B
build/edit-post/style-rtl.css 12.2 kB 0 B
build/edit-post/style.css 12.2 kB 0 B
build/edit-site/style-rtl.css 5.22 kB 0 B
build/edit-site/style.css 5.22 kB 0 B
build/edit-widgets/style-rtl.css 4.69 kB 0 B
build/edit-widgets/style.css 4.69 kB 0 B
build/editor/editor-styles-rtl.css 425 B 0 B
build/editor/editor-styles.css 428 B 0 B
build/editor/style-rtl.css 5.07 kB 0 B
build/editor/style.css 5.08 kB 0 B
build/format-library/style-rtl.css 502 B 0 B
build/format-library/style.css 502 B 0 B
build/hooks/index.js 2.13 kB 0 B
build/html-entities/index.js 622 B 0 B
build/i18n/index.js 3.56 kB 0 B
build/keyboard-shortcuts/index.js 2.51 kB 0 B
build/keycodes/index.js 1.94 kB 0 B
build/list-reusable-blocks/index.js 3.13 kB 0 B
build/list-reusable-blocks/style-rtl.css 226 B 0 B
build/list-reusable-blocks/style.css 226 B 0 B
build/media-utils/index.js 5.29 kB 0 B
build/notices/index.js 1.79 kB 0 B
build/nux/style-rtl.css 616 B 0 B
build/nux/style.css 613 B 0 B
build/primitives/index.js 1.5 kB 0 B
build/priority-queue/index.js 789 B 0 B
build/server-side-render/index.js 2.68 kB 0 B
build/shortcode/index.js 1.7 kB 0 B
build/url/index.js 4.02 kB 0 B
build/viewport/index.js 1.84 kB 0 B
build/warning/index.js 1.14 kB 0 B

compressed-size-action

Comment on lines 31 to 33
const { getEntityRecord } = select( 'core' );
newTemplateId = templateIds
.map( ( id ) =>
getEntityRecord( 'postType', 'wp_template', id )
)
.find(
( template ) => template.slug === data.post_name
).id;
const { getEntityRecords } = select( 'core' );
newTemplateId = getEntityRecords(
'postType',
'wp_template',
{
slug: data.post_name,
}
)[ 0 ].id;
Copy link
Contributor

Choose a reason for hiding this comment

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

The slug approach does not guarantee you'll get the same post ID that is loaded in the editor. It doesn't account for multiple auto-drafts, a published template, etc.

Was the previous approach making REST requests? All of those template IDs should be preloaded.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The slug approach does not guarantee you'll get the same post ID that is loaded in the editor. It doesn't account for multiple auto-drafts, a published template, etc.

Oh, okay. I think that's something we should seek to resolve though -- possibly through some modifications to the endpoint, in order to reflect the template loading mechanism.

Aside, is the 'proper' resolution documented anywhere? I.e. when to use the published template, when to fall back to an auto-draft, when to generate one (?) etc? If it isn't, it'd be good to have it on file somewhere so it's easier to reason about.

It'd be good to have a client-side mechanism to request an up-to-date list of templates, so we can use the familiar useSelect/useDispatch pattern to update those. This will help solving glitches like this, and will overall help decouple the client from the PHP-provided variables (which in turn will eventually allow us to directly integrate edit-site with e.g. Calypso).

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, okay. I think that's something we should seek to resolve though -- possibly through some modifications to the endpoint, in order to reflect the template loading mechanism.

We shouldn't modify the standard REST API collection behavior. We can introduce a separate endpoint for finding the currently published template for a given slug.

Aside, is the 'proper' resolution documented anywhere? I.e. when to use the published template, when to fall back to an auto-draft, when to generate one (?) etc? If it isn't, it'd be good to have it on file somewhere so it's easier to reason about.

Published templates are always used first and mean the template was customized. Auto drafts are only used when the templates haven't been customized. We should preferably use the latest ones, but because certain preloading flows can run template resolution more than once, you can end up in a situation where the site editor loaded the N-1 auto drafts and then when you do this fetch by slug, you end up with an N auto draft.

This isn't documented because it's a regression I recently found when catching up with the preloading work.

It'd be good to have a client-side mechanism to request an up-to-date list of templates, so we can use the familiar useSelect/useDispatch pattern to update those. This will help solving glitches like this, and will overall help decouple the client from the PHP-provided variables (which in turn will eventually allow us to directly integrate edit-site with e.g. Calypso).

Agreed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, okay. I think that's something we should seek to resolve though -- possibly through some modifications to the endpoint, in order to reflect the template loading mechanism.

We shouldn't modify the standard REST API collection behavior. We can introduce a separate endpoint for finding the currently published template for a given slug.

Agreed. If the required query can still be done on the client side (and doesn't impact perf too negatively), we can also resort to that. (I didn't mean to mess with the collection endpoint format, I was rather considering adding some standard modifications akin to e.g. your #21851.)

Aside, is the 'proper' resolution documented anywhere? I.e. when to use the published template, when to fall back to an auto-draft, when to generate one (?) etc? If it isn't, it'd be good to have it on file somewhere so it's easier to reason about.

Published templates are always used first and mean the template was customized. Auto drafts are only used when the templates haven't been customized. We should preferably use the latest ones, but because certain preloading flows can run template resolution more than once, you can end up in a situation where the site editor loaded the N-1 auto drafts and then when you do this fetch by slug, you end up with an N auto draft.

Thanks for explaining, that's very helpful!

This isn't documented because it's a regression I recently found when catching up with the preloading work.

Also good to know, thanks 👍

Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps, a new top-level query param would be nice. That way, we can keep using core/data semantically in the client, but leave the awkward publish/auto-draft logic in the server. Something like ?loaded or ?resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

BTW, I just realized that the logic you described seems to be implemented in useTemplatePartPost, right? So it might make sense to use this in NavigateToLink in order to centralize the implementation of this behavior, and allow us to change it if we end up making changes to the endpoint.

Perhaps, a new top-level query param would be nice. That way, we can keep using core/data semantically in the client, but leave the awkward publish/auto-draft logic in the server. Something like ?loaded or ?resolved.

Yeah, keeping that logic on the server side sounds like a good idea. Would you add those query args to the existing endpoint (using rest_wp_template_part_collection_params and rest_wp_template_part_query)?

Copy link
Contributor

Choose a reason for hiding this comment

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

BTW, I just realized that the logic you described seems to be implemented in useTemplatePartPost, right? So it might make sense to use this in NavigateToLink in order to centralize the implementation of this behavior, and allow us to change it if we end up making changes to the endpoint.

Yes

Yeah, keeping that logic on the server side sounds like a good idea. Would you add those query args to the existing endpoint (using rest_wp_template_part_collection_params and rest_wp_template_part_query)?

Yes

Would you like to do those things in this PR instead?

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, I'll give that a shot tomorrow!

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Prep PRs took a while 😅 WIP PR for this feature: #21981

@ockham ockham force-pushed the remove/navigate-to-link-template-ids-prop branch 2 times, most recently from 4e46c18 to 3a657a9 Compare April 29, 2020 21:04
@ockham ockham force-pushed the remove/navigate-to-link-template-ids-prop branch from 3a657a9 to 961d690 Compare May 13, 2020 11:46
@epiqueras
Copy link
Contributor

Is this ready for another look?

@ockham
Copy link
Contributor Author

ockham commented May 13, 2020

Is this ready for another look?

It is now -- there was one annoying bug that I missed in #21981 and that I've finally fixed. I've added an (unfortunately lengthy 😅 ) note to the PR desc (including instructions how to test the fix).

@@ -183,7 +183,7 @@ function filter_rest_wp_template_collection_params( $query_params ) {
function filter_rest_wp_template_query( $args, $request ) {
if ( $request['resolved'] ) {
$template_ids = array( 0 ); // Return nothing by default (the 0 is needed for `post__in`).
$template_types = $request['slug'] ? array( $request['slug'] ) : get_template_types();
$template_types = $request['slug'] ? $request['slug'] : get_template_types();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the bug I missed in #21981. Turns out that $request['some-param'] is an array 😬

@@ -194,10 +194,10 @@ function filter_rest_wp_template_query( $args, $request ) {

$current_template = gutenberg_find_template_post_and_parts( $template_type );
if ( isset( $current_template ) ) {
$template_ids[ $current_template['template_post']->post_name ] = $current_template['template_post']->ID;
$template_ids[] = $current_template['template_post']->ID;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is kinda cosmetic, we just don't need array keys.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's to avoid duplication, but I guess post__in doesn't care.

@ockham
Copy link
Contributor Author

ockham commented May 13, 2020

Apologies, I found another issue. Putting on hold.

@ockham ockham added the [Status] Blocked Used to indicate that a current effort isn't able to move forward label May 13, 2020
@ockham
Copy link
Contributor Author

ockham commented May 13, 2020

Apologies, I found another issue. Putting on hold.

Fixed in 2528cfa. Looks like I'd broken template rendering 😅

Should be ready for review now.

@ockham ockham removed the [Status] Blocked Used to indicate that a current effort isn't able to move forward label May 13, 2020
@epiqueras epiqueras merged commit 9699f4f into master May 13, 2020
@epiqueras epiqueras deleted the remove/navigate-to-link-template-ids-prop branch May 13, 2020 18:50
@github-actions github-actions bot added this to the Gutenberg 8.2 milestone May 13, 2020
ockham added a commit that referenced this pull request Jun 9, 2020
…21878)

This is to decouple `edit-site` even further from the `settings` variable that is at the moment directly passed from PHP, and will use the REST API instead. #21877 is complementary to this PR.
@ellatrix ellatrix mentioned this pull request Jun 16, 2020
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants