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
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.
Cart plugin (e.g. cart.js) builds this structure and provides formatted
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.