Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Catalog and product page hooks

Shop pages are assembled from hooks. The product page template is almost empty: it holds do_action() calls, while the title, the price and the button are printed by WooCommerce functions attached to those hooks with different priorities. So a page is changed without touching the template: you add your function, detach a standard one or change the order.

The code of this lesson goes into includes/storefront.php.

Adding a block

// wp-content/plugins/acme-shop/includes/storefront.php
add_action('woocommerce_single_product_summary', function () {
    echo '<p class="acme-guarantee">Exchange and returns within 30 days.</p>';
}, 35);

The woocommerce_single_product_summary hook prints the right column of the product page. Priority 35 puts the paragraph right under the Add to cart button — open any product to see it.

The product page map

HookPriorityStandard block
woocommerce_before_single_product_summary10The Sale badge
20The image gallery
woocommerce_single_product_summary5The title
10The rating and the price
20The short description
30The Add to cart button
40SKU, categories, tags
50Sharing buttons
woocommerce_after_single_product_summary10Tabs: description, reviews
15Upsells
20Related products

Your block lands between the standard ones if you pick a priority between their numbers: 25 is between the description and the button, 45 is after the SKU.

Removing a block

// wp-content/plugins/acme-shop/includes/storefront.php
add_action('init', function () {
    remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_meta', 40);
    remove_action('woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20);
});

The line with the SKU and categories and the Related products block disappear from the product page. remove_action() takes the same hook, the same function and the same priority the block was attached with.

Moving a block

Moving means detaching and attaching again with a different priority:

// wp-content/plugins/acme-shop/includes/storefront.php
add_action('init', function () {
    remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_price', 10);
    add_action('woocommerce_single_product_summary', 'woocommerce_template_single_price', 29);
});

The price moves from under the title to the Add to cart button.

The catalog tile map

HookPriorityStandard block
woocommerce_before_shop_loop_item10The product link opens
woocommerce_before_shop_loop_item_title10The Sale badge and the image
woocommerce_shop_loop_item_title10The title
woocommerce_after_shop_loop_item_title5The rating
10The price
woocommerce_after_shop_loop_item5The link closes
10The Add to cart button
// wp-content/plugins/acme-shop/includes/storefront.php
add_action('woocommerce_after_shop_loop_item_title', function () {
    global $product;
 
    if (!$product->is_in_stock()) {
        echo '<span class="acme-out">Out of stock</span>';
    }
}, 15);

On the /shop/ page a note appears under the price of products that are out of stock.

Hooks around the list

HookWhere
woocommerce_before_main_contentBefore the content of any shop page
woocommerce_before_shop_loopAbove the list: result count and sorting
woocommerce_after_shop_loopBelow the list: pagination
woocommerce_no_products_foundWhen no products are found

Common mistake

remove_action() is called at the top level of a file or with a wrong priority — and the block stays in place without any error. Only an already attached function can be removed, and only with its own priority. Look up the exact name and number in the woocommerce/includes/wc-template-hooks.php file.

Thanks for reading!

Donate to the site — we work hard for you.