The configurator renders from wp.template markup printed into the page as
<script type="text/html"> blocks. These hooks let you add to that markup, or change the
attributes and classes it carries.
They are ordinary PHP actions and filters, but what they print is Underscore template syntax
evaluated later in the browser — {{ }} escapes, {{{ }}} does not, and <# #> is JavaScript.
See Template hooks are different.
Everything here runs once, when the templates are printed. It does not run per choice — the same markup is reused for every choice in the configurator, so anything conditional has to be expressed in template syntax rather than in PHP.
The main view
| Hook | Type | Purpose |
|---|---|---|
mkl_pc_frontend_templates_before | action | Before any template part is included |
mkl_pc_frontend_templates_after | action | After all of them |
mkl_pc_frontend_templates_parts | filter | The list of template part files to include |
mkl_pc_frontend_configurator__main_view | action | Inside the configurator's root template |
mkl_pc_container | action | Inside .mkl_pc_container |
Viewer
| Hook | Type | Purpose |
|---|---|---|
mkl_pc_layers_before | action | Before the layers container |
mkl_pc_layers | action | Inside .mkl_pc_layers |
mkl_pc_layers_after | action | After the layers container |
mkl_pc_templates_empty_viewer | action | Inside the empty-viewer template |
Toolbar and footer
| Hook | Type | Purpose |
|---|---|---|
mkl_pc_frontend_configurator_toolbar | action | Inside the toolbar template |
mkl_pc_frontend_configurator_footer_section_left_before | action | Before the left footer section |
mkl_pc_frontend_configurator_footer_section_left_inner_before | action | Inside it, first |
mkl_pc_frontend_configurator_footer_section_left_inner | action | Inside it |
mkl_pc_frontend_configurator_footer_section_left_inner_after | action | Inside it, last |
mkl_pc_frontend_configurator_footer_section_right_before | action | Before the right footer section |
mkl_pc_frontend_configurator_footer_form_before | action | Before the cart form |
mkl_pc_frontend_configurator_footer_form | action | Inside the cart form |
mkl_pc_frontend_configurator_footer_form_after | action | After the cart form |
mkl_pc_frontend_configurator_footer_after | action | After the whole footer |
mkl_pc_reset_button_classes | filter | Classes on the reset button |
mkl_pc/reset_button/before_label | action | Inside the reset button, before its label |
Steps
| Hook | Type | Purpose |
|---|---|---|
mkl_pc/previous_step/button_classes | filter | Classes on the previous-step button |
mkl_pc/previous_step/before | action | Inside it, before the label |
mkl_pc/previous_step/after | action | Inside it, after the label |
mkl_pc/next_step/button_classes | filter | Classes on the next-step button |
mkl_pc/next_step/before | action | Inside it, before the label |
mkl_pc/next_step/after | action | Inside it, after the label |
Layers and choices
| Hook | Type | Purpose |
|---|---|---|
tmpl-mkl-pc-configurator-layer-item-button | action | Inside a layer button |
mkl_pc_layer_thumbnail_alt | filter | alt text on a layer thumbnail |
mkl-pc-configurator-layer-item.with.button | JS filter | Whether a layer renders as <button> or <span> |
mkl-pc-configurator-choices--after | action | End of the choices list template |
tmpl-pc-configurator-choice-item-attributes | action | Extra attributes on a choice button |
mkl_pc_choice_items_attributes | filter | The attribute array for a choice item |
tmpl-pc-configurator-choice-item | action | Inside a choice button |
tmpl-pc-configurator-choice-item--after | action | After a choice button |
tmpl-pc-configurator-choice-item-label | filter | The choice name expression |
tmpl-pc-configurator-choice-group-item--before | action | Before a choice group |
tmpl-pc-configurator-choice-group-item--after | action | After a choice group |
Summary and add to cart
| Hook | Type | Purpose |
|---|---|---|
mkl_pc_frontend_configurator_summary | action | Inside the summary template |
tmpl-mkl-pc-configurator-add-to-cart--modal | action | Inside the add-to-cart modal |
tmpl-mkl-pc-atc-added | action | The "added to cart" state |
tmpl-mkl-pc-atc-redirection-content | action | The redirection state |
tmpl-pc-configurator-choice-item and tmpl-pc-configurator-choice-item--after
The two you will use most. The first prints inside the choice's <button>, the second
after it — which matters, because markup inside a button cannot contain interactive elements.
Core itself uses the first at three priorities: thumbnail at 5, name at 10, description at 50.
add_action( 'tmpl-pc-configurator-choice-item', function () { ?> <# if ( data.sku ) { #><span class="choice-sku">{{ data.sku }}</span><# } #><?php }, 20 ); // between the name and the description
Anything you reference as data.… must actually be on the choice model — add it with
mkl_pc_choice_default_settings and it will be. See
Adding custom data to choices.
Put links, buttons and inputs in --after:
add_action( 'tmpl-pc-configurator-choice-item--after', function () { ?> <# if ( data.spec_sheet ) { #> <a class="spec-link" href="{{ data.spec_sheet }}" target="_blank">Specification</a> <# } #><?php } );
Both fire for choice groups too, from inside the group's label.
tmpl-pc-configurator-choice-item-attributes and mkl_pc_choice_items_attributes
Two ways to get attributes onto a choice. The action prints raw attribute markup into the button tag, so it can use template syntax:
add_action( 'tmpl-pc-configurator-choice-item-attributes', function () { ?> data-sku="{{ data.sku }}"<?php } );
The filter works on an array and is escaped for you, so it is the safer choice for static values:
add_filter( 'mkl_pc_choice_items_attributes', function ( $attributes ) { $attributes['data-analytics'] = 'choice'; return $attributes;} );
Both are printed into every choice. Anything that varies per choice has to come from data.….
tmpl-pc-configurator-choice-item-label
The expression used for the choice name, {{{data.name}}} by default. Because it is passed
through wp_kses_post(), you can wrap it but not introduce arbitrary markup.
add_filter( 'tmpl-pc-configurator-choice-item-label', function ( $label ) { return '<strong>' . $label . '</strong>';} );
mkl_pc_frontend_configurator_footer_*
The footer is where the price, quantity, add-to-cart button and reset button live. The hooks bracket each section, so you can insert without replacing anything:
add_action( 'mkl_pc_frontend_configurator_footer_form_before', function () { ?> <div class="lead-time"><# if ( data.lead_time ) { #>Ships in {{ data.lead_time }} days<# } #></div><?php } );
Core attaches the reset button to …_footer_section_right_before at priority 30 and the product
name to …_footer_section_left_inner, so use priorities around those to position your own.
mkl_pc_frontend_templates_parts
The list of template part files, each an array with path and file. Adding an entry is the
supported way to ship a whole template of your own; replacing one is how you override core markup
wholesale.
add_filter( 'mkl_pc_frontend_templates_parts', function ( $parts ) { // Swap the summary template for your own. foreach ( $parts as &$part ) { if ( 'summary.php' === $part['file'] ) { $part['path'] = plugin_dir_path( __FILE__ ) . 'templates/'; } } return $parts;} );
A missing file is not fatal but is dumped to the page with var_dump, so check your paths.
mkl-pc-configurator-layer-item.with.button
A JavaScript filter, despite living in a PHP template — it is evaluated in the browser each
time a layer renders. It decides whether a layer is a <button> or a non-interactive <span>;
core returns false for step layers.
wp.hooks.addFilter( 'mkl-pc-configurator-layer-item.with.button', 'my-plugin/layers', function ( useButton, data ) { return data.my_readonly ? false : useButton; });
Register it like any other JavaScript hook — it is listed here because that is where you will find it in the source.
mkl_pc_layer_thumbnail_alt
Layer thumbnails are decorative and carry an empty alt by default. Return a non-empty string to
make them informative — but only if the image genuinely conveys something the layer name does
not, or you are adding noise for screen reader users.
mkl_pc_layers and mkl_pc_layers_before / _after
The viewer's own hooks. mkl_pc_layers prints inside the element the 2D layer images are stacked
into, which makes it the place for a watermark or an overlay:
add_action( 'mkl_pc_layers', function () { ?> <div class="my-overlay" aria-hidden="true"></div><?php } );
On a 3D product the same container holds the canvas instead, so anything you add here must be positioned rather than in normal flow.
mkl_pc_frontend_templates_before and _after
Bracket the whole template block. Use them to print templates of your own without touching the parts list:
add_action( 'mkl_pc_frontend_templates_after', function () { ?> <script type="text/html" id="tmpl-my-badge"> <span class="badge">{{ data.label }}</span> </script><?php } );