Woo Dynamic Data Tree
Woo product dynamic data is exposed under omewoo on Etch post data when the post is a Woo product.
Use the same tree with different prefixes depending on context:
| Context | Prefix |
|---|---|
| Product archive or product loop | {item.omewoo...} |
| Single product template | {this.omewoo...} |
The examples below use {this.omewoo...}. In a product loop, replace this with item.
Product Tree
| Expression | Type | Meaning |
|---|---|---|
{this.omewoo.productType} | string | Woo product type, such as simple, variable, or variation. |
{this.omewoo.productId} | number | Woo product ID. |
{this.omewoo.priceText} | string | Formatted current product price text. |
{this.omewoo.stockStatus} | string | Woo stock status. |
{this.omewoo.available} | boolean | true when the product is purchasable and in stock. |
{this.omewoo.product.id} | number | Product identity ID. |
{this.omewoo.product.type} | string | Product identity type. Use this for AddToCartForm.product.product_type. |
{this.omewoo.product.sku} | string | Product SKU. |
{this.omewoo.product.name} | string | Product display name. |
The top-level values are convenience aliases. The grouped objects are the more descriptive structure.
Variation Post Context
When the current post is a native Woo product_variation, the base omewoo tree describes the variation itself. Variation posts expose variation-level price, media, purchase, and product identity fields. They do not expose parent selector data through omewoo.attributes or omewoo.variants; those arrays stay empty outside the parent variable product context.
Use parentProduct when a variation template needs the parent product identity:
| Expression | Type | Meaning |
|---|---|---|
{this.omewoo.parentProduct.id} | number | Parent product ID for a variation post. Empty on non-variation products. |
{this.omewoo.parentProduct.type} | string | Parent product type, usually variable. |
{this.omewoo.parentProduct.sku} | string | Parent product SKU. |
{this.omewoo.parentProduct.name} | string | Parent product display name. |
Use selectedAttributes for displayable selected variation attributes:
{#loop this.omewoo.selectedAttributes as attribute}
{attribute.label}: {attribute.valueLabel}
{/loop}
Each selected attribute row has this shape:
| Expression | Type | Meaning |
|---|---|---|
{attribute.key} | string | Store API variation attribute key, such as attribute_pa_color. |
{attribute.taxonomy} | string | Raw Woo taxonomy or local attribute name, such as pa_color or Shoe Size. |
{attribute.label} | string | Human-readable attribute label. |
{attribute.value} | string | Stored selected value, such as blue. |
{attribute.valueLabel} | string | Term name when resolvable, otherwise a readable value fallback. |
selectedAttributesMap is the machine-readable selected value map. It uses the same normalized Store API keys as variant.attributes, for example:
{
"attribute_pa_color": "blue",
"attribute_shoe-size": "large"
}
For author-facing output, prefer the selectedAttributes loop. Use selectedAttributesMap when a template or runtime integration needs normalized selected values by key.
Price Tree
| Expression | Type | Meaning |
|---|---|---|
{this.omewoo.price.currencyCode} | string | Store currency code. |
{this.omewoo.price.currencySymbol} | string | Decoded store currency symbol. |
{this.omewoo.price.raw} | string | Raw Woo price. |
{this.omewoo.price.regular} | string | Raw regular price. |
{this.omewoo.price.sale} | string | Raw sale price. |
{this.omewoo.price.text} | string | Formatted price text. |
{this.omewoo.price.html} | string | Sanitized Woo price HTML, including ranges or sale markup where Woo supplies it. |
{this.omewoo.price.currentHtml} | string | Sanitized server-formatted current price amount. |
{this.omewoo.price.regularHtml} | string | Sanitized server-formatted regular price amount. |
{this.omewoo.price.saleHtml} | string | Sanitized server-formatted sale price amount, or an empty string when there is no sale price. |
Use price.html as the authored content for OmeWooProductPrice. The atom's price_display prop selects the matching HTML field after a variation resolves. The browser never reconstructs currency or tax presentation.
Description Tree
| Expression | Type | Meaning |
|---|---|---|
{this.omewoo.description.html} | string | Full product description after WordPress formatting and sanitization. |
{this.omewoo.description.shortHtml} | string | Short product description after Woo formatting and sanitization. |
Bind either field to OmeWooProductDescription.content. Inside a Product Provider, a resolved variation uses its sanitized variant.description.html and falls back to the authored base content when its own description is empty.
Media Tree
| Expression | Type | Meaning |
|---|---|---|
{this.omewoo.media.image.id} | number | Primary attachment ID, or 0 when no attachment is available. When the product has no featured image, the first valid gallery attachment is promoted. |
{this.omewoo.media.image.url} | string | Full image URL. |
{this.omewoo.media.image.alt} | string | Attachment alt text, falling back to product or variant name. |
{this.omewoo.media.image.title} | string | Attachment title. |
{this.omewoo.media.image.caption} | string | Attachment caption. |
{this.omewoo.media.image.description} | string | Attachment description. |
{this.omewoo.media.image.filename} | string | Image filename. |
{this.omewoo.media.image.srcset} | string | WordPress image srcset. |
{this.omewoo.media.image.width} | number | Full image width. |
{this.omewoo.media.image.height} | number | Full image height. |
{this.omewoo.media.image.filesize} | number | Attachment filesize when available. |
{this.omewoo.media.image.mime_type} | string | Attachment MIME type. |
{this.omewoo.media.image.sizes.full.url} | string | Full-size URL when WordPress provides it. |
{this.omewoo.media.image.sizes.full.width} | number | Full-size width. |
{this.omewoo.media.image.sizes.full.height} | number | Full-size height. |
{this.omewoo.media.gallery} | array | Current product display gallery. The primary image is first, followed by de-duped Woo product gallery images. |
{this.omewoo.media.variationGalleries} | array | Variable-product variation media rows for selector-aware image and gallery UI. Empty on simple products and native variation posts. |
sizes is keyed by registered WordPress image size names. Common keys include thumbnail, medium, large, and full, but the available keys depend on the site.
Each media.gallery row uses the same image shape as media.image, including id, url, alt, title, caption, srcset, dimensions, MIME type, and responsive sizes.
Bind media.image.id to OmeWooProductImage.media_id for a server-rendered hero image and bind the complete media.gallery array to OmeWooProductMedia.media. Inside the Product Media default slot, bind media.id to a nested Product Image. Etch derives registered responsive image output from the attachment ID; leave Product Image alt empty to use the media-library alt text.
Inside the nearest Product Provider, Product Media selection changes only the active image. It does not alter attributes, resolve a variation, mutate the cart, or dispatch ome-woo:variation-selection-changed. Resolving a variation replaces the effective gallery, and reset restores the base product gallery.
On a native Woo product_variation post, media.gallery describes that variation. The variation post context does not expose a parent selector map through media.variationGalleries.
Variation Gallery Rows
Parent variable products expose media-focused variation rows under omewoo.media.variationGalleries. This keeps full gallery payloads out of omewoo.variants, which stays the purchase and selection catalog commonly serialized into AddToCartForm.
Loop target:
{#loop this.omewoo.media.variationGalleries as variationGallery}
...
{/loop}
Each variationGallery row has this shape:
| Expression | Type | Meaning |
|---|---|---|
{variationGallery.variationId} | number | Variation product ID. |
{variationGallery.attributes.attribute_pa_color} | string | Selected value for a variation attribute key. Actual keys depend on the product. |
{variationGallery.image.*} | object | Primary image payload using the same image shape as product omewoo.media.image. |
{variationGallery.gallery} | array | Display gallery for that variation. Each row uses the same image shape as media.image. |
Variation gallery rows mirror Woo's product-image fallback behavior:
- When the parent product has no featured image, its first valid gallery image becomes the base primary image.
- When a variation has no owned images, its gallery uses the parent featured image plus parent gallery images.
- When a variation has only a featured image, that image is first and parent gallery extras follow.
- When a variation has a variation-owned gallery, that gallery is used, with the selected primary image first.
- When a variation has a gallery but no featured image, the first valid variation gallery image becomes the primary image.
Use omewoo.media.variationGalleries for gallery components that need to react to selected attributes. Use omewoo.variants for resolving purchasable variation IDs, availability, price, and form submission data.
Purchase Tree
| Expression | Type | Meaning |
|---|---|---|
{this.omewoo.purchase.available} | boolean | Product can be purchased and is in stock. |
{this.omewoo.purchase.purchasable} | boolean | Woo says the product is purchasable. |
{this.omewoo.purchase.inStock} | boolean | Woo says the product is in stock. |
{this.omewoo.purchase.stockStatus} | string | Woo stock status. |
{this.omewoo.purchase.availabilityHtml} | string | Sanitized Woo availability HTML for the current product. |
{this.omewoo.purchase.quantity.min} | number | Woo minimum purchase quantity. |
{this.omewoo.purchase.quantity.max} | number | null | Woo maximum purchase quantity, including a finite stock limit when applicable. null means unbounded. |
{this.omewoo.purchase.quantity.step} | number | Woo purchase quantity step. Decimal values are preserved. |
{this.omewoo.purchase.quantity.soldIndividually} | boolean | true when Woo fixes the product quantity at one. |
AddToCartForm uses the availability values through its props. A counter AddToCartButton using stepper presentation inside ProductProvider also reads the current product or variation's purchase.quantity object. Authored quantity props can tighten these rules but cannot loosen them. If the product is unavailable, the form disables its submit controls at runtime.
Attribute Tree
Variable products expose variation attributes under omewoo.attributes. Simple products intentionally expose an empty array.
Loop target:
{#loop this.omewoo.attributes as attribute}
...
{/loop}
Each attribute row has this shape:
| Expression | Type | Meaning |
|---|---|---|
{attribute.key} | string | Store API variation attribute key, such as attribute_pa_color. |
{attribute.taxonomy} | string | Woo taxonomy or local attribute name, such as pa_color. |
{attribute.label} | string | Human-readable attribute label. |
{attribute.required} | boolean | Current implementation marks variation attributes as required. |
{attribute.options} | array | Selectable option rows for AttributeSelector. |
AttributeSelector expects the whole attribute object:
<OmeWooAttributeSelector target='{{"attribute":{attribute}}}' />
Attribute Option Tree
Inside an attribute, options are available as attribute.options. AttributeSelector loops this tree internally through props.target.attribute.options, but authors can also inspect it in custom loops.
| Expression | Type | Meaning |
|---|---|---|
{option.label} | string | Option display label. |
{option.value} | string | Option slug sent as the selected variation value. |
{option.variationId} | number | Variation ID when a single-attribute product can map the option to one variant; otherwise 0. |
{option.priceText} | string | Variant price text when available from a single-attribute variant. |
{option.available} | boolean | Whether the option has at least one purchasable matching variation. |
{option.partialAvailable} | boolean | Same partial-selection availability, exposed explicitly for multi-attribute products. |
{option.matchingVariationIds} | array | Purchasable variation IDs that include this option value. |
{option.stockStatus} | string | Mapped single-variation stock status, or the first purchasable partial match stock status. |
{option.image} | object | Image payload using the same image shape as media.image. |
{option.swatchImage.id} | number | Stable variation-owned image ID for an image swatch, or 0 when the complete matching variation set is missing an owned image or uses different images. |
Runtime copies option availability into data-ome-available, data-ome-unavailable, and data-ome-stock-status so unavailable variation choices can disable the parent form. On multi-attribute products, an option is available when at least one purchasable variation can still match that partial selection; the final variation_id is resolved from the complete selection and omewoo.variants.
swatchImage is deliberately smaller and stricter than option.image. It is resolved from every matching variation, including unavailable and wildcard variations, and never falls back to a parent product image. Existing option.image, variant.image, and variant.media.image paths remain unchanged for compatibility. AttributeSelector uses only swatchImage.id to render its Dynamic Image block; Etch derives the responsive image data from that attachment ID.
Variant Tree
Variable products expose all variation payloads under omewoo.variants. Simple products intentionally expose an empty array.
| Expression | Type | Meaning |
|---|---|---|
{variant.id} | number | Variation product ID. |
{variant.label} | string | Label built from selected variation attribute values. |
{variant.sku} | string | Variation SKU. |
{variant.priceText} | string | Formatted variation price text. |
{variant.regularPrice} | string | Raw regular variation price. |
{variant.available} | boolean | Variation can be purchased and is in stock. |
{variant.stockStatus} | string | Variation stock status. |
{variant.product.id} | number | Variation identity ID. |
{variant.product.type} | string | Variation product type. |
{variant.product.sku} | string | Variation SKU from the nested identity object. |
{variant.product.name} | string | Variation display name. |
{variant.price.*} | object | Same price tree as product omewoo.price. |
{variant.description.html} | string | Sanitized Woo variation description. |
{variant.media.image.*} | object | Same image tree as product omewoo.media.image. |
{variant.purchase.*} | object | Same purchase tree as product omewoo.purchase, including variation-specific quantity limits. |
{variant.attributes.attribute_pa_color} | string | Selected value for a variation attribute key. Actual keys depend on the product. |
{variant.image.*} | object | Legacy flat image alias retained for existing dynamic-data consumers. |
variant.media intentionally exposes only image. Full variation galleries live in omewoo.media.variationGalleries so the purchase catalog remains compact when passed into AddToCartForm.
For a two-attribute product such as color plus size, bind both trees into the purchase form:
<OmeWooAddToCartForm product='{{"product_id":"{this.id}","product_type":"{this.omewoo.product.type}","variants":{this.omewoo.variants}}}'>
{#slot default}
{#loop this.omewoo.attributes as attribute}
<OmeWooAttributeSelector target='{{"attribute":{attribute}}}' />
{/loop}
<OmeWooAddToCartButton behavior='{{"trigger":"form_submit"}}' />
{/slot}
</OmeWooAddToCartForm>
Do not read option.variationId as the final variation for multi-attribute products. It is 0 until the selected attribute values map to a complete variation record.
The variation attributes object is keyed by Store API variation attribute names. For taxonomy attributes this is typically attribute_pa_{slug}.
Common Product Bindings
| Use case | Product loop | Single product |
|---|---|---|
| Product ID | {item.id} or {item.omewoo.productId} | {this.id} or {this.omewoo.productId} |
| Product type | {item.omewoo.product.type} | {this.omewoo.product.type} |
| Product image URL | {item.omewoo.media.image.url} | {this.omewoo.media.image.url} |
| Product image alt | {item.omewoo.media.image.alt} | {this.omewoo.media.image.alt} |
| Product gallery loop | item.omewoo.media.gallery | this.omewoo.media.gallery |
| Variation gallery map | item.omewoo.media.variationGalleries | this.omewoo.media.variationGalleries |
| Product price HTML | {item.omewoo.price.html} | {this.omewoo.price.html} |
| Product SKU | {item.omewoo.product.sku} | {this.omewoo.product.sku} |
| Product availability HTML | {item.omewoo.purchase.availabilityHtml} | {this.omewoo.purchase.availabilityHtml} |
| Full product description | {item.omewoo.description.html} | {this.omewoo.description.html} |
| Short product description | {item.omewoo.description.shortHtml} | {this.omewoo.description.shortHtml} |
| Variation attributes loop | item.omewoo.attributes | this.omewoo.attributes |
Use item inside loops and this on single product templates. If this.omewoo.attributes is empty in preview, confirm the preview product is a variable product.
Related Cart Source Trees
These are not under omewoo, but they are the other Woo dynamic sources authors can target directly.
cartItems
Loop target:
{#loop cartItems as item}
...
{/loop}
| Expression | Type | Meaning |
|---|---|---|
{item.key} | string | Woo cart item key. |
{item.productId} | number | Product ID. |
{item.title} | string | Composed title, including selected variation labels when present. |
{item.productTitle} | string | Parent product title. |
{item.titleParts} | array | Title parts used to compose title. |
{item.attributes} | array | Selected cart item attribute rows. |
{item.quantity} | number | Cart item quantity. |
{item.url} | string | Product permalink. |
{item.priceRaw} | string | Raw unit price. |
{item.priceText} | string | Formatted unit price text. |
{item.subtotalRaw} | string | Raw line subtotal. |
{item.subtotalText} | string | Formatted line subtotal text. |
{item.media.image.*} | object | Current item image payload. |
{item.image.*} | object | Legacy flat image alias retained for existing dynamic-data consumers. |
Each item.attributes row has:
| Expression | Type | Meaning |
|---|---|---|
{attribute.key} | string | Attribute taxonomy key. |
{attribute.name} | string | Human-readable attribute name. |
{attribute.taxonomy} | string | Attribute taxonomy. |
{attribute.value} | string | Human-readable selected attribute value. |
cartSummary
| Expression | Type | Meaning |
|---|---|---|
{cartSummary.item_count} | number | Sum of cart quantities. |
{cartSummary.line_count} | number | Number of cart lines. |
{cartSummary.state} | string | has-items or empty. |
cartTotals
| Expression | Type | Meaning |
|---|---|---|
{cartTotals.total_price} | string | Raw final total. |
{cartTotals.totalPriceText} | string | Formatted final total. |
{cartTotals.total_items} | string | Raw subtotal/items total. |
{cartTotals.totalItemsText} | string | Formatted subtotal/items total. |
{cartTotals.total_discount} | string | Raw discount total. |
{cartTotals.totalDiscountText} | string | Formatted discount total. |
{cartTotals.total_shipping} | string | Raw shipping total. |
{cartTotals.totalShippingText} | string | Formatted shipping total. |
{cartTotals.total_tax} | string | Raw tax total. |
{cartTotals.totalTaxText} | string | Formatted tax total. |
The flat fields above are the released legacy lane and remain exact for backward compatibility. They preserve their existing raw values, positive discount representation, and missing-value-to-zero behavior. They are not silently reinterpreted for the store's shopper-facing tax presentation.
cartTotals.cartAmount
cartTotals.cartAmount is the additive canonical lane for OmeWooCartAmount. Its monetary values use Store API minor units and keep direct net and tax fields split:
| Expression | Type | Meaning |
|---|---|---|
{cartTotals.cartAmount.total_items} | string | Items subtotal excluding tax, in minor units. |
{cartTotals.cartAmount.total_items_tax} | string | Tax paired with the items subtotal, in minor units. |
{cartTotals.cartAmount.total_discount} | string | Discount excluding tax, in minor units. Cart Amount supplies the shopper-facing minus sign. |
{cartTotals.cartAmount.total_discount_tax} | string | Tax paired with the discount, in minor units. |
{cartTotals.cartAmount.total_fees} | string | Fees excluding tax, in minor units. |
{cartTotals.cartAmount.total_fees_tax} | string | Tax paired with fees, in minor units. |
{cartTotals.cartAmount.total_shipping} | string or null | Shipping excluding tax, in minor units. null while required shipping is unresolved. |
{cartTotals.cartAmount.total_shipping_tax} | string or null | Tax paired with shipping, in minor units. null while required shipping is unresolved. |
{cartTotals.cartAmount.total_tax} | string | Direct WooCommerce tax total, in minor units. |
{cartTotals.cartAmount.total_price} | string | Direct WooCommerce final total, in minor units. It already contains applicable tax. |
{cartTotals.cartAmount.needs_shipping} | boolean | Whether this cart requires shipping. |
{cartTotals.cartAmount.has_calculated_shipping} | boolean | Whether WooCommerce has calculated shipping. |
{cartTotals.cartAmount.tax_display} | string | Normalized store cart presentation: including_tax or excluding_tax. |
{cartTotals.cartAmount.currency_code} | string | ISO currency code. |
{cartTotals.cartAmount.currency_symbol} | string | Decoded currency symbol. |
{cartTotals.cartAmount.currency_minor_unit} | number | Currency precision used to format minor-unit values. |
{cartTotals.cartAmount.currency_decimal_separator} | string | Decimal separator. |
{cartTotals.cartAmount.currency_thousand_separator} | string | Thousands separator. |
{cartTotals.cartAmount.currency_prefix} | string | Formatted currency prefix. |
{cartTotals.cartAmount.currency_suffix} | string | Formatted currency suffix. |
Cart Amount combines only the matching net/tax pairs for subtotal, discount, fees, and shipping. It reads total_tax and total_price directly and never reconstructs them. In particular, do not add tax to total_price.
A resolved total_shipping="0" means free shipping. Nullable shipping plus required, uncalculated shipping means pending; in that case the direct final total is exposed as estimated rather than guessing a shipping charge. Use OmeWooCartAmount instead of wiring these rules by hand.
cartCoupons
| Expression | Type | Meaning |
|---|---|---|
{coupon.code} | string | Applied coupon code. |
Related Selector Source Trees
shippingRates
Loop target:
{#loop shippingRates as rate}
...
{/loop}
| Expression | Type | Meaning |
|---|---|---|
{rate.key} | string | Package-aware key in {package_id}:{rate_id} form. |
{rate.package_id} | number | Shipping package index or package ID. |
{rate.rate_id} | string | Raw Woo shipping rate ID. |
{rate.name} | string | Shipping rate label. |
{rate.description} | string | Shipping rate description. |
{rate.price} | string | Raw shipping cost. |
{rate.priceText} | string | Formatted shipping cost. |
{rate.selected} | boolean | Whether Woo currently has the rate selected for the package. |
paymentMethods
Loop target:
{#loop paymentMethods as method}
...
{/loop}
| Expression | Type | Meaning |
|---|---|---|
{method.id} | string | Payment gateway ID. |
{method.label} | string | Payment gateway label. |
{method.description} | string | Payment gateway description. |
{method.selected} | boolean | Whether Woo currently has this gateway selected. |
Only enabled simple gateways are included. Gateways with custom embedded fields are skipped by this source.