Skip to content

Shortcodes ​

Ambikly registers eight shortcodes. They are the primary way to place the storefront on a page — the five pages created at activation each hold one — and unlike the blocks, their attributes are plain text you can edit anywhere, including in page builders.

Every shortcode enqueues the storefront stylesheet and script when it renders, so there is nothing to load manually.

The eight shortcodes at a glance ​

ShortcodeRendersUsual page
[ambikly_shop]Product grid, or a single product when ?ambikly_product= is setShop
[ambikly_product]One product's detail pageShop (via the query string)
[ambikly_cart]The cart applicationCart
[ambikly_checkout]The checkout applicationCheckout
[ambikly_account]Customer account, or a sign-in formMy Account
[ambikly_thank_you]Order confirmationOrder Received
[ambikly_search]Search results gridA search page
[ambikly_archive]Category, tag or brand listingAn archive page

[ambikly_shop] ​

The catalog grid, and the busiest shortcode in the plugin.

AttributeDefaultClamp / accepted valuesWhat it does
per_page12Clamped to 1–100Products per page.
columns3Not clampedGrid columns, written to a --cols CSS variable.
category""Category IDRestrict to one category. A ?category= query arg overrides it.
featured""See belowShow only featured products.
show_sortyesno hides itShow the sort dropdown.
show_searchyesno hides itShow the search box.
Careful: featured is on for any value except an empty string, no and false. Write featured="yes" to turn it on and simply leave the attribute off to turn it off.

Delegating to the single product page ​

When the URL carries ?ambikly_product=<slug>, [ambikly_shop] hands off to the single-product renderer instead of drawing the grid. That is what lets one WordPress page serve as both the catalog and every product detail page.

This is also why the Shop page must keep this shortcode. Replacing it with the ambikly/product-grid block breaks every product URL on the site.

Sorting ​

The sort dropdown submits ?orderby=. Four values are recognized:

?orderby= valueLabel in the dropdownSorts by
created_atNewestcreated_at descending
price_ascPrice: low to highprice ascending
price_descPrice: high to lowprice descending
nameName A–Zname ascending

Anything else falls back to created_at. The dropdown resubmits the whole GET form, and any active category, tag or brand filter is carried along as a hidden field so sorting does not silently drop it.

Pagination ​

Pages are addressed with ?ap=. ?ap=1 is the first page; the value is floor-clamped to 1.

If you ask for a page past the end of the result set — a stale bookmark, or ?ap=9999 — the grid re-queries clamped to the real last page and shows that instead of an empty "No products matched your search." The pagination nav itself always shows the first and last page plus a two-page window around the current one, with ellipses between, so a large catalog does not emit dozens of links.

Filtering by query string ​

Query argExampleEffect
?s=?s=mugFree-text product search.
?category=?category=4Filter to a category ID. Overrides the category attribute.
?tag=?tag=summerFilter to a tag slug.
?brand=?brand=acmeFilter to a brand slug.
?orderby=?orderby=price_ascSort, as above.
?ap=?ap=3Page number.
?ambikly_product=?ambikly_product=blue-mugRender that product's detail page.

When a category, tag or brand filter is active, the grid header shows a label such as "Category: Mugs" so the shopper can tell a filter is on.

A category whose own status is not published matches nothing. Draft and archived categories are not browsable from the front end even if you know their ID.

What a product card shows ​

Cards are shared by the shop grid, search, archives, related products and the ambikly/product-grid block:

  • Image (or a placeholder), linked to the product.
  • A Sale badge, passed through the ambikly_product_card_badges filter.
  • A Digital or External type label where it applies.
  • Title, price, and rating stars with a review count when there is at least one approved review.
  • A View button and an add-to-cart button. The button is disabled and reads "Out of stock" when the product is not in stock, and reads "Download" for digital products.
  • Any extra buttons returned by the ambikly_product_card_actions filter.

Variable products that leave their own price blank show "From $X", computed from the cheapest published variation's effective price.

[ambikly_product] ​

One product's full detail page: gallery, attribute selectors, variations, pricing plans, description, reviews and related products.

AttributeDefaultWhat it does
id""Look the product up by numeric ID.
slug""Look the product up by slug.

With neither attribute set, the shortcode falls back to the ?ambikly_product= query arg. That is how the Shop page serves product detail pages.

If the product does not exist, or exists but is not published, the page sends a 404 status header, disables caching, and renders:

Product not found.

with a link back to the Shop page. Draft products are never visible to anonymous visitors, even by a guessed slug.

The page also adds real SEO output on wp_head: a rel="canonical" link to the product's own URL, a meta description from the product's meta_description (falling back to its short description, trimmed to 30 words), and a document title from meta_title (falling back to the product name).

Product URLs ​

Product permalinks are query-string based:

{shop page URL}?ambikly_product={slug}

There is no pretty-permalink rewrite in the free core. Every product URL is built by one helper, which passes the finished URL through the ambikly_product_permalink filter — so a theme or plugin can swap in its own rewrite without touching the plugin.

[ambikly_cart] ​

The cart application. No attributes.

Renders #ambikly-cart-app with a "Loading cart..." placeholder, then storefront.js fetches the cart over REST and takes over. For a server-rendered first paint with a real item preview, use the ambikly/cart block instead.

[ambikly_checkout] ​

The checkout application. No attributes.

Renders #ambikly-checkout-app with a "Loading checkout..." placeholder. Everything after that — addresses, shipping methods, gateways, order placement — runs in JavaScript against the REST API.

[ambikly_account] ​

The customer account area. No attributes.

Logged out, it renders a branded sign-in card: a WordPress login form, whatever the ambikly_login_form_after filter returns (this is where the Social Login add-on injects its buttons), and a "Lost your password?" link.

Logged in, it renders a sidebar and one tab of content. The tab comes from ?ambikly_tab=; an unknown value falls back to the dashboard.

?ambikly_tab=TabContent
dashboard (default)Dashboard"Hello, {name}", plus live order count and total spent.
ordersOrdersPaginated order table with number, date, status, total and an invoice link.
downloadsDownloadsPaginated file list with use count, limit and expiry.
addressesAddressesSaved billing and shipping addresses.
profileProfileDisplay name, email and phone.

Both the orders and downloads tables paginate 50 rows at a time, using the same ?ap= parameter as the shop grid.

The tab list runs through the ambikly_account_tabs filter, and after the core tab renders, ambikly_account_tab_{tab} fires — that is how Pro add-ons add a Subscriptions, Licenses, Gift Cards or Wishlist tab.

Careful: The Addresses tab is display-only. There is no storefront address editing in the free core — addresses are saved from checkout. The Profile tab's "Edit profile" button goes to the WordPress profile screen, which covers name, email and password but not the customer phone number.

[ambikly_thank_you] ​

The order confirmation page. No attributes.

Reads ?order_id= and ?key= from the URL. The key is an HMAC token returned by the checkout response; without a valid one, only the order's owner (matched on user ID or email) or a store administrator can view the page. Anyone else sees the generic "Thank you for your purchase." message. That guard is what stops sequential order IDs from leaking order numbers, totals and payment status.

For a paid order the page shows the item table, the order number, payment method, payment status, total, and a View invoice button.

This page is also the completion point for redirect gateways. When a paid order lands here for the first time, the cart is cleared and ambikly_checkout_completed fires — once, guarded by order meta so a refresh does not re-fire it.

Tip: For Stripe and PayPal, ambikly_checkout_completed fires with null as its second argument. Any handler you write must null-check it.
AttributeDefaultClamp
per_page12Clamped to 1–100 by the grid
columns3Not clamped

Delegates to the shop grid, so it honors ?s=, ?orderby=, ?ap= and every other shop query arg. Use it when you want a dedicated search results page separate from the catalog.

[ambikly_archive] ​

AttributeDefaultClamp
per_page12Clamped to 1–100 by the grid
columns3Not clamped

Also delegates to the shop grid. It is meant for category, tag and brand listings driven by ?category=, ?tag= and ?brand=. The tag and brand chips on a product detail page link here by default.

window.AmbiklyStore ​

Every storefront page that enqueues the script also gets a small bootstrap object on window. The JavaScript reads it instead of hard-coding anything, and you can read it too.

js
window.AmbiklyStore = {
  rest_url: 'https://example.com/wp-json/ambikly/v1',
  nonce: 'a1b2c3d4e5',
  currency: 'USD',
  currency_symbol: '$',
  store: {
    country: 'US'
  },
  pages: {
    shop: 'https://example.com/shop/',
    cart: 'https://example.com/cart/',
    checkout: 'https://example.com/checkout/',
    account: 'https://example.com/my-account/',
    thank_you: 'https://example.com/order-received/'
  }
};
KeyWhat it holds
rest_urlBase URL for the ambikly/v1 REST namespace.
nonceA wp_rest nonce. Send it as the X-WP-Nonce header.
currencyThe store currency code.
currency_symbolThe symbol for that currency.
store.countryThe store country, used as the default in the checkout country select.
pagesResolved permalinks for the five store pages.

That is the whole object. There is nothing else on it — no cart contents, no customer data.

Recipes ​

A category landing page ​

Create a page, drop in the archive shortcode, and link to it with the category ID.

[ambikly_archive per_page="24" columns="4"]

Then link to /mugs/?category=4. The grid filters itself and the header shows "Category: Mugs". Sorting and paging from there keep the filter.

If you would rather bake the category into the page so no query string is needed, use the shop shortcode with the attribute instead:

[ambikly_shop category="4" columns="4" per_page="24" show_search="no"]

A search results page ​

Create a page at /search/ with:

[ambikly_search per_page="24" columns="3"]

Then point any search form at it:

html
<form method="get" action="/search/">
  <input type="search" name="s" placeholder="Search products…">
  <button type="submit">Search</button>
</form>

The grid reads ?s= and shows the match count in its header. An empty result renders "No products matched your search."

[ambikly_shop featured="yes" per_page="4" columns="4" show_sort="no" show_search="no"]
PROFiltering without a page reload

The shop grid filters through query strings, which means a full page load per change. The AJAX Filters add-on adds faceted filter widgets that refresh the grid in place, and Smart Search replaces the plain search box with instant results.

See pricing →

Where to go next ​