Template Overrides
{/* AUTO-GENERATED from ../docs/template-overrides.md by scripts/sync-dev-docs.mjs — do not edit by hand. */}
Overview
Section titled “Overview”Dino Discounts ships PHP templates for every storefront-facing component. Theme authors and agencies can replace any template by placing a copy in their theme directory. The plugin renders from the theme copy instead of its own.
When to override:
- You need HTML structure changes that CSS can’t solve (e.g. adding a wrapper, reordering elements).
- You need to inject additional data from your theme (e.g. ACF fields, custom post meta).
- Your design system requires semantic markup the default template doesn’t produce.
When not to override:
- You only need visual changes — use CSS targeting
.dd-*classes instead. - You want to change copy — use the
gettextfilter on the relevant string. - You want to suppress a component entirely — use
remove_actionon the hook that callsdino_discounts_get_template().
Override Mechanism
Section titled “Override Mechanism”Copy the template from the plugin into your theme, preserving its relative path under a dino-discounts/ directory:
yourtheme/└── dino-discounts/ ├── storefront/ │ ├── tier-table.php │ ├── discount-message.php │ └── spend-more-nudge.php └── mini-cart-discounts.phpSearch order (first match wins):
{child_theme}/dino-discounts/{template_name}{parent_theme}/dino-discounts/{template_name}{plugin}/templates/{template_name}
Variables are extracted into the template’s local scope via extract() — the same pattern WooCommerce uses. Every variable listed in each template’s docblock is available as a plain PHP variable inside the template file.
Per-Template Variable Reference
Section titled “Per-Template Variable Reference”storefront/tier-table.php
Section titled “storefront/tier-table.php”Purpose: Tier pricing table rendered on single product pages, showing quantity/spend thresholds and the corresponding discount for each tier.
Override path: yourtheme/dino-discounts/storefront/tier-table.php
Since: 4.15.0
Stability: ⚠️ Risky — see Stability Guide
| Variable | Type | Description |
|---|---|---|
$tiers | array | Sorted array of tier objects. Each entry has threshold (int/float), reward_type (string), and reward_value (float). |
$type | string | Rule type: 'bulk', 'tiered', 'x_for_y', or 'mix_match'. Controls which column headers are rendered. |
$trigger_metric | string | What the threshold measures: 'quantity', 'cart_subtotal', or 'line_total'. |
$product_price | float | Current product price, used to compute the discounted unit price in percent/fixed rows. |
$currency | string | WooCommerce currency symbol. Passed for convenience; the default template uses wc_price() directly rather than this variable. |
$rule | array | Full discount rule array from the engine. Useful for advanced customisation; schema may change between minor versions. |
$product | \WC_Product | WooCommerce product object for the page being rendered. |
Reward type values ($tier['reward_type']): 'percent_off', 'fixed_amount_off', 'free_shipping', 'free_item'.
storefront/discount-message.php
Section titled “storefront/discount-message.php”Purpose: Promotional message rendered on single product pages (e.g. “Buy 3, save 20%”). The message string is fully resolved before the template receives it.
Override path: yourtheme/dino-discounts/storefront/discount-message.php
Since: 4.15.0
Stability: ✅ Safe — see Stability Guide
| Variable | Type | Description |
|---|---|---|
$message | string | Resolved message HTML. Placeholders have already been replaced and the value is wp_kses_post-safe. |
$rule | array | Full discount rule array. Use for conditional rendering; schema may change between minor versions. |
$product | \WC_Product | WooCommerce product object. |
storefront/spend-more-nudge.php
Section titled “storefront/spend-more-nudge.php”Purpose: “Spend more” nudge bar rendered in the cart, checkout, and mini-cart, showing how much more the shopper needs to spend to unlock the next discount tier.
Override path: yourtheme/dino-discounts/storefront/spend-more-nudge.php
Since: 4.15.0
Stability: ✅ Safe — see Stability Guide
| Variable | Type | Description |
|---|---|---|
$message | string | Resolved nudge message HTML. Placeholders have already been replaced and the value is wp_kses_post-safe. |
$modifier_class | string | Space-separated CSS modifier classes added to the wrapper (e.g. 'dd-spend-more-nudge--cart-page dd-position-bottom'). |
$rule | array | Full discount rule array. |
$delta | float | Monetary gap between the shopper’s current spend and the next threshold. |
$context | string | Where the nudge is displayed: 'mini', 'cart', or 'checkout'. |
$position | string | Nudge position relative to its container: 'top' or 'bottom'. |
mini-cart-discounts.php (legacy)
Section titled “mini-cart-discounts.php (legacy)”See Legacy Note below.
Stability Guide
Section titled “Stability Guide”Safe overrides
Section titled “Safe overrides”discount-message.php and spend-more-nudge.php are stable override targets. Their variable contracts are intentionally narrow:
$messageis a pre-rendered, already-escaped string. You can wrap it, hide it, or replace it with your own markup without touching engine internals.$ruleis passed for context but your template does not need to consume it. If you do read from$rule, be aware the schema can change on minor version bumps (see version-skew section below).- Other variables (
$delta,$context,$position) are plain scalars unlikely to change semantics.
Risky overrides
Section titled “Risky overrides”tier-table.php is tightly coupled to the engine rule schema. It reads $tiers, $type, and $trigger_metric — all of which are derived directly from internal engine data. When the engine gains a new reward type or trigger metric, the default template is updated in the same release. If you have overridden this template, your copy will not receive that update and may silently mis-render new tiers or omit new reward types.
Mitigation if you must override tier-table:
- Copy the default template in full and make the minimum change needed.
- Subscribe to the changelog. Any release that touches
src/Engine/ortemplates/storefront/tier-table.phprequires you to merge upstream changes into your copy. - Add a comment at the top of your copy recording the plugin version it was based on (e.g.
// Based on Dino Discounts 4.15.0).
Version-skew detection
Section titled “Version-skew detection”There is currently no automatic template-version check. To detect drift manually:
- After each plugin update, run:
Terminal window diff wp-content/plugins/dino-discounts/templates/storefront/tier-table.php \wp-content/themes/yourtheme/dino-discounts/storefront/tier-table.php - Review the diff against the plugin changelog before going live.
Filter: dino_discounts_locate_template
Section titled “Filter: dino_discounts_locate_template”Intercept template resolution and point any template at a custom path — useful for plugins, page builders, or multi-theme setups that can’t use the standard theme directory.
/** * Signature: * apply_filters( 'dino_discounts_locate_template', string $template, string $template_name ) * * @param string $template Absolute path to the resolved template (child/parent theme or plugin fallback). * @param string $template_name Relative template name that was requested (e.g. 'storefront/tier-table.php'). * @return string Absolute path to use instead. */add_filter( 'dino_discounts_locate_template', function ( string $template, string $template_name ): string { // Redirect the tier table to a custom location for a specific child theme. if ( 'storefront/tier-table.php' === $template_name && is_child_theme() ) { $custom = get_stylesheet_directory() . '/my-custom-templates/tier-table.php'; if ( file_exists( $custom ) ) { return $custom; } } return $template;}, 10, 2 );The filter fires on every template load, so keep the callback fast (a single file_exists() check is fine; a database query is not).
Actions: dino_discounts_before_template and dino_discounts_after_template
Section titled “Actions: dino_discounts_before_template and dino_discounts_after_template”Inject markup immediately before or after any template without replacing it. Useful for wrapping elements, adding tracking pixels, or inserting theme-specific content alongside plugin output.
Both actions pass 3 arguments: $template_name, $template_path, and $args. Always register with accepted_args = 3 (the fourth parameter to add_action) so WordPress passes all three to your callback. This is confirmed at includes/Storefront/template-functions.php lines 74 and 90.
/** * Signature (both actions share the same parameters): * do_action( 'dino_discounts_before_template', string $template_name, string $template_path, array $args ) * do_action( 'dino_discounts_after_template', string $template_name, string $template_path, array $args ) * * @param string $template_name Relative template name (e.g. 'storefront/spend-more-nudge.php'). * @param string $template_path Absolute path to the resolved template file. * @param array $args All variables passed into the template (same keys as the variable tables above). */
// Example: wrap the spend-more nudge in a theme-specific container.// Priority 10, accepted_args 3 — required to receive all three hook parameters.add_action( 'dino_discounts_before_template', function ( string $template_name, string $template_path, array $args ): void { if ( 'storefront/spend-more-nudge.php' === $template_name ) { echo '<div class="mytheme-nudge-wrapper">'; } }, 10, 3);
add_action( 'dino_discounts_after_template', function ( string $template_name, string $template_path, array $args ): void { if ( 'storefront/spend-more-nudge.php' === $template_name ) { echo '</div>'; } }, 10, 3);// Example: log which templates fire on a page (development only).// $args contains all variables passed into the template.add_action( 'dino_discounts_before_template', function ( string $template_name, string $template_path, array $args ): void { if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log error_log( 'dino_discounts template: ' . $template_name . ' from ' . $template_path ); } }, 10, 3);Note that dino_discounts_get_template() captures output via ob_start() / ob_get_clean(), so template output is returned as a string rather than echoed directly. The before/after actions fire inside that buffer, so any echo from your action callback is included in the captured string.
Legacy Note: mini-cart-discounts.php
Section titled “Legacy Note: mini-cart-discounts.php”templates/mini-cart-discounts.php is a legacy artifact. The current mini-cart rendering path is JavaScript-driven (assets/js/mini-cart-discounts.js, reading from window.dinoDiscountsMiniCart). The PHP template is no longer called during a normal page load.
Overriding this file has no effect on what shoppers see in the mini-cart. If you need to change the mini-cart discount display, target the JS output via CSS or open a feature request for a JS-side hook.
The file is retained for backward compatibility with any third-party code that called the template directly before 4.15.0.
Path note: The template file’s own comment incorrectly states the override path as
yourtheme/woocommerce/dino-discounts/mini-cart-discounts.php. The actual loader looks foryourtheme/dino-discounts/mini-cart-discounts.php(without thewoocommerce/segment). The stale comment in the file will be corrected in a future release.
Testing Checklist
Section titled “Testing Checklist”After placing an override, verify it is active and behaves correctly:
- Override is loaded: Add a visible marker (e.g.
<!-- override active -->) to the template, load the relevant page, and confirm the marker appears in page source. Remove before shipping. - No PHP errors or warnings: Check
wp-content/debug.log(withWP_DEBUG_LOGenabled) after loading the affected page. - All variables are defined: In
WP_DEBUGmode, WordPress will warn on undefined variables. Walk through every variable listed in the table for your template. - Correct context rendering: For
spend-more-nudge.php, test in mini-cart, cart page, and checkout. Fortier-table.php, test withbulk,tiered,x_for_y, andmix_matchrule types if your store uses more than one. - Escaping is intact: Every user-visible string must pass through
esc_html(),esc_attr(), orwp_kses_post()as appropriate. Do not echo raw$ruleor$productdata directly. - Child/parent theme priority: If using a child theme, confirm the child copy wins over the parent by temporarily removing it and verifying the parent copy loads.
- Plugin update regression: After each Dino Discounts update, diff your copy against the plugin’s version of the template and merge any upstream changes before re-testing.