Skip to content

Themes & template overrides ​

Ambikly works with any WordPress theme. The storefront is rendered by shortcodes and blocks inside your theme's normal page template, so your header, footer, container widths and typography all apply without configuration.

What Ambikly does not have is a WooCommerce-style template hierarchy. This page is deliberately precise about where the line falls, because the difference matters a lot if you are planning customization work.

What you can override, and what you cannot ​

AreaOverride method
Transactional email markupTheme template override — three templates, listed below
Shop, product, cart, checkout, account, thank-you markupNo template override. CSS, block and shortcode attributes, and ambikly_* filters only
Product card badges and buttonsambikly_* filters
Account tabsambikly_* filters and actions
Product URLsambikly_product_permalink filter
Colors, spacing, layoutYour theme's CSS

There is no storefront template-override system

The plugin ships exactly three template files, and all three are email templates. Shop, product, cart, checkout, account and thank-you markup is generated inline in PHP. Copying a file into your-theme/ambikly/ will not change any storefront page, because there is no storefront template file to copy.

The template loader ​

The loader function is ambikly_locate_template(). It resolves a template name through WordPress's own locate_template(), which checks the child theme first and then the parent theme:

  1. {child-theme}/ambikly/{template}
  2. {parent-theme}/ambikly/{template}
  3. The plugin's own templates/{template}

The first file that exists wins. The resolved path then passes through the ambikly_locate_template filter, so a plugin can redirect a template somewhere else entirely.

ambikly_get_template() wraps the loader: it locates the file, extracts any named arguments into scope, fires ambikly_before_template_part, includes the file, and fires ambikly_after_template_part. If the located file does not exist it calls _doing_it_wrong() and renders nothing rather than fataling.

Both functions are declared inside if (!function_exists()) guards, so a theme can replace either one wholesale by declaring it first.

The three templates you can override ​

These are the only template files in the plugin.

TemplatePlugin pathChild theme override path
Email headertemplates/emails/header.phpyour-child-theme/ambikly/emails/header.php
Email footertemplates/emails/footer.phpyour-child-theme/ambikly/emails/footer.php
Order notification bodytemplates/emails/order/notification.phpyour-child-theme/ambikly/emails/order/notification.php

To override one, copy the file from the plugin into your child theme at the matching path under an ambikly/ folder and edit your copy. Keep the folder structure — emails/order/notification.php, not notification.php.

Tip: Override the header and footer to wrap every transactional email in your own branding once, rather than editing message bodies individually. Message text itself is editable without any code — see Emails.

Customizing the storefront ​

With no templates to copy, storefront customization comes down to three things: CSS, attributes, and filters.

1. CSS ​

All storefront markup carries stable, prefixed class names. The stylesheet is registered as ambikly-storefront and enqueued by every shortcode and block, so you can enqueue your own stylesheet after it and override freely.

The classes you will use most:

ClassElement
.ambikly-shopShop wrapper. Carries data-columns.
.ambikly-shop__gridThe product grid. Column count is the --cols CSS variable.
.ambikly-product-cardOne product card. Carries data-ambikly-product-id.
.ambikly-product-card--out-of-stockAdded to cards for products that are not in stock.
.ambikly-product-card__badges / __badgeBadge container and individual badges.
.ambikly-product-detailSingle product page wrapper.
.ambikly-product-galleryProduct gallery, main image and thumbnails.
.ambikly-cart / #ambikly-cart-appCart mount node.
.ambikly-checkout / #ambikly-checkout-appCheckout mount node.
.ambikly-accountAccount wrapper. .ambikly-account--guest for the sign-in card.
.ambikly-thankyouOrder confirmation wrapper.
.ambikly-btn, .ambikly-btn--primary, .ambikly-btn--outline, .ambikly-btn--blockButtons.
.ambikly-pagination / .ambikly-pagePagination nav and links.
.ambikly-reviews__list / .ambikly-reviewReviews list and one review.

Put your rules in your theme's stylesheet or a child theme. There is no "Custom CSS" or "Custom JS" field in the plugin's settings screens that affects the storefront — nothing in the plugin reads such a value.

2. Block and shortcode attributes ​

Columns, products per page, whether the sort and search controls appear, cart layout, media position, CTA labels — a lot of what looks like it needs a template change is a shortcode attribute. Check Shortcodes and Blocks & store pages before writing any PHP.

3. Filters and actions ​

These are the storefront extension points in the free core. Register them with plain add_action() and add_filter() in your theme's functions.php or a small site plugin.

HookTypeFiresArguments
ambikly_product_card_badgesfilterOn every product card, before rendering badgesarray $badges, Product $product
ambikly_product_card_actionsfilterOn every product card, after the View and add-to-cart buttonsarray $actions, int $product_id, Product $product
ambikly_product_detail_bodyactionInside the product detail info column, after the short descriptionProduct $product
ambikly_product_detail_actionsfilterInside the add-to-cart form on the product detail pagearray $extras, int $product_id, Product $product
ambikly_product_permalinkfilterWhenever a product URL is builtstring $url, Product $product
ambikly_account_tabsfilterWhen the account page builds its sidebararray $tabs (key => label)
ambikly_account_tab_{tab}actionAfter the account page renders the selected tabarray $customer
ambikly_account_order_extrasfilterPer order row in the account Orders tablestring $html, Order $order
ambikly_login_form_afterfilterDirectly after the sign-in form on a logged-out account pagestring $html
ambikly_locate_templatefilterEvery template lookupstring $template, string $name, string $theme_path, string $default_path
ambikly_before_template_partactionBefore a template file is includedstring $name, string $located, array $args
ambikly_after_template_partactionAfter a template file is includedstring $name, string $located, array $args

Note what each is for:

  • ambikly_product_card_badges is the only supported way to add a ribbon to a product card. Each badge is an array with a key (used in the CSS class) and a label.
  • ambikly_product_card_actions and ambikly_product_detail_actions both take an array of ready-made HTML strings and join them with a space. Escape your own output — the plugin does not.
  • ambikly_product_detail_body is an action, not a filter: echo your markup directly.
  • ambikly_product_permalink is where you would add pretty permalinks. Ambikly's own URLs are {shop page}?ambikly_product={slug} and there is no rewrite in the free core.
  • ambikly_account_tabs plus ambikly_account_tab_{tab} are a pair: add the tab to the array with the first, render its body with the second.
  • ambikly_login_form_after takes and returns a string of HTML appended below the login form.

A real example ​

Add a "Free shipping" badge to every product over $50, and a small "Ships in 24h" note under the add-to-cart button on product pages.

php
<?php
// In your child theme's functions.php, or a small site plugin.

add_filter('ambikly_product_card_badges', function (array $badges, $product) {
    $price = (float) ($product->sale_price ?: $product->price);
    if ($price >= 50.0) {
        $badges[] = [
            'key'   => 'free-shipping',
            'label' => __('Free shipping', 'my-theme'),
        ];
    }
    return $badges;
}, 10, 2);

add_filter('ambikly_product_detail_actions', function (array $extras, $product_id, $product) {
    if ($product->type !== 'digital') {
        $extras[] = '<p class="my-ships-fast">'
            . esc_html__('Ships in 24 hours', 'my-theme')
            . '</p>';
    }
    return $extras;
}, 10, 3);

Then style the new badge with the class the plugin generates for it:

css
.ambikly-product-card__badge--free-shipping {
  background: #0f766e;
  color: #fff;
}
Careful: Do not use the helper class Ambikly\Support\Hooks to register these. It exists in the source but has no call sites. Use plain add_action() and add_filter().

Using Ambikly in a block theme ​

Block themes work, with one thing to plan around: Ambikly's blocks have no editor UI, so a full-site-editing template is usually easier to build with shortcodes.

  1. Leave the five store pages exactly as the activation seeder created them — a page each holding [ambikly_shop], [ambikly_cart], [ambikly_checkout], [ambikly_account] and [ambikly_thank_you].
  2. Make sure your theme's Page template renders post_content full-width enough for a product grid and a two-column cart.
  3. For a cart icon in the site header, edit your Header template part and add the mini-cart block through the code editor: <!-- wp:ambikly/mini-cart {"showSubtotal":true} /-->.
  4. For product listings elsewhere — a home page featured row, a landing page — use a Shortcode block with [ambikly_shop] and its attributes, rather than the product grid block. You get an editable attribute string instead of hand-written JSON.
Careful: Do not build a custom FSE template for "single product". There is no product post type and no product template in the hierarchy — product pages are the Shop page rendering a different shortcode branch based on the ?ambikly_product= query string.

Overriding an email template ​

The three templates are the one place a real file override applies, so here is what you get inside them.

The order notification body is rendered with the order in scope and its content passed through the smart-tag parser. Smart tags are replaced at send time, and this is the complete built-in set:

Smart tagValue
The order number, falling back to the order ID
The order total, formatted in the order's currency
The order's current status
The customer-facing payment method title
The order's email address
Billing first name, falling back to "there"
Billing full name, falling back to the email address
Link to the order's invoice
Link to the order in wp-admin
The site home URL
The site name

Add your own with the ambikly_all_smart_tags filter — it receives the tag map, the order, and any extra tags the caller supplied, and whatever you return is what gets substituted.

  1. Copy templates/emails/header.php and templates/emails/footer.php from the plugin into your-child-theme/ambikly/emails/.
  2. Edit your copies to wrap every email in your own table-based layout, logo and footer text.
  3. Send a test order to yourself and check the result in a real email client, not just a browser.
Tip: Override the header and footer, not the notification body. Message text is editable from Ambikly → Emails without any code, and a merchant editing copy there should not have to touch a PHP file you own.

Practical advice for theme authors ​

  • Give the shortcodes room. The shop grid, cart and checkout expect a reasonably wide content column. A narrow blog-post container will squeeze the two-column cart layout.
  • Do not fight the column variable. The grid sets --cols inline from the columns attribute. Read it in your own CSS rather than hard-coding a column count.
  • Style the disabled state. Out-of-stock cards get .ambikly-product-card--out-of-stock and a disabled button. If your theme's button styles ignore [disabled], an unbuyable product will look buyable.
  • Check the guest account page. The logged-out account page uses .ambikly-account--guest and renders WordPress's own wp_login_form() markup. That form inherits core styles, not yours, unless you style it.
  • Test the 404. A missing or unpublished product sends a real 404 header from inside the Shop page. Make sure your theme does not swallow that.

Where to go next ​

  • Hooks & filters — the complete hook reference, including the order, cart, checkout and email hooks not listed here.
  • Template overrides — the loader in more detail, and the exact contents of the three email templates.
  • Emails — editing email content without touching a template file.