All expressions in the frontend template engine are evaluated against a merged context: the global scope (Documentation Index
Fetch the complete documentation index at: https://docs.elasticfunnels.io/llms.txt
Use this file to discover all available pages before exploring further.
window.efScope) plus any local context (e.g. loop variables). This page describes what data lives where and how to use it safely.
Global scope: window.efScope
The single source of truth for reactive data is window.efScope. The application and plugins (cart, checkout, bumps) populate and update it.
- Initialization: The template engine ensures
window.efScopeexists wheninitTemplateScope()runs (e.g. from main.js). Cart and checkout plugins then setcartItems,checkout, etc. - Updates:
efScopeis reactive. After code changesefScope, the DOM updates automatically.
Typical top-level keys
| Key | Description |
|---|---|
cartItems (or items) | Array of cart line items. Prefer cartItems in new templates. |
checkout | Checkout data: totals, customer fields, bump products, coupon, etc. Only set on checkout pages. |
query | URL query parameters as an object (e.g. query.coupon, query.p, query.bumps). Must be populated at init (e.g. via syncQueryToScope()). |
currency | Default currency (e.g. USD) when not overridden by checkout.currency. |
is_cart / is_single_product | Booleans set by the app to distinguish multi-item checkout vs single-product checkout. |
errors | Object keyed by field id: { [fieldId]: message }. Used for checkout validation messages. |
mode | Helper object with e.g. item_count, has_query_product, is_cart, is_single_product. |
Cart: cartItems / items
cartItems— Preferred name for the array of cart line items (used on checkout and cart UI).items— Alias; same data in many contexts.- On checkout pages the same list is also exposed as
checkout.cartandcheckout.items.
| Property | Description |
|---|---|
code | Product/cart line code (used for qty +/- and remove). |
name | Product name. |
image | Product image URL (for thumbnails). |
quantity | Quantity. |
price | Unit price — already formatted (e.g. “$29.00”). Use as-is in [[ item.price ]]. |
total | Line total — already formatted. Use [[ item.total ]]; do not call formatPrice(lineTotal(item), ...). |
currency | Currency code for the line. |
price and total; the template engine does not re-format them.
Checkout: checkout.*
On checkout pages, efScope.checkout holds everything needed for the order summary, form, and payment. For full checkout-specific docs (totals, fields, coupon, bumps, payment panel), see Checkout.
Totals (formatted + raw, mode-agnostic)
The same totals schema is available in both checkout modes (is_single_product and is_cart), so templates can reuse one price-summary layout.
Formatted keys (display):
checkout.product_price,checkout.retail_pricecheckout.bump_totalcheckout.subtotal_before_discountcheckout.discount_totalcheckout.subtotal_after_discountcheckout.subtotal(legacy alias ofsubtotal_after_discount)checkout.shipping,checkout.tax,checkout.total
checkout.product_price_raw,checkout.retail_price_rawcheckout.bump_total_rawcheckout.subtotal_before_discount_rawcheckout.discount_total_rawcheckout.subtotal_after_discount_rawcheckout.subtotal_raw(legacy alias ofsubtotal_after_discount_raw)checkout.shipping_raw,checkout.tax_raw,checkout.total_raw
checkout.tax_raw > 0.
Single-product vs cart layout
is_single_product— One product; show hero image + title block. Usecheckout.product_image,checkout.product_title,checkout.product_price,checkout.retail_price(and optionallyproduct_code,product_description). Do not usecartItems[0]in that block.is_cart— Multiple items; show list with<template-foreach data-each="item in cartItems">and[[ item.image ]],[[ item.name ]],[[ item.total ]], etc.
Bumps
checkout.bump_products— Full list of bump products (each hascode,name,description,priceformatted,price_rawnumeric,imageURL,addedboolean).checkout.selectedBumpLines— Array of selected bumps:code,name,price(formatted),price_raw.
[[ bump.price ]] and [[ line.price ]] for display; do not pass them to formatPrice. Use price_raw only for conditions or when you explicitly format a raw number. Use bump.added for conditional blocks and for @click add/remove patterns (e.g. <button @click="bump.added = true"> / <button @click="bump.added = false">); use ef-src="bump.image" for the bump image (with a placeholder src).
Coupon
checkout.coupon— When applied:applied,code,name,value_formatted,fixed_value,pct_value,discount.checkout.coupon_message— Error message from validation (e.g. invalid code). Show with<template-if data-condition="checkout.coupon_message">and[[ checkout.coupon_message ]].- URL coupon: Use
query.couponto detect a coupon from the URL; usecheckout.couponfor the applied details after the app auto-applies.
Customer and form fields
checkout.customer.*— Paths used withdata-template-valuefor two-way binding: e.g.checkout.customer.email,checkout.customer.shipping_first_name,checkout.customer.billing_first_name.checkout.shipping_same_as_billing— Boolean; when true, shipping address block can be hidden and a short message shown instead.checkout.countries,checkout.usStates— Arrays of{ value, label }for country/state<select>options.
URL parameters: query.*
query should be an object built from window.location.search (e.g. via syncQueryToScope() at init). Each query parameter is a key; e.g. query.coupon, query.p, query.bumps.
Use query.* for URL-driven visibility:
efScope.query, conditions like query.coupon will be undefined and the block will not show.
Effective context and mode
The engine merges caller context (e.g. from a loop) with window.efScope to form the effective context for each expression. It also adds:
mode— Object withitem_count,has_query_product,is_cart,is_single_product.is_cart,is_single_product— Convenience booleans on the root of the merged context.
<template-if data-condition="is_single_product"> and <template-if data-condition="is_cart"> without touching checkout directly.
Runtime API: watch and computed
The frontend API also exposes Vue-like helpers atwindow.ef.template:
Summary
- Data lives in
window.efScope; expressions see global scope + loop/block context. - Reactivity is automatic when
efScopevalues change. - Cart: Use
cartItems(oritems); each item hasprice,total(formatted),code,name,image,quantity. - Checkout: Use
checkout.*for totals, bumps, coupon, customer; use formatted keys for display and_rawonly when you need numbers orformatPrice. - URL: Use
query.*after the app has setefScope.query(e.g. viasyncQueryToScope()). - Layout: Use
is_single_productandis_cartto choose between single-product summary and cart list.