Item Options
{exp:cartthrob:item_options} outputs option groups for a product or cart row and helps render the correct form inputs for selecting/updating those options.
This tag is commonly used in:
- product detail templates (
entry_idmode) - cart/update templates (
row_idmode) - package sub-item editing (
row_idlikeparent_row:sub_row)
See also:
Parameters
entry_id
Product entry ID used to load price-modifier options from channel data.
Use this when rendering options before the item is in the cart.
entry_id="123"
row_id
Cart row ID used to load selected/dynamic options for a specific cart item.
Use this when rendering options for cart updates.
row_id="{row_id}"
Sub-item/package rows are supported with parent_row:sub_row format.
row_id="{sub:row_id}"
At least one of entry_id or row_id is required. If both are missing, the tag returns no-results output.
field
Limit output to one or more option fields (pipe-delimited).
field="product_size|product_color"
search:option_name
Filter option rows by displayed option name when building option lists.
search:option_name="Small|Medium"
search:selected
Set to yes to return only the choice currently selected on the cart row
inside each options, list, or select pair. Use this with row_id when
displaying a cart item’s Configurator selections.
search:selected="yes"
Variables
Each item_options loop iteration represents one option field/group.
- option_field
- option_label
- configuration_label
- field_type
- option_value
- dynamic
- options_exist
- allow_selection
- input
- item_options_total_results
- item_options_count
option_field
Field short name for the option group.
product_size
option_label
Human-readable label for the option group.
If no label is found in field metadata, CartThrob falls back to stored custom labels or a humanized field name.
Product Size
Alias also available:
{item_options:option_label}
configuration_label
Used for configurator-style price modifier fields (top-level configurator label).
Configurable Item
field_type
CartThrob field type for this option field (for example configurator field types).
cartthrob_price_modifiers
option_value
Currently selected/stored value for this option field (if available).
L
dynamic
1 when the option field is dynamic (not defined as a standard price modifier for this entry), otherwise 0.
{if dynamic}This option was added on the fly{/if}
options_exist
True when this option field has configured selectable options in price modifiers.
Use this to hide empty dropdown sections.
{if options_exist}...{/if}
allow_selection
For package/edit contexts, indicates whether this field can be edited (1) or should be display-only (0).
input
Auto-generated <input> element with correct name and current value.
It uses item_options[field] names for entry mode, and item_options[row_id][field] names for row mode.
{input}
item_options_total_results
Total number of option groups returned by this tag call.
{item_options_total_results}
item_options_count
1-based counter for the current option group.
{item_options_count}
Example:
{if "{item_options_count}" == "1"}
Show this once at the top
{/if}
Variable Pairs
options
Freeform pair that outputs one row per available choice.
{options}
{option_value}: {option_name} {price}
{/options}
list
Alias of options (same row data, different naming style in templates).
{list}
{option_name} ({option_value})
{/list}
Option-row variables available in options/list/select pairs:
option,option_value,option_nameselected(HTML attribute string),checked(HTML attribute string)option_selected(1/0 boolean-style helper)price,option_priceprice:numeric,price_numericprice:plus_tax,price:plus_tax_numeric,price_numeric:plus_taxoption_price:numeric,option_price_numericoption_price:plus_tax,option_price_plus_taxtaxed_price,option_taxed_priceweight,option_weightoption_count,option_total_results,option_first_row,option_last_rowinput_name,option_field,dynamic- custom columns from price modifier rows (if configured)
When the mapped modifier field includes an inventory column,
{inventory} is available as one of those custom columns:
- a positive value means that many units are available;
0means the option is out of stock;- a missing inventory column,
null, or a blank value means unlimited inventory.
For the standard Price Modifiers fieldtype, this is the inventory of that option row. The modifier field must be the product channel’s mapped Inventory field for CartThrob to validate and reduce it. An entry with no option rows is unlimited. Once rows exist, a missing or unknown submitted selection is invalid.
The
Price Modifiers Configurator
tracks inventory on each complete generated configuration/SKU, not on
the individual option-group choices rendered by item_options. For
example, Large + Green can have inventory, but Green alone does not
have one shared inventory value.
The option-row value is useful for labeling or disabling a choice, but the Add to Cart action remains authoritative and validates the submitted option and quantity on the server.
Configurator option groups use generated field names in this form:
configuration:CONFIGURATOR_FIELD_SHORT_NAME:OPTION_GROUP_SHORT_NAME
The generated {select} or {input} uses that complete name under
item_options[...]. Keep it intact; posting only the Configurator field short
name does not identify the customer’s individual group selections.
select
Generates a <select> wrapper automatically and parses your option markup inside it.
{select}
<option {selected} value="{option_value}">{option_name} {price}</option>
{/select}
You can pass HTML attributes to generated controls in tag parameters:
class,id,onchangeattr:*for custom attributes
Examples:
{select class="input-medium" attr:data-role="item-option"}
<option {selected} value="{option_value}">{option_name}</option>
{/select}
{input type="text" class="input-medium" attr:data-role="item-option-input"}
Conditionals
{if dynamic}
True when option field is dynamic (on-the-fly field, not a configured modifier field).
{if dynamic}...{/if}
{if option_field}
Checks whether option_field has a value.
{if option_field}...{/if}
{if option_label}
Checks whether option_label has a value.
{if option_label}...{/if}
{if options_exist}
True when the current option group has configured selectable values.
{if options_exist}...{/if}
{if allow_selection}
Useful for package/edit flows where some sub-item options are not editable.
{if allow_selection}...{/if}
Examples
Product page (entry mode)
{exp:cartthrob:item_options entry_id="{entry_id}"}
{if dynamic}
<label>{option_label}</label>
{input}
{if:else}
{if options_exist}
<label>{option_label}</label>
{select}
<option {selected} value="{option_value}">
{option_name}{if option_price_numeric != 0} +{option_price}{/if}
</option>
{/select}
{/if}
{/if}
{/exp:cartthrob:item_options}
For a Price Modifiers Configurator, the same loop outputs each generated group
separately—for example Color and Size—and gives each control the required
configuration:FIELD:GROUP name. Do not manually concatenate every option
label or value into one <option>.
Product options with stock status
Use this inside the product’s add_to_cart_form:
{exp:cartthrob:item_options entry_id="{entry_id}" field="product_size"}
<label>{option_label}</label>
{select}
<option
value="{option_value}"
{selected}
{if inventory == "0"}disabled{/if}
>
{option_name}
{if inventory == "0"} — Out of stock{/if}
{if inventory} — {inventory} available{/if}
</option>
{/select}
{/exp:cartthrob:item_options}
A missing or blank {inventory} value deliberately remains selectable
because only an explicit numeric value activates modifier stock
tracking. An entry with no modifier rows is likewise unlimited. If
every modifier option is explicitly unavailable, the product-level
is_in_stock tag also reports the
product as out of stock.
Cart update (row mode)
{exp:cartthrob:item_options row_id="{row_id}"}
{if options_exist}
<label>{option_label}</label>
{select}
<option {selected} value="{option_value}">
{option_name}{if option_price_numeric != 0} +{option_price}{/if}
</option>
{/select}
{if:else}
<label>{option_label}</label>
{input}
{/if}
{/exp:cartthrob:item_options}
Display selected Configurator values in the cart
Use the current cart row ID and filter each option pair to its selected value:
{exp:cartthrob:item_options row_id="{row_id}" search:selected="yes"}
<p>
<strong>{option_label}:</strong>
{if options_exist}
{options}{option_name}{/options}
{if:else}
{option_value}
{/if}
</p>
{/exp:cartthrob:item_options}
For a Configurator, {option_label} is the group label such as Color or Size.
The raw selected value is also exposed by cart_items_info as
{item_options:configuration:FIELD:GROUP} when the generated name is known.
Package sub-item option editing
{package}
<h5>{sub:title}</h5>
{exp:cartthrob:item_options row_id="{sub:row_id}"}
{if options_exist}
{if allow_selection}
<label>{option_label}</label>
{select}
<option {selected} value="{option_value}">{option_name}</option>
{/select}
{if:else}
{options}
{if selected}{option_label}: {option_name}{/if}
{/options}
{/if}
{/if}
{/exp:cartthrob:item_options}
{/package}
Filter to specific option fields
{exp:cartthrob:item_options row_id="{row_id}" field="product_size|product_color"}
<label>{option_label}</label>
{select}
<option {selected} value="{option_value}">{option_name}</option>
{/select}
{/exp:cartthrob:item_options}
Freeform option listing
{exp:cartthrob:item_options row_id="{row_id}"}
{options}
{if option_first_row}<strong>{option_field}</strong><br />{/if}
{option_name} ({option_value}) {price}<br />
{/options}
{/exp:cartthrob:item_options}