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

Lib: Add template part CPTs and their theme resolution logic. #18339

Merged
merged 1 commit into from Nov 19, 2019

Conversation

@epiqueras
Copy link
Contributor

epiqueras commented Nov 6, 2019

Follows #17512

Description

This PR continues the template API work by introducing the concept of template parts.

Template parts are blocks with the following attributes:

  • slug: The name of the template, e.g. 'header'.
  • theme: The name of the theme that provided the part, if any, e.g. 'twentytwenty' or null for no theme.
  • id: After a template part has been modified, it will be saved as a wp_template_part post. This attribute references that post, if any, e.g. 8.

Themes provide template parts in a /block-template-parts directory as html files where the name of the file matches their 'slug' attribute.

For example:

/block-templates/single.html:

<!-- wp:template-part {"slug":"header","theme":"twentytwenty"} /-->
<!-- wp:paragraph -->
<p>Single Template</p>
<!-- /wp:paragraph -->

/block-template-parts/header.html:

<!-- wp:paragraph -->
<p>Header TwentyTwenty Template Part</p>
<!-- /wp:paragraph -->

When loading in the editor, all template parts without an id will get an auto draft with the relevant file's contents in them so that the editor can load the contents and potentially persist any changes. Once the block is implemented, this will have to also call the block's server rendering callback to check for any nested template parts.

When loading in the front end, the block's server rendering callback should output either the relevant file's content if there is no id, or the relevant post content if there is one.

We need a theme attribute to differentiate between template parts with the same slug originating from different themes. When you save changes to a given template, it and all its nested template parts will persist across theme switches. Even though by that point those template parts will have ids and will be renderable regardless of what the new active theme provides, we need a way for the user to insert new instances of them and that is where theme comes in handy. For now, we store the value in post meta so we can do meta queries.

How has this been tested?

This was mainly a foundational change, but it was verified that the Full Site Editing experiment still works as expected and that nothing changes when it is not enabled.

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.
@youknowriad

This comment has been minimized.

Copy link
Contributor

youknowriad commented Nov 11, 2019

Themes provide template parts in a /block-template-parts directory

Does it need to be different than the regular block templates?

@youknowriad youknowriad requested a review from mtias Nov 11, 2019
@epiqueras

This comment has been minimized.

Copy link
Contributor Author

epiqueras commented Nov 11, 2019

Does it need to be different than the regular block templates?

It simplifies a lot of the resolution code.

@youknowriad

This comment has been minimized.

Copy link
Contributor

youknowriad commented Nov 12, 2019

It simplifies a lot of the resolution code.

Can you elaborate more. It feels to me like it's just a "virtual" distinction, today in themes you can have page.php include a sidebar.php at the same level.

@epiqueras

This comment has been minimized.

Copy link
Contributor Author

epiqueras commented Nov 12, 2019

Querying the file system to look for templates vs. template parts becomes easier if they are in separate directories.

Furthermore, writing WPQuerys that mirror the template hierarchy also just works out of the box without having to filter out template parts from templates or vice versa.

From Dotcom's exploration:

For storing the data, we are now only using wp_template_part CPT, but that’s just because our solution didn’t require more. When we tried to envision what core is going to do and align with that a couple of months ago, we leaned toward the wp_template and wp_template_part split, as opposed to just wp_template CPT with hierarchical taxonomies. To clarify, both options seem viable from the implementation standpoint, but it seems like the former requires less wiring, might perform slightly better, and could better aligns with existing WP concepts and infrastructure. Some benefits in my opinion:

  1. There is a nice parallel with terminology in existing template hierarchy (page templates and template parts).

  2. We are trying to model a tree structure, and that’s easier to enforce with the above split. In order to prevent it from becoming a cyclic graph, that could result in infinite loops in editing and rendering context, our query would have to be more complex and filter out page templates in some contexts (e.g. we want to prevent template A containing template B, which also contains A).

  3. Similar to (2), designating a template part as a full page template wouldn’t make much sense, again requiring additional code, and likely another table join with taxonomies to filter them out (depending on implementation). For example: assigning the Header template part as the Homepage template doesn't make sense because a "full-fledged template" would entail several template parts (header, footer, post content etc.).

While all of the above can easily be worked around, they might hint that we are trying to clump together two conceptually different entities under the same roof, and we might discover additional work on account of that down the road too.

Copy link
Member

felixarntz left a comment

This looks solid to me, good to go. I agree that separating the folder for template parts from the one for templates makes sense. It's a very common pattern today which helps a lot with distinguishing the two, especially because they can easily pile up.

@epiqueras epiqueras merged commit 5b789a3 into master Nov 19, 2019
2 checks passed
2 checks passed
pull-request-automation
Details
Travis CI - Pull Request Build Passed
Details
@epiqueras epiqueras added this to Done in Phase 2 via automation Nov 19, 2019
@epiqueras epiqueras deleted the add/template-parts-post-type branch Nov 19, 2019
@youknowriad youknowriad modified the milestones: Future, Gutenberg 7.0 Nov 25, 2019
@epiqueras epiqueras mentioned this pull request Nov 26, 2019
5 of 6 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.