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
| Hook | Priority | Standard block |
|---|---|---|
woocommerce_before_single_product_summary | 10 | The Sale badge |
| 20 | The image gallery | |
woocommerce_single_product_summary | 5 | The title |
| 10 | The rating and the price | |
| 20 | The short description | |
| 30 | The Add to cart button | |
| 40 | SKU, categories, tags | |
| 50 | Sharing buttons | |
woocommerce_after_single_product_summary | 10 | Tabs: description, reviews |
| 15 | Upsells | |
| 20 | Related 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
| Hook | Priority | Standard block |
|---|---|---|
woocommerce_before_shop_loop_item | 10 | The product link opens |
woocommerce_before_shop_loop_item_title | 10 | The Sale badge and the image |
woocommerce_shop_loop_item_title | 10 | The title |
woocommerce_after_shop_loop_item_title | 5 | The rating |
| 10 | The price | |
woocommerce_after_shop_loop_item | 5 | The link closes |
| 10 | The 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
| Hook | Where |
|---|---|
woocommerce_before_main_content | Before the content of any shop page |
woocommerce_before_shop_loop | Above the list: result count and sorting |
woocommerce_after_shop_loop | Below the list: pagination |
woocommerce_no_products_found | When 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.