
msProductOptions
Extended snippet for outputting all or filtered product options with full information for each (metadata, categories, types).
Parameters
| Parameter | Default | Description |
|---|---|---|
| product | current resource | Product ID |
| tpl | tpl.msProductOptions | Layout chunk |
| onlyOptions | Output only the specified options (comma-separated) | |
| ignoreOptions | Ignore the specified options | |
| groups | Output only options from the specified groups | |
| ignoreGroups | Ignore the specified groups | |
| sortOptions | Option sort order (comma-separated) | |
| sortGroups | Group sort order (comma-separated) | |
| sortOptionValues | Sort values within options (see msOptions) | |
| return | tpl | Output format: tpl, data, array |
Auto sort
If onlyOptions is set but sortOptions is not, options are automatically sorted in the order given in onlyOptions.
Deprecated parameters
Backward compatibility
The &input parameter is deprecated. Use &product.
Examples
All product options
{'msProductOptions' | snippet}For a specific product
{'msProductOptions' | snippet: [
'product' => 15
]}Only certain options
{'msProductOptions' | snippet: [
'onlyOptions' => 'color,size,material,weight'
]}Exclude options
{'msProductOptions' | snippet: [
'ignoreOptions' => 'internal_code,supplier_id'
]}Only from certain groups
{'msProductOptions' | snippet: [
'groups' => 'Main,Dimensions'
]}With group and option sorting
{'msProductOptions' | snippet: [
'sortGroups' => 'Main,Dimensions,Additional',
'sortOptions' => 'weight,dimensions,material,color'
]}Return data for processing
{set $options = 'msProductOptions' | snippet: [
'return' => 'data'
]}
{foreach $options as $key => $option}
<div class="option">
<strong>{$option.caption}:</strong>
{if $option.value is array}
{$option.value | join: ', '}
{else}
{$option.value}
{/if}
</div>
{/foreach}Data structure
With return=data or return=array, an associative array is returned where the key is the option name:
[
'color' => [
'caption' => 'Color',
'value' => ['Red', 'Blue'],
'category' => 'main',
'group_name' => 'Main specs',
'type' => 'combo-options',
'properties' => [...]
],
'size' => [
'caption' => 'Size',
'value' => 'M',
'category' => 'main',
'group_name' => 'Main specs'
],
'weight' => [
'caption' => 'Weight',
'value' => '250 g',
'category' => 'specs',
'group_name' => 'Specs'
]
]Option key
The option name (color, size, weight) is the array key, not a field inside the option. To access it, use {foreach $options as $key => $option}.
Placeholders in chunk
| Placeholder | Description |
|---|---|
{$options} | Associative array of product options |
Fields per option
| Field | Description |
|---|---|
{$option.caption} | Option label (human-readable) |
{$option.value} | Value (string or array) |
{$option.category} | Option group key |
{$option.group_name} | Group name |
{$option.type} | Field type (textfield, combo-options, etc.) |
{$option.properties} | Additional option properties |
Use foreach to get the option key:
{foreach $options as $key => $option}
{* $key = 'color', 'size', etc. *}
<div data-option="{$key}">{$option.caption}: {$option.value}</div>
{/foreach}Default chunk
The default chunk tpl.msProductOptions outputs options as rows:
{* tpl.msProductOptions *}
{foreach $options as $option}
<div class="form-group row align-items-center">
<label class="col-6 col-md-3 text-right text-md-left col-form-label">
{$option.caption}:
</label>
<div class="col-6 col-md-9">
{if $option.value is array}
{$option.value | join: ', '}
{else}
{$option.value}
{/if}
</div>
</div>
{/foreach}Alternative chunk — table
{* tpl.msProductOptions.table *}
{if $options?}
<table class="product-options">
<tbody>
{foreach $options as $option}
<tr>
<th>{$option.caption}</th>
<td>
{if $option.value is array}
{$option.value | join: ', '}
{else}
{$option.value}
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
{/if}Grouping by category
{* tpl.msProductOptions.grouped *}
{if $options?}
{set $grouped = []}
{* Group options by category *}
{foreach $options as $option}
{set $cat = $option.group_name ?: 'Main'}
{set $grouped[$cat][] = $option}
{/foreach}
{* Output grouped options *}
{foreach $grouped as $groupName => $groupOptions}
<div class="options-group">
<h4>{$groupName}</h4>
<table>
{foreach $groupOptions as $option}
<tr>
<th>{$option.caption}</th>
<td>
{if $option.value is array}
{$option.value | join: ', '}
{else}
{$option.value}
{/if}
</td>
</tr>
{/foreach}
</table>
</div>
{/foreach}
{/if}Selecting options when adding to cart
When options are selectable (for example, color and size):
<form class="product-form">
{set $options = 'msProductOptions' | snippet: [
'return' => 'data',
'onlyOptions' => 'color,size'
]}
{foreach $options as $key => $option}
<div class="form-group">
<label>{$option.caption}</label>
<select name="options[{$key}]" required>
<option value="">Select {$option.caption | lower}</option>
{if $option.value is array}
{foreach $option.value as $val}
<option value="{$val}">{$val}</option>
{/foreach}
{/if}
</select>
</div>
{/foreach}
<button type="button"
data-ms-action="cart/add"
data-id="{$_modx->resource.id}">
Add to cart
</button>
</form>When to use
| Suitable | Not suitable |
|---|---|
| You need ALL product options | Only 2–3 specific options needed |
| Metadata is required | Maximum speed matters |
| Filtering by groups | Simple fixed list |
| Flexible sorting is required | |
| Options are built dynamically |
For simple output of specific options without metadata, use msOptions.
