WooCommerce

Product Loop

Use {{ query:products }} when you want to render WooCommerce product cards in a shop section, landing page, archive, carousel, or category template.

{{ query:product }} is accepted as a singular alias for the same product loop. The examples use products because the loop usually renders more than one product.

Smallest Product Loop#

Start with title, link, and price:

phpresources/views/front-page.php
{{ query:products limit="4" }}  <article>    <a href="{{ url }}">      <h2>{{ title }}</h2>    </a>    <div>{{ price_html }}</div>  </article>{{ else }}  <p>No products are available yet.</p>{{ /query:products }}

Read it like this:

  • {{ query:products }} asks WordPress for WooCommerce product posts.
  • The markup inside the loop repeats once for each product.
  • {{ else }} renders when the query finds no products.
  • {{ title }} and {{ url }} are normal WordPress post values.
  • {{ price_html }} is a WooCommerce product value.

{{ price_html }} is a value tag. It is not a paired tag and should not be written with {{ /price_html }}.

Add Product Images#

Use {{ featured }} or {{ featured_image }} for the main product image URL:

phpresources/views/front-page.php
{{ query:products limit="4" }}  <article>    <a href="{{ url }}">      <img src="{{ featured }}" alt="">      <h2>{{ title }}</h2>    </a>    <div>{{ price_html }}</div>  </article>{{ /query:products }}

Use {{ gallery_images }} when you want the extra images from the WooCommerce Product gallery box:

php
{{ gallery_images }}  <img src="{{ url }}" alt="{{ alt }}">{{ /gallery_images }}

Inside {{ gallery_images }}, {{ url }} is the gallery image URL. Outside that loop, {{ url }} is the product URL.

Product Values#

Inside {{ query:products }} or {{ query:product }}, these common WooCommerce values are available:

ValueGood for
product_idHidden inputs, labels, and debugging.
pricePlain product price value.
regular_priceRegular price.
sale_priceSale price.
discountDiscount percentage as a number, such as 20 for 20% off.
price_htmlWooCommerce formatted price HTML.
skuSKU text.
stock_statusRaw stock status.
stock_quantityStock quantity when WooCommerce exposes one.
in_stockConditional checks.
on_saleSale badges.
purchasableChecks before showing purchase UI.
typeProduct type, such as simple or variable.
descriptionProduct description HTML.
short_descriptionShort product description HTML.
average_ratingRating number.
rating_htmlWooCommerce rating HTML.

Raw price values stay numeric. Use {{ price | currency }}, {{ regular_price | currency }}, or {{ sale_price | currency }} when you want WooCommerce currency formatting. Use {{ discount | percent }} when you want the discount rendered as 20%.

Common checks:

php
{{ if on_sale }}  <span>Sale</span>{{ /if }}{{ if in_stock }}  <span>In stock</span>{{ else }}  <span>Out of stock</span>{{ /if }}

For variable products, {{ price }}, {{ regular_price }}, and {{ sale_price }} use WooCommerce's lowest matching variation prices before a variation is selected. See Product Loop With Variations when the card needs selectable options.

Categories And Tags#

Product categories and tags are collections:

php
{{ query:products limit="6" }}  <article>    <h2>{{ title }}</h2>    <nav aria-label="Product categories">      {{ categories }}        <a href="{{ url }}">{{ name }}</a>      {{ else }}        <span>Uncategorized</span>      {{ /categories }}    </nav>  </article>{{ /query:products }}

Category and tag values:

ValuePrints
idTerm ID.
name or titleTerm name.
slugTerm slug.
urlTerm archive URL.
countNumber of products in the term.

Product Archive And Category Templates#

Use WordPress template names for WooCommerce archives:

      • archive-product.php
      • taxonomy-product_cat.php
      • taxonomy-product_cat-dames.php

Inside taxonomy-product_cat.php and taxonomy-product_cat-{slug}.php, {{ query:products }} automatically inherits the current product category unless you provide your own taxonomy:product_cat filter.

phpresources/views/taxonomy-product_cat.php
<section>  <h1>{{ category_name }}</h1>  {{ query:products limit="12" }}    <article>      <a href="{{ url }}">        <img src="{{ featured }}" alt="">        <h2>{{ title }}</h2>      </a>      <div>{{ price_html }}</div>    </article>  {{ /query:products }}</section>

Use {{ category_name }} outside the product loop for the current product category name. Inside the loop, {{ title }} is the product title.

Query Options#

Use limit for the number of products:

php
{{ query:products limit="12" }}  <h2>{{ title }}</h2>{{ /query:products }}

Without limit, TemplateX asks for all matching products.

Filter by product category or tag:

php
{{ query:products taxonomy:product_cat="shirts" limit="8" }}  <h2>{{ title }}</h2>{{ /query:products }}

Available WooCommerce taxonomy options:

TaxonomyUse
product_catProduct categories.
product_tagProduct tags.

Use a pipe when the query should match more than one term:

php
{{ query:products taxonomy:product_cat="shirts|hoodies" limit="8" }}  <h2>{{ title }}</h2>{{ /query:products }}

You can sort products with the shared query sort option:

php
{{ query:products sort="title:asc" limit="12" }}  <h2>{{ title }}</h2>{{ /query:products }}

Useful sort examples:

SortResult
date:descNewest products first.
title:ascAlphabetical products.
randomRandom products.
order:ascWordPress menu order.

For WooCommerce's native archive sorting, result counts, layered navigation, and pagination, use WooCommerce archive templates or WooCommerce blocks. {{ query:products }} is best for theme-owned product sections.