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

Use cleaned slug to query for template part post #25030

Merged

Conversation

noahtallen
Copy link
Member

Description

Fixes #20375. Apparently, WordPress changes the title of the template part CPT to remove a character like / and replace it with -, which is obviously problematic for paths. We "clean for slug" in several other places in the template part, so I'm just adding that here. That said....

What other code could be problematic because of this? Do we need to support the character / more directly? I wonder if this code could be problematic when trying to figure out if we need to create a new template part autodraft:

$template_part_query = new WP_Query(
array(
'post_type' => 'wp_template_part',
'post_status' => array( 'publish', 'auto-draft' ),
'name' => $block['attrs']['slug'],
'meta_key' => 'theme',
'meta_value' => $block['attrs']['theme'],
'posts_per_page' => 1,
'no_found_rows' => true,
)
);

it might not be able to find existing autodrafts because it does not convert the slug.

How has this been tested?

Locally in edit site. To test, you should do the following:

  1. delete all existing template and template part CPTs.
  2. In an existing block-based theme mapped to your WordPress instance, create a new subdirectory under block-template-parts called template-part-subdir
  3. In that subdirectory, create a new file called new-template-part.html. Copy/paste some block markup into that file and make sure you can identify what the content is by changing some paragraph content or something like that.
  4. From an existing template (e.g. index or singular), update one of the template parts slugs to say template-part-subdir/new-template-part. (e.g. change the slug from header to essentially the path to the new template part under the subdirectory)
  5. Open that template in the site editor and make sure that the template part loads from the subdirectory.

Screenshots

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 Sep 3, 2020

Size Change: +9 B (0%)

Total Size: 1.17 MB

Filename Size Change
build/block-library/index.js 138 kB +9 B (0%)
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 1.14 kB 0 B
build/annotations/index.js 3.67 kB 0 B
build/api-fetch/index.js 3.41 kB 0 B
build/autop/index.js 2.82 kB 0 B
build/blob/index.js 620 B 0 B
build/block-directory/index.js 7.99 kB 0 B
build/block-directory/style-rtl.css 953 B 0 B
build/block-directory/style.css 952 B 0 B
build/block-editor/index.js 128 kB 0 B
build/block-editor/style-rtl.css 11.1 kB 0 B
build/block-editor/style.css 11.1 kB 0 B
build/block-library/editor-rtl.css 8.64 kB 0 B
build/block-library/editor.css 8.64 kB 0 B
build/block-library/style-rtl.css 7.6 kB 0 B
build/block-library/style.css 7.6 kB 0 B
build/block-library/theme-rtl.css 741 B 0 B
build/block-library/theme.css 742 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/blocks/index.js 47.7 kB 0 B
build/components/index.js 200 kB 0 B
build/components/style-rtl.css 15.5 kB 0 B
build/components/style.css 15.5 kB 0 B
build/compose/index.js 9.67 kB 0 B
build/core-data/index.js 12.3 kB 0 B
build/data-controls/index.js 1.29 kB 0 B
build/data/index.js 8.55 kB 0 B
build/date/index.js 5.38 kB 0 B
build/deprecated/index.js 772 B 0 B
build/dom-ready/index.js 568 B 0 B
build/dom/index.js 4.48 kB 0 B
build/edit-navigation/index.js 11.7 kB 0 B
build/edit-navigation/style-rtl.css 1.16 kB 0 B
build/edit-navigation/style.css 1.16 kB 0 B
build/edit-post/index.js 305 kB 0 B
build/edit-post/style-rtl.css 6.26 kB 0 B
build/edit-post/style.css 6.25 kB 0 B
build/edit-site/index.js 17.1 kB 0 B
build/edit-site/style-rtl.css 3.06 kB 0 B
build/edit-site/style.css 3.06 kB 0 B
build/edit-widgets/index.js 12 kB 0 B
build/edit-widgets/style-rtl.css 2.46 kB 0 B
build/edit-widgets/style.css 2.45 kB 0 B
build/editor/editor-styles-rtl.css 492 B 0 B
build/editor/editor-styles.css 493 B 0 B
build/editor/index.js 45.6 kB 0 B
build/editor/style-rtl.css 3.81 kB 0 B
build/editor/style.css 3.81 kB 0 B
build/element/index.js 4.65 kB 0 B
build/escape-html/index.js 733 B 0 B
build/format-library/index.js 7.71 kB 0 B
build/format-library/style-rtl.css 547 B 0 B
build/format-library/style.css 548 B 0 B
build/hooks/index.js 2.13 kB 0 B
build/html-entities/index.js 621 B 0 B
build/i18n/index.js 3.57 kB 0 B
build/is-shallow-equal/index.js 710 B 0 B
build/keyboard-shortcuts/index.js 2.52 kB 0 B
build/keycodes/index.js 1.94 kB 0 B
build/list-reusable-blocks/index.js 3.12 kB 0 B
build/list-reusable-blocks/style-rtl.css 476 B 0 B
build/list-reusable-blocks/style.css 476 B 0 B
build/media-utils/index.js 5.32 kB 0 B
build/notices/index.js 1.79 kB 0 B
build/nux/index.js 3.4 kB 0 B
build/nux/style-rtl.css 671 B 0 B
build/nux/style.css 668 B 0 B
build/plugins/index.js 2.56 kB 0 B
build/primitives/index.js 1.41 kB 0 B
build/priority-queue/index.js 789 B 0 B
build/redux-routine/index.js 2.85 kB 0 B
build/rich-text/index.js 13.9 kB 0 B
build/server-side-render/index.js 2.77 kB 0 B
build/shortcode/index.js 1.7 kB 0 B
build/token-list/index.js 1.27 kB 0 B
build/url/index.js 4.06 kB 0 B
build/viewport/index.js 1.85 kB 0 B
build/warning/index.js 1.14 kB 0 B
build/wordcount/index.js 1.17 kB 0 B

compressed-size-action

@Addison-Stavlo
Copy link
Contributor

it might not be able to find existing autodrafts because it does not convert the slug.

Looking through the code for auto-drafting, it seems like this would be the case. Im thinking we would just need to change the 'name' value in that query array you mentioned by adding the clean_for_slug there.

@noahtallen
Copy link
Member Author

Looking at the format of the autodraft:

$post = [
  "post_title" => "test-dir/new-template-part",
  "post_status" => "auto-draft",
  "post_name" => "test-dir-new-template-part"
  "post_type" => "wp_template_part",

];

When inserting the post, both title and name are set to the slug, so it appears that only the name field is being modified here 🤔

@noahtallen
Copy link
Member Author

Looking at this code though:

if ( $template_part_post && 'auto-draft' !== $template_part_post->post_status ) {
$template_part_id = $template_part_post->ID;
} else {
// Template part is not customized, get it from a file and make an auto-draft for it, unless one already exists

It looks like we avoid referencing the ID for auto-draft, so it would only affect things after the template part is considered "published". (That said, doesn't that mean that we are creating tons of extra autodrafts??)

@Addison-Stavlo
Copy link
Contributor

Addison-Stavlo commented Sep 3, 2020

(That said, doesn't that mean that we are creating tons of extra autodrafts??)

In the case of template parts in nested folders, yes that seems like thats what it would mean. But if we clean_for_slug the name field in the first query that should prevent it.

It looks like we avoid referencing the ID for auto-draft, so it would only affect things after the template part is considered "published".

Im not exactly sure what you mean here. If it is an auto draft it checks to see if that auto draft's content match the file contents to see if it needs to create a new one, but either way it still returns the auto-drafts ID.

if ( $template_part_post && $template_part_post->post_content === $file_contents ) {
$template_part_id = $template_part_post->ID;
} else {
$template_part_id = wp_insert_post(

@noahtallen
Copy link
Member Author

If it is an auto draft it checks to see if that auto draft's content match the file contents to see if it needs to create a new one

Ah, this is the part I was missing, thanks.

But if we clean_for_slug the name field in the first query that should prevent it.

I'm struggling to find a similar PHP function :/ I'm thinking we could search for title instead of name so that we don't have to do any conversion there.

@noahtallen noahtallen force-pushed the fix/template-part-resolution-from-nested-directories branch from d56f59a to 93abd13 Compare September 3, 2020 18:07
@noahtallen
Copy link
Member Author

@Addison-Stavlo I added error_log calls locally, and it was creating new autodrafts for nested template parts every time that function was called.

With 93abd13, I confirmed that it no longer does that. We use title now instead of name, since title does not appear to change the format of the slug like name does.

@jeyip
Copy link
Contributor

jeyip commented Sep 3, 2020

Hmmm...I think I may be misunderstanding something.

Original Steps:

  1. delete all existing template and template part CPTs.
  2. In an existing block-based theme mapped to your WordPress instance, create a new subdirectory under block-template-parts called template-part-subdir
  3. In that subdirectory, create a new file called new-template-part.html. Copy/paste some block markup into that file and make sure you can identify what the content is by changing some paragraph content or something like that.
  4. From an existing template (e.g. index or singular), update one of the template parts slugs to say template-part-subdir/new-template-part. (e.g. change the slug from header to essentially the path to the new template part under the subdirectory)
  5. Open that template in the site editor and make sure that the template part loads from the subdirectory.

What I did:

  1. I ran npx wp-env destroy all
  2. I created the block-template-parts/template-part-subdir/ subdirectory for seedlet-blocks
  3. I added new-template-part.html to the subdirectory
  4. I added distinct content to the new file
  5. I enabled seedlet blocks and the site editor
  6. I navigated to the site editor and renamed the header to template-part-subdir/new-template-part
  7. I created a new template part block and tried to choose the existing template-part-subdir/new-template-part

The template part does not display the distinct content in the new file I made

@noahtallen
Copy link
Member Author

tried to choose the existing template-part-subdir/new-template-part

I don't think we ever try to find all template parts provided by the theme and then pull them into the site editor. We only ever show template parts from themes which are used by templates that the theme provides. Essentially, when loading the template, we look for all template part blocks in the template, and only then try to find block template part HTML files which match the slugs in the template part blocks. So I'm not sure if it would show up otherwise.

From an existing template (e.g. index or singular), update one of the template parts slugs to say template-part-subdir/new-template-part

If you do this step from the template HTML file before loading it in the site editor, it should work.

I navigated to the site editor and renamed the header to template-part-subdir/new-template-part

I'm not sure if this would work because template-part-subdir/new-template-part is changed to template-part-subdir-new-template-part in cleanForSlug. Since no autodrafts are made for template parts until they are referenced by a template, I'm not sure it would find anything...

I created a new template part block and tried to choose the existing template-part-subdir/new-template-part

Does it show up in the list as an option?

At any rate, I think you're uncovering some more limitations with template part loading. I think they might possibly apply more broadly than just template parts with / in the slug.

I ran npx wp-env destroy all

Also, just a couple tips for this step:

  • npx wp-env destroy destroys everything related to the current local instance, no all param needed
  • npx wp-env clean all would wipe the databases without cleaning up anything else
  • you can delete customized template and template part CPTs from the Appearance > Template or Appearance > Template Part menu in wp-admin :)

Screen Shot 2020-09-03 at 1 41 03 PM

Copy link
Contributor

@Addison-Stavlo Addison-Stavlo left a comment

Choose a reason for hiding this comment

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

Tested and confirmed:
✅ Subdirectory template part is properly resolved.
✅ Subdirectory template parts no longer have duplicated auto-drafts created on each load.
✅ The rest of the flow seems to continue to work as expected.

The changes look good to me. 😁 Nice catch and fix!

@jeyip
Copy link
Contributor

jeyip commented Sep 3, 2020

If you do this step from the template HTML file before loading it in the site editor, it should work.

Ahhhh I see. I should modify the template part slug in index.html. I tried again and referencing block templates in subdirectories works as expected 🎉

Also, just a couple tips for this step:

  • npx wp-env destroy destroys everything related to the current local instance, no all param needed
  • npx wp-env clean all would wipe the databases without cleaning up anything else
  • you can delete customized template and template part CPTs from the Appearance > Template or Appearance > Template Part > menu in wp-admin :)

Thanks for the tips Noah 🙏

@noahtallen
Copy link
Member Author

I'll go ahead and merge this. I think there may still be some weird things to work out when it comes to slugs & titles and the difference with cleanForSlug, but those can be done separately. This still fixes the root issue, which is allowing themes to include template parts from subdirectories, which is now working correctly.

@noahtallen noahtallen merged commit b1c8026 into master Sep 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Block library /packages/block-library [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Block template parts in subfolders are not loaded in the Full Site Editor
3 participants