Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Fix custom templates with fallback being incorrectly attributed #5447

Merged
merged 5 commits into from Dec 24, 2021

Conversation

sunyatasattva
Copy link
Contributor

@sunyatasattva sunyatasattva commented Dec 23, 2021

Category and tags templates can fallback to the generic archive if, e.g., the theme provides one for the latter but not for the former (#5380). However, since Gutenberg is not aware of this fallback mechanism, it would incorrectly attribute the custom template
to the user instead of the theme.

Here we are explicitly setting the has_theme_file to make sure Gutenberg knows we do, in fact, have a theme fail (if not what it expects).

Fixes #5441

Testing

Manual Testing

How to test the changes in this Pull Request:

  1. Install and enable the Gutenberg plugin.
  2. Install and enable the TT1 Blocks theme.
  3. Add an archive-product.html. This is because we are using the themes archive-product.html file for the category and tag templates as they're typically the same.
  4. Go to the templates list within the Site Editor
  5. You will see now that Product Archive, Product Category and Product Tag are added by the theme.
  6. Customize the Product Category template and save it.
  7. Navigate back to the templates list within the Site Editor. You will notice under the "Added By" column it should say your theme along with a theme icon.
  8. Notice that these templates render in the Site Editor, and on the front-end as expected with and without customizations.

Regression testing

Note: The logic of all these steps is a bit convoluted, so doing some regression tests is advised for the following scenarios:

  1. If you put product taxonomy template(s) in the theme, please check that these are used over the themes product-archive.html on both the frontend and in the site editor. Please also check these are customizable and render as expected.
  2. If no Woo related templates are in the theme, check it uses the templates from Woo Blocks as expected, on both the frontend and in the site editor. Please also check these are customizable and render as expected.
  3. If you put a taxonomy template(s) in the theme, it doesn't appear twice in the template list.

User Facing Testing

These are steps for user testing (where "user" is someone interacting with this change that is not editing any code).

  • Same as above

Changelog

Fix custom templates with fallback to archive being incorrectly attributed to the user in the editor instead of the parent theme.

Category and tags templates can fallback to the generic archive if, e.g., the theme
provides one for the latter but not for the former. However, since Gutenberg is not
aware of this fallback mechanism, it would incorrectly attribute the custom template
to the user instead of the theme.

Here we are explicitly setting the `has_theme_file` to make sure Gutenberg knows
we do, in fact, have a theme fail (if not what it expects).

Fixes #5441
@sunyatasattva sunyatasattva added type: bug The issue/PR concerns a confirmed bug. focus: FSE Work related to prepare WooCommerce for FSE. focus: template Related to API powering block template functionality in the Site Editor labels Dec 23, 2021
@sunyatasattva sunyatasattva self-assigned this Dec 23, 2021
@rubikuserbot rubikuserbot requested a review from a team December 23, 2021 12:37
@github-actions
Copy link
Contributor

github-actions bot commented Dec 23, 2021

Size Change: +137 B (0%)

Total Size: 819 kB

Filename Size Change
build/attribute-filter.js 12.7 kB +4 B (0%)
build/cart-blocks/order-summary-frontend.js 8.98 kB +29 B (0%)
build/cart-frontend.js 45.5 kB -3 B (0%)
build/cart.js 44.3 kB +29 B (0%)
build/checkout-blocks/order-summary-frontend.js 11.4 kB +36 B (0%)
build/checkout.js 47.1 kB +27 B (0%)
build/price-filter.js 8.62 kB +15 B (0%)
ℹ️ View Unchanged
Filename Size
build/active-filters-frontend.js 6.22 kB
build/active-filters.js 7.05 kB
build/all-products-frontend.js 18.6 kB
build/all-products.js 34.4 kB
build/all-reviews.js 8.35 kB
build/atomic-block-components/add-to-cart--atomic-block-components/button--atomic-block-components/image---a7e2bb9b.js 2.76 kB
build/atomic-block-components/add-to-cart--atomic-block-components/button.js 1.48 kB
build/atomic-block-components/add-to-cart-frontend.js 6.87 kB
build/atomic-block-components/add-to-cart.js 6.42 kB
build/atomic-block-components/button-frontend.js 1.48 kB
build/atomic-block-components/button.js 851 B
build/atomic-block-components/category-list-frontend.js 457 B
build/atomic-block-components/category-list.js 458 B
build/atomic-block-components/image-frontend.js 1.37 kB
build/atomic-block-components/image.js 1.05 kB
build/atomic-block-components/price-frontend.js 1.74 kB
build/atomic-block-components/price.js 1.7 kB
build/atomic-block-components/rating-frontend.js 552 B
build/atomic-block-components/rating.js 554 B
build/atomic-block-components/sale-badge-frontend.js 625 B
build/atomic-block-components/sale-badge.js 622 B
build/atomic-block-components/sku-frontend.js 386 B
build/atomic-block-components/sku.js 385 B
build/atomic-block-components/stock-indicator-frontend.js 584 B
build/atomic-block-components/stock-indicator.js 585 B
build/atomic-block-components/summary-frontend.js 872 B
build/atomic-block-components/summary.js 871 B
build/atomic-block-components/tag-list-frontend.js 458 B
build/atomic-block-components/tag-list.js 458 B
build/atomic-block-components/title-frontend.js 1.11 kB
build/atomic-block-components/title.js 1.1 kB
build/attribute-filter-frontend.js 16.3 kB
build/blocks-checkout.js 17.6 kB
build/cart-blocks/accepted-payment-methods-frontend.js 1.15 kB
build/cart-blocks/checkout-button-frontend.js 1.14 kB
build/cart-blocks/empty-cart-frontend.js 345 B
build/cart-blocks/express-payment-frontend.js 4.86 kB
build/cart-blocks/filled-cart-frontend.js 766 B
build/cart-blocks/items-frontend.js 298 B
build/cart-blocks/line-items-frontend.js 5.13 kB
build/cart-blocks/totals-frontend.js 320 B
build/checkout-blocks/actions-frontend.js 1.44 kB
build/checkout-blocks/billing-address--checkout-blocks/shipping-address-frontend.js 4.22 kB
build/checkout-blocks/billing-address-frontend.js 884 B
build/checkout-blocks/contact-information-frontend.js 2.94 kB
build/checkout-blocks/express-payment-frontend.js 5.15 kB
build/checkout-blocks/fields-frontend.js 343 B
build/checkout-blocks/order-note-frontend.js 1.13 kB
build/checkout-blocks/payment-frontend.js 7.41 kB
build/checkout-blocks/shipping-address-frontend.js 971 B
build/checkout-blocks/shipping-methods-frontend.js 4.81 kB
build/checkout-blocks/terms-frontend.js 1.21 kB
build/checkout-blocks/totals-frontend.js 324 B
build/checkout-frontend.js 47.6 kB
build/featured-category.js 8.55 kB
build/featured-product.js 9.9 kB
build/handpicked-products.js 7.32 kB
build/legacy-template.js 2.08 kB
build/mini-cart-component-frontend.js 14.2 kB
build/mini-cart-contents.js 3.59 kB
build/mini-cart-frontend.js 1.76 kB
build/mini-cart.js 6.46 kB
build/price-filter-frontend.js 12.4 kB
build/price-format.js 1.18 kB
build/product-best-sellers.js 7.51 kB
build/product-categories.js 3.47 kB
build/product-category.js 8.36 kB
build/product-new.js 7.66 kB
build/product-on-sale.js 8.05 kB
build/product-search.js 2.47 kB
build/product-tag.js 7.76 kB
build/product-top-rated.js 7.63 kB
build/products-by-attribute.js 8.48 kB
build/reviews-by-category.js 11.9 kB
build/reviews-by-product.js 12.9 kB
build/reviews-frontend.js 7.25 kB
build/single-product-frontend.js 22.1 kB
build/single-product.js 10.4 kB
build/stock-filter-frontend.js 6.81 kB
build/stock-filter.js 6.82 kB
build/vendors--atomic-block-components/add-to-cart--cart-blocks/order-summary--checkout-blocks/billing-ad--c5eb4dcd-frontend.js 19 kB
build/vendors--atomic-block-components/add-to-cart-frontend.js 6.82 kB
build/vendors--atomic-block-components/price--cart-blocks/line-items--cart-blocks/order-summary--checkout--8a3571de-frontend.js 5.71 kB
build/vendors--cart-blocks/line-items--checkout-blocks/order-summary-frontend.js 3.14 kB
build/vendors--cart-blocks/order-summary--checkout-blocks/billing-address--checkout-blocks/order-summary---eb4d2cec-frontend.js 4.75 kB
build/wc-blocks-data.js 8.84 kB
build/wc-blocks-editor-style-rtl.css 4.46 kB
build/wc-blocks-editor-style.css 4.46 kB
build/wc-blocks-google-analytics.js 1.56 kB
build/wc-blocks-middleware.js 949 B
build/wc-blocks-registry.js 2.7 kB
build/wc-blocks-shared-context.js 1.51 kB
build/wc-blocks-shared-hocs.js 1.14 kB
build/wc-blocks-style-rtl.css 21.6 kB
build/wc-blocks-style.css 21.6 kB
build/wc-blocks-vendors-style-rtl.css 1.28 kB
build/wc-blocks-vendors-style.css 1.28 kB
build/wc-blocks-vendors.js 65.5 kB
build/wc-blocks.js 2.96 kB
build/wc-payment-method-bacs.js 820 B
build/wc-payment-method-cheque.js 816 B
build/wc-payment-method-cod.js 912 B
build/wc-payment-method-paypal.js 838 B
build/wc-payment-method-stripe.js 11.1 kB
build/wc-settings.js 2.61 kB

compressed-size-action

Copy link
Contributor

@opr opr left a comment

Choose a reason for hiding this comment

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

Works well! Thanks for doing this, I just have a couple of nitpicky changes though, let me know what you think :)

👏🏼

* @return boolean
*/
public static function confirm_theme_file_when_fallback_is_available( $query_result, $template ) {
$template_with_fallback_idx = null;
Copy link
Contributor

Choose a reason for hiding this comment

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

What is idx? If it means index can we just use the full word instead?

$template_with_fallback_idx = null;
$is_duplicate = false;

array_walk(
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason why you chose to use this over a foreach? foreach is quicker :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No reason but my massive PHP ignorance. I didn't know you could get the index with foreach but it looks like you can! Thanks for pointing that out.

);

if ( $is_duplicate ) {
if ( is_int( $template_with_fallback_idx ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we add a comment here explaining why we need to check is_int? This will stop someone "refactoring" it in future 🤓

*
* @return boolean
*/
public static function confirm_theme_file_when_fallback_is_available( $query_result, $template ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think something like set_has_theme_file_if_fallback_is_available would be a slightly better name? At a glance it is hard to tell what this function does imo.

Comment on lines 297 to 305
if (
in_array( $template_slug, $eligible_for_fallbacks, true )
&& ! self::theme_has_template( $template_slug )
&& self::theme_has_template( 'archive-product' )
) {
return true;
}

return false;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we just return the result of the evaluation instead of using an if here?

@sunyatasattva
Copy link
Contributor Author

@opr Thanks for the feedback, especially for the foreach ! My code looks much cleaner as I refactored the whole need to have an index there. 🙏

Copy link
Contributor

@opr opr left a comment

Choose a reason for hiding this comment

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

🙌🏼 Thanks for addressing the changes! There's just one tiny thing but I'll pre-approve.

* @return boolean
*/
public static function set_has_theme_file_if_fallback_is_available( $query_result, $template ) {
foreach ( $query_result as $i => &$query_result_template ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks much better but $i is not used

Suggested change
foreach ( $query_result as $i => &$query_result_template ) {
foreach ( $query_result as $query_result_template ) {

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 had used the index, but then I realized I didn't need that. I think I still need to pass the query_result_template as reference because I edit it, right? Again, my lackluster PHP knowledge her, but I thought the & was required here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh right, yeah you do sorry I missed that! I didn't notice the & there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At least that's what I understand from the docs:

In order to be able to directly modify array elements within the loop precede $value with &

@github-actions github-actions bot added this to the 6.7.0 milestone Dec 23, 2021
@sunyatasattva sunyatasattva merged commit 9a8f27f into trunk Dec 24, 2021
@sunyatasattva sunyatasattva deleted the fix/5441-wrongly-assigned-template-fallbacks branch December 24, 2021 15:15
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
focus: FSE Work related to prepare WooCommerce for FSE. focus: template Related to API powering block template functionality in the Site Editor type: bug The issue/PR concerns a confirmed bug.
Projects
None yet
2 participants