Product Contexts#
Product values and product collections are available in:
{{ query:products }}...{{ /query:products }}{{ query:product }}...{{ /query:product }}as a singular aliasresources/views/archive-product.phpresources/views/taxonomy-product_cat.phpresources/views/taxonomy-product_cat-{slug}.phpresources/views/single-product.php- Any path that ends with
/single-product.php resources/views/woocommerce/single-product.php- Files under
resources/views/woocommerce/single-product/
Use product values such as {{ price_html }} only in those contexts.
In taxonomy-product_cat.php and taxonomy-product_cat-{slug}.php, {{ query:product }} and {{ query:products }} inherit the current product category automatically. Use {{ category_name }} outside the product loop for the current category name; inside the loop, {{ title }} is the product title.
Product category archive filenames must use WordPress taxonomy hierarchy names:
| File | Applies to |
|---|---|
taxonomy-product_cat-dames.php | Only the dames product category. |
taxonomy-product_cat.php | Every WooCommerce product category. |
archive-product.php | Product archive/shop fallback. |
page-dames.php is for a WordPress page with the slug dames. category-dames.php is for normal blog post categories. Neither one targets WooCommerce product category archives.
Product Category URLs#
By default, WooCommerce product URLs use a fixed product base such as:
/product/notre-v/TemplateX can opt into category-path product URLs from TemplateX > Settings > WooCommerce. Turn on Product URLs From Categories to generate product links from WooCommerce product categories:
/dames/hakken/notre-v/For that example, the product is assigned to the hakken product category, and hakken is a child of dames.
TemplateX saves WooCommerce's native product permalink setting with the custom base /%product_cat%. WooCommerce then registers the product rewrite rules and fills the category placeholder in product links.
Products assigned to multiple categories use the category WooCommerce chooses for the product permalink, normally the deepest category path. Wrong category paths for an existing product are left for WooCommerce's canonical redirect behavior.
The normal WooCommerce Permalinks screen treats that exact root-level category base as invalid and rewrites it to /product/%product_cat%, so use the TemplateX toggle when the site intentionally wants no fixed product base.
This setting removes the fixed /product/ base, so URL paths need to stay unambiguous. Avoid creating a page, product category, and product that would all want the same path. After changing the setting, TemplateX flushes rewrite rules. Add 301 redirects yourself for any old product URLs that are already indexed or shared externally.
Product Tags And Values#
| Syntax | Kind | Use |
|---|---|---|
{{ query:products }}...{{ /query:products }} | Paired tag | Loop over products. |
{{ query:product }}...{{ /query:product }} | Paired tag | Singular alias for the product loop. |
{{ cart:add }}...{{ /cart:add }} | Paired tag | Render an add-to-cart form for the current product. |
{{ product:image }} | Value tag | Render the current product image and update it when a variation is selected. |
{{ images }}...{{ /images }} | Paired tag | Loop over all product images, with the featured image first. |
{{ gallery_images }}...{{ /gallery_images }} | Paired tag | Loop over only WooCommerce gallery images. |
{{ categories }}...{{ /categories }} | Paired tag | Loop over product categories. |
{{ tags }}...{{ /tags }} | Paired tag | Loop over product tags. |
{{ attributes }}...{{ /attributes }} | Paired tag | Loop over product attributes. |
{{ options }}...{{ /options }} | Paired tag | Loop over product variation options. |
{{ variations }}...{{ /variations }} | Paired tag | Loop over available variation data. |
{{ variation:select for="attribute" }} | Value tag | Render a select control for one variation attribute. |
{{ variation:pills for="attribute" }}...{{ /variation:pills }} | Paired tag | Render pill choices for one variation attribute. |
{{ variation:radios for="attribute" }}...{{ /variation:radios }} | Paired tag | Render radio-style choices for one variation attribute. |
Product value tags:
| Value | Notes |
|---|---|
product_id | WooCommerce product ID. |
price | Raw price value. |
regular_price | Regular price. |
sale_price | Sale price. |
discount | Discount percentage as a number, such as 20 for 20% off. |
price_html | WooCommerce formatted price HTML. |
sku | SKU. |
stock_status | Raw stock status. |
stock_quantity | Stock quantity. |
in_stock | Useful in conditionals. |
on_sale | Useful in conditionals. |
purchasable | Useful before showing purchase UI. |
type | Product type. |
description | Product description HTML. |
short_description | Short description HTML. |
average_rating | Rating number. |
rating_count | Rating count. |
review_count | Review count. |
rating_html | WooCommerce rating HTML. |
weight | Product weight. |
dimensions | Product dimensions. |
These are value tags. Do not add closing tags to them.
Raw price values are numeric. Use {{ price | currency }}, {{ regular_price | currency }}, or {{ sale_price | currency }} for WooCommerce currency formatting. Use {{ discount | percent }} to render a numeric discount as a percentage.
When a selected variation has its own description or short_description, that variation text is used. When the variation description is empty, TemplateX falls back to the parent product description.
Add-to-cart arguments:
| Argument | Notes |
|---|---|
open_cart | Use open_cart to open the first available cart drawer when the form submits. |
variation_url | Use variation_url to keep the current URL in sync with the selected variation and restore that variation from shared URLs. |
Product image arguments:
| Argument | Notes |
|---|---|
class | Applied to the generated <img>. |
size | WordPress image size to request. Default is full. Not rendered as an HTML attribute. |
alt | Optional alt text override. If omitted, TemplateX uses the attachment alt text. |
| Any valid image attribute | Passed through to the generated <img>, for example loading, decoding, or fetchpriority. |
Variation control arguments:
| Argument | Tags | Notes |
|---|---|---|
for | All variation controls | Attribute slug, taxonomy name, submitted input name, or label. |
attribute | All variation controls | Alias for for. |
class | All variation controls | Applied to the select or each generated choice button. |
active_class | variation:pills, variation:radios | Added when a choice is selected. |
selected_class | variation:pills, variation:radios | Alias for active_class. |
unavailable_class | variation:pills, variation:radios | Added when a choice is out of stock or otherwise unavailable. Hover variant classes and cursor-pointer are removed for unavailable choices. |
disabled_class | variation:pills, variation:radios | Alias for unavailable_class. |
non_active_class or inactive_class | variation:pills, variation:radios | Alias for unavailable_class. Prefer unavailable_class so the state is not confused with an unselected choice. |
unavailable | All variation controls | disable, hide, or show. Default is disable. |
placeholder | variation:select | Optional empty first option. |
image | variation:pills, variation:radios | Use variation or auto to expose variation image values; use none to skip images. |
Choice values inside variation:pills and variation:radios:
| Value | Notes |
|---|---|
label | Human label. |
value | Submitted WooCommerce value. |
slug | Sanitized slug. |
selected | Whether the choice is currently selected. |
available | Whether at least one matching variation is in stock and purchasable. |
image.src, image.alt, image.width, image.height | Variation image data when available. |
price, regular_price, sale_price, discount, price_html | Matching variation price data. |
sku, stock_status, stock_quantity | Matching variation inventory data. |
prices.min, prices.max, prices.html | Aggregate price data when multiple variations match a choice. |
variations | Matching variation rows for advanced output. |
Cart Tags And Values#
| Syntax | Kind | Use |
|---|---|---|
{{ cart }}...{{ /cart }} | Paired tag | Start a cart context. |
{{ cart:items }}...{{ /cart:items }} | Paired tag | Loop over cart items. |
{{ cart:trigger }}...{{ /cart:trigger }} | Paired tag | Render a cart drawer trigger button. |
{{ cart:overlay }}...{{ /cart:overlay }} | Paired tag | Render a cart drawer overlay. |
{{ cart:panel }}...{{ /cart:panel }} | Paired tag | Render a drawer panel. |
{{ cart:close }}...{{ /cart:close }} | Paired tag | Render a drawer close button. |
{{ cart:update }}...{{ /cart:update }} | Paired tag | Render an item quantity update form. |
{{ cart:remove }}...{{ /cart:remove }} | Paired tag | Render an item remove form. |
{{ coupon }}...{{ /coupon }} | Paired tag | Render a coupon form. |
{{ notices }} | Value tag | Print WooCommerce notices. |
Cart value tags inside {{ cart }}:
| Value | Notes |
|---|---|
count or item_count | Cart item count. |
cart_url | Cart page URL. |
checkout_url | Checkout page URL. |
subtotal | Formatted subtotal. |
total | Formatted total. |
Cart drawer triggers open on click by default. Add open_on="hover" or the shorthand hover to {{ cart:trigger }} when the drawer should also open on hover. Open drawers close with {{ cart:close }}, Escape, backdrop clicks, or any click outside the active overlay.
Cart item value tags inside {{ cart:items }}:
| Value | Notes |
|---|---|
key | Cart item key. |
product_id | Product ID. |
title | Product title. |
url or permalink | Product URL. Variation cart items include variation_id and selected attribute_* query parameters. |
quantity | Quantity. |
price | Formatted unit price. |
line_total | Formatted line total. |
line_subtotal | Formatted line subtotal. |
product_image, featured_image, featured, or image_url | Image URL. |
thumbnail_url | Thumbnail URL. |
thumbnail or image | WooCommerce image HTML. |
remove_url | Remove URL. |
Checkout Tags And Values#
| Syntax | Kind | Use |
|---|---|---|
{{ checkout }} | Value tag | Render WooCommerce's full checkout. |
{{ checkout }}...{{ /checkout }} | Paired tag | Start a custom checkout context. |
{{ checkout:form }}...{{ /checkout:form }} | Paired tag | Render the checkout form. |
{{ checkout:billing }}...{{ /checkout:billing }} | Paired tag | Loop over billing fields. |
{{ checkout:shipping }}...{{ /checkout:shipping }} | Paired tag | Loop over shipping fields. |
{{ checkout:account }}...{{ /checkout:account }} | Paired tag | Loop over account fields. |
{{ checkout:order_fields }}...{{ /checkout:order_fields }} | Paired tag | Loop over order note fields. |
{{ checkout:fields group="billing" }}...{{ /checkout:fields }} | Paired tag | Loop over an explicit field group. |
{{ checkout:order }} | Value tag | Print order review. |
{{ checkout:payment }} | Value tag | Print payment methods. |
{{ checkout:submit }}...{{ /checkout:submit }} | Paired tag | Render the place-order button. |
Checkout field value tags:
| Value | Notes |
|---|---|
key | Field key. |
id | Field ID. |
name | Input name. |
type | Field type. |
label | Label text. |
placeholder | Placeholder text. |
description | Description text. |
required | Required flag. |
value | Current value. |
priority | Field priority. |
class | Field wrapper classes. |
input_class | Input classes. |
label_class | Label classes. |
autocomplete | Autocomplete value. |
options | Select option collection. |
input | Input markup only. |
field | Full WooCommerce field markup. |
{{ input }} and {{ field }} are value tags. Do not write closing tags for them.
Native Page Tags#
| Syntax | Kind | Use |
|---|---|---|
{{ my_account }} | Value tag | Print WooCommerce My Account output. |
{{ order_pay }} | Value tag | Print WooCommerce order payment output. |
{{ order_received }} | Value tag | Print WooCommerce order received output. |
{{ notices }} | Value tag | Print WooCommerce notices. |
Kebab-case aliases also work for the native page tags:
{{ my-account }}{{ order-pay }}{{ order-received }}Email Template Overrides#
WooCommerce email overrides use native WooCommerce template paths under resources/views/woocommerce/emails/:
- customer-completed-order.php
- email-header.php
- email-footer.php
- email-styles.php
Those files compile and publish to the theme's native woocommerce/emails/ folder.
Common WooCommerce email variables:
| Variable | Notes |
|---|---|
$order | The WC_Order object for order emails. |
$email_heading | The configured email heading. |
$sent_to_admin | Whether this email is for the store admin. |
$plain_text | Whether WooCommerce is rendering the plain text version. |
$email | The WooCommerce email object. |
Email overrides are not product loop, cart, checkout, or account contexts. Use WooCommerce's email variables and hooks for order content.
Common Problems#
Product values print blank#
Check that the template is inside a product context. {{ price_html }} works inside {{ query:products }} and product-aware single product paths. It does not work on a normal page unless you first query products.
Product lists show everything#
Add limit:
{{ query:products limit="8" }} <h2>{{ title }}</h2>{{ /query:products }}Without limit, TemplateX asks WordPress for all matching products.
Add to cart does not render#
{{ cart:add }} needs a current product. Move it inside {{ query:products }} or a single product template.
Variable products do not choose a variation#
Prefer the generated variation controls inside {{ cart:add }}:
{{ variation:pills for="maat" }} {{ label }}{{ /variation:pills }}{{ variation:select for="kleur" placeholder="Choose color" }}TemplateX handles the WooCommerce field names, submitted values, and selected variation ID.
If you use raw {{ options }} loops instead, select controls should use name="{{ name }}". Radio controls inside {{ values }} should use name="{{ parent.name }}" and value="{{ value }}".
If selected variation values do not appear, make sure visible product values such as {{ price_html }}, {{ price }}, or {{ sale_price }} are printed near the matching {{ cart:add }} form.
Cart update or remove controls behave strangely#
{{ cart:update }} and {{ cart:remove }} render forms. Do not place them inside another form.
Checkout payment methods are missing#
Use plain {{ checkout }} first. If you use a custom checkout layout, include {{ checkout:payment }} inside {{ checkout:form }}.
WooCommerce notices disappear#
Use one clear {{ notices }} location per page. WooCommerce can clear notices after rendering them.