Skip to content
Back to skills

Classic Woocommerce Shop Loop

ASecurity

Build or audit WooCommerce shop/archive loops and product cards in a classic PHP theme. Covers `archive-product.php`, `content-product.php`, product taxonomy templates, `woocommerce_product_loop()`, `woocommerce_product_loop_start/end()`, `wc_get_loop_prop()`, `wc_get_template_part( 'content', 'product' )`, `wc_product_class()`, loop hooks, product cards, sale flash, thumbnails, ratings, price, add-to-cart ARIA, result count, ordering, pagination, no-products state, grid columns, and avoiding...

  • 22 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 5, 2026
developmentgophpdocumentation

Security analysis

A100/100

Scanned September 5, 2026

npx -y skills add Lonsdale201/wp-agent-skills --skill classic-woocommerce-shop-loop --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Classic Woocommerce Shop Loop?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Classic Woocommerce Shop Loop
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lonsdale201-classic-woocommerce-shop-loop/badge)](https://www.skillsdirectory.com/skills/lonsdale201-classic-woocommerce-shop-loop)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: classic-woocommerce-shop-loop
description: Build or audit WooCommerce shop/archive loops and product cards in a classic PHP theme. Covers `archive-product.php`, `content-product.php`, product taxonomy templates, `woocommerce_product_loop()`, `woocommerce_product_loop_start/end()`, `wc_get_loop_prop()`, `wc_get_template_part( 'content', 'product' )`, `wc_product_class()`, loop hooks, product cards, sale flash, thumbnails, ratings, price, add-to-cart ARIA, result count, ordering, pagination, no-products state, grid columns, and avoiding raw `WP_Query`/postmeta product loops.
metadata:
  wp-skills-author: "Soczó Kristóf"
  wp-skills-contact: "mailto:lonsdale201@hotmail.com"
  wp-skills-plugin: "woocommerce"
  wp-skills-plugin-version-tested: "10.8.1"
  wp-skills-wp-version-tested: "7.1"
  wp-skills-php-min: "7.4"
  wp-skills-last-updated: "2026-08-20"
---

# Classic WooCommerce Shop Loop

Use this when building or reviewing shop archives, product category/tag/attribute archives, product grids, related product grids, and product cards in a classic WooCommerce theme.

## When to Use This Skill

- Editing `woocommerce/archive-product.php`.
- Editing `woocommerce/content-product.php`.
- Changing product card markup, image size, title, price, rating, sale badge, or add-to-cart output.
- Adjusting result count, ordering, pagination, no-products state, rows, or columns.
- Reviewing custom product loops in templates.

## Archive Skeleton

Keep Woo's archive loop contract.

```php
do_action( 'woocommerce_before_main_content' );
do_action( 'woocommerce_shop_loop_header' );

if ( woocommerce_product_loop() ) {
	do_action( 'woocommerce_before_shop_loop' );

	woocommerce_product_loop_start();

	if ( wc_get_loop_prop( 'total' ) ) {
		while ( have_posts() ) {
			the_post();
			do_action( 'woocommerce_shop_loop' );
			wc_get_template_part( 'content', 'product' );
		}
	}

	woocommerce_product_loop_end();

	do_action( 'woocommerce_after_shop_loop' );
} else {
	do_action( 'woocommerce_no_products_found' );
}

do_action( 'woocommerce_after_main_content' );
```

Rules:

- Use `woocommerce_product_loop()` instead of only checking `have_posts()`.
- Use `woocommerce_product_loop_start()` and `woocommerce_product_loop_end()` so loop wrappers and subcategories work.
- Use `wc_get_loop_prop( 'total' )` before rendering products.
- Preserve `woocommerce_before_shop_loop`, `woocommerce_after_shop_loop`, and `woocommerce_no_products_found`.
- Do not build shop archives with a raw `WP_Query` unless this is a deliberate secondary product section.

## Product Card Contract

`content-product.php` must preserve the product object guard and visibility check.

```php
global $product;

if ( ! is_a( $product, WC_Product::class ) || ! $product->is_visible() ) {
	return;
}
?>
<li <?php wc_product_class( '', $product ); ?>>
	<?php
	do_action( 'woocommerce_before_shop_loop_item' );
	do_action( 'woocommerce_before_shop_loop_item_title' );
	do_action( 'woocommerce_shop_loop_item_title' );
	do_action( 'woocommerce_after_shop_loop_item_title' );
	do_action( 'woocommerce_after_shop_loop_item' );
	?>
</li>
```

Rules:

- Keep `wc_product_class( '', $product )`.
- Preserve default hook positions unless intentionally replacing output.
- Do not echo product title, price, image, or add-to-cart from raw postmeta.
- Use Woo template functions or `WC_Product` methods.
- Product cards should remain valid list items when inside `woocommerce_product_loop_start()`.

## Hook Map for Cards

Default product card hooks:

- `woocommerce_before_shop_loop_item`: product link open.
- `woocommerce_before_shop_loop_item_title`: sale flash and thumbnail.
- `woocommerce_shop_loop_item_title`: product title.
- `woocommerce_after_shop_loop_item_title`: rating and price.
- `woocommerce_after_shop_loop_item`: product link close and add-to-cart.

Example: move rating below add-to-cart.

```php
add_action( 'after_setup_theme', 'mytheme_product_card_hooks' );

function mytheme_product_card_hooks() {
	remove_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_rating', 5 );
	add_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_rating', 15 );
}
```

Rules:

- Use exact priorities from `wc-template-hooks.php`.
- Prefer hook changes over copying `content-product.php`.
- Test simple, variable, external, grouped, out-of-stock, sale, and hidden products.

## Add-to-Cart Accessibility

Woo 10.x loop add-to-cart provides:

- `aria-label` from `$product->add_to_cart_description()`.
- optional `aria-describedby` screen-reader text.
- `role="button"` for AJAX add-to-cart links when configured.
- `data-success_message` for simple products.

Rules:

- Do not remove `aria-label`, `aria-describedby`, or screen-reader text from `loop/add-to-cart.php`.
- If filtering `woocommerce_loop_add_to_cart_link`, preserve product-specific accessible names.
- Do not replace add-to-cart with a generic "Buy" link for all products.
- Variable/external/grouped products often need a view/select-options flow, not AJAX add-to-cart.

## Images and Grid

Rules:

- Product card images should use `woocommerce_thumbnail`.
- Control catalog image width through Woo theme support or Woo image settings.
- Do not use full-size images in product grids.
- Preserve responsive image attributes generated by Woo/WP.
- Set CSS grid/flex rules so `columns-N` classes do not create overflow.

## Result Count, Ordering, Pagination

Default hooks:

- `woocommerce_before_shop_loop`: notices at 10, result count at 20, ordering at 30.
- `woocommerce_after_shop_loop`: pagination at 10.

Rules:

- Preserve result count and ordering unless the design has a replacement.
- Preserve `woocommerce_output_all_notices` on archives.
- Use Woo pagination; do not manually build `paged` links.
- The pagination template has an accessible `aria-label`.

## Custom Product Sections

For secondary product grids, use Woo product queries carefully.

Rules:

- Prefer Woo shortcodes/blocks only when the theme is intentionally using them.
- For PHP sections, use `wc_get_products()` for product objects or `WP_Query` only when WordPress loop behavior is required.
- If using `WP_Query`, call `wp_reset_postdata()` after the loop.
- Render each product with `wc_get_template_part( 'content', 'product' )` when you want standard card behavior.
- Set loop props such as columns only for the local section and restore expectations afterward.

## Review Checklist

- Archive templates keep Woo wrapper hooks.
- Product loops use Woo loop helpers.
- Product cards preserve product guard, visibility, and `wc_product_class()`.
- Hook changes are preferred over template copies.
- Add-to-cart accessibility attributes are preserved.
- Product images use Woo image sizes.
- Result count, ordering, notices, pagination, and no-products states work.
- Product categories/tags/attributes use Woo taxonomy archive flow.
- No raw price/stock/meta output bypasses `WC_Product` methods.

## Common Mistakes

- Replacing `woocommerce_product_loop_start()` with a custom `<div>` and breaking subcategories/plugins.
- Removing `woocommerce_output_all_notices` from archives.
- Rendering hidden products because the `is_visible()` guard was deleted.
- Losing AJAX add-to-cart classes/data attributes.
- Hardcoding "Add to cart" without product-specific ARIA.
- Using `WP_Query` and forgetting `wp_reset_postdata()`.

## References

- Official documentation: <https://developer.woocommerce.com/docs/theming/theme-development/template-structure/>
- Official documentation: <https://developer.woocommerce.com/docs/theming/theme-development/conditional-tags/>
- Official documentation: <https://developer.woocommerce.com/docs/theming/theme-development/image-sizes/>
- Official documentation: <https://developer.woocommerce.com/docs/theming/theme-development/theme-design-ux-guidelines/>
- Verified source paths:
  - `wp-content/plugins/woocommerce/templates/archive-product.php`
  - `wp-content/plugins/woocommerce/templates/content-product.php`
  - `wp-content/plugins/woocommerce/templates/loop/add-to-cart.php`
  - `wp-content/plugins/woocommerce/templates/loop/loop-start.php`
  - `wp-content/plugins/woocommerce/templates/loop/pagination.php`
  - `wp-content/plugins/woocommerce/includes/wc-template-hooks.php`
  - `wp-content/plugins/woocommerce/includes/wc-template-functions.php`
  - `wp-content/plugins/woocommerce/includes/wc-product-functions.php`

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…