Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Block and classic cart and checkout

The Cart and Checkout pages come in two variants. Classic ones are rendered by shortcodes and PHP templates. Block ones are rendered by editor blocks that JavaScript draws in the browser. New shops get the block variant by default, and the variant decides which hooks fire on the page.

How to tell the variant

Open Pages → Cart in the editor:

What is on the pageVariant
A Cart block with nested blocksBlock
The [woocommerce_cart] shortcodeClassic
A Checkout blockBlock
The [woocommerce_checkout] shortcodeClassic

In code the same is checked by the WordPress function has_block():

// wp-content/plugins/acme-shop/includes/checkout.php
function acme_is_block_checkout(): bool
{
    return has_block('woocommerce/checkout', wc_get_page_id('checkout'));
}

The function returns true if the checkout page holds the block. Create the includes/checkout.php file and include it in acme-shop.php — it will be needed in the next chapter.

What works in both variants

Calculations run on the server the same way, so the calculation hooks are shared:

HookWhat it does
woocommerce_before_calculate_totalsChanges prices in the cart
woocommerce_cart_calculate_feesAdds fees and discounts
woocommerce_package_ratesChanges shipping costs
woocommerce_add_to_cart_validationValidates adding to the cart
woocommerce_add_cart_item_dataStores cart item data
woocommerce_order_status_...Reacts to an order status
woocommerce_thankyouThe Order received page

What works only in the classic variant

Everything that prints HTML or belongs to the PHP checkout form:

HookReplacement in the block variant
woocommerce_before_cart, woocommerce_after_cart_tableOrdinary blocks in the page editor
woocommerce_checkout_fieldswoocommerce_register_additional_checkout_field()
woocommerce_after_checkout_validationValidation in the field definition
woocommerce_checkout_order_processedwoocommerce_store_api_checkout_order_processed
Copies of cart/ and checkout/ templatesNot used

In the block variant these hooks are not called and raise no errors — the code is simply silent.

Going back to the classic variant

If the shop's customizations rely on classic hooks, the page is switched. Open Pages → Checkout, delete the Checkout block and insert a Shortcode block with the text:

[woocommerce_checkout]

Do the same for the cart with the [woocommerce_cart] shortcode. After saving, the page is rendered by PHP templates and all hooks from old examples start working.

Plugin compatibility

A plugin can state that it has been tested with block pages — next to the HPOS declaration in the main file:

// wp-content/plugins/acme-shop/acme-shop.php
add_action('before_woocommerce_init', function () {
    if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
            'cart_checkout_blocks',
            __FILE__,
            true
        );
    }
});

A third argument of false means the opposite: the plugin is incompatible with blocks, and the page editor warns the shop owner about it.

What to choose

SituationVariant
A new shop, few customizationsBlock
Many PHP fields and validations of your ownClassic
Payment or shipping plugins without block supportClassic

In this course the checkout examples are written for the classic variant, and a replacement is given for the block one.

Common mistake

Code from a ten-year-old article is attached to woocommerce_before_cart or woocommerce_checkout_fields, and nothing changes on the page. There are no errors in the log, so people hunt for a typo. First check whether the page is block or classic — nine times out of ten that is the cause.

Thanks for reading!

Donate to the site — we work hard for you.