diff --git a/content/docs/apps/guides/dispute-service.mdx b/content/docs/apps/guides/dispute-service.mdx index c6560c2..d214cc4 100644 --- a/content/docs/apps/guides/dispute-service.mdx +++ b/content/docs/apps/guides/dispute-service.mdx @@ -137,7 +137,7 @@ It's desirable to cancel fulfillment for orders that have not shipped yet when t To retrieve a list of all fulfillment orders and their status, use the [ordersFulfillmentOrdersRetrieve](/docs/admin-api/reference/orders/ordersFulfillmentOrdersRetrieve) endpoint. - + If order `fulfilmlent_status` is `unfulfilled`, your dispute service can stop fulfillment using the [fulfillmentOrdersHold](/docs/admin-api/reference/fulfillment/fulfillmentOrdersHold) endpoint. @@ -151,7 +151,7 @@ If order `fulfilmlent_status` is `unfulfilled`, your dispute service can stop fu ``` - + If order `fulfilmlent_status` is `processing` your dispute service can request processing fulfillment orders be canceled with the fulfillment locations with the [cancellationRequestSend](/docs/admin-api/reference/fulfillment/cancellationRequestSend) endpoint. diff --git a/content/docs/storefront/themes/cdn-and-caching.mdx b/content/docs/storefront/themes/cdn-and-caching.mdx index 2f2989a..659b875 100644 --- a/content/docs/storefront/themes/cdn-and-caching.mdx +++ b/content/docs/storefront/themes/cdn-and-caching.mdx @@ -39,5 +39,5 @@ Updating a template through the dashboard or [Theme Kit](/docs/storefront/themes There are a few cases wherein a form on the frontend needs to use a `{% csrf_token %}` field to secure submission to the backend. The platform core JS will automatically replace `{% csrf_token %}` that are in cached versions of pages to ensure the forms still work. -**It is advisable to not implement custom templates that require `{% csrf_token %}`, we recommend to [Storefront API](/docs/storefront/api) instead.** +**It is advisable to not implement custom templates that require `{% csrf_token %}`, we recommend the [Storefront GraphQL API](/docs/storefront/graphql) instead.** \ No newline at end of file diff --git a/content/docs/storefront/themes/templates/filters.md b/content/docs/storefront/themes/templates/filters.md index a42f782..ae58d26 100644 --- a/content/docs/storefront/themes/templates/filters.md +++ b/content/docs/storefront/themes/templates/filters.md @@ -297,9 +297,16 @@ For example, if value is the string "Sandy", the output would be the list ['S', Returns a plural suffix if the value is not 1, '1', or an object of length 1. By default, this suffix is 's'. ```jinja title="pluralize" -You have { num_messages }} message {{ num_messages|pluralize }} +You have {{ num_messages }} message{{ num_messages|pluralize }} ``` +### split +Splits a string by the given delimiter and returns a list. +```django title="split" +{{ value|split:"," }} +``` +For example, if value is `"red,green,blue"`, the output will be the list `['red', 'green', 'blue']`. + ### slugify Converts to ASCII. Converts spaces to hyphens. Removes characters that aren’t alphanumerics, underscores, or hyphens. Converts to lowercase. Also strips @@ -355,6 +362,29 @@ Returns the number of words. For example, if value is "Joel is a slug", the output will be 4. +## Currency + +### currency +Formats a decimal value as a currency string using the provided currency code. This is the primary filter for displaying prices throughout a theme. +```django title="currency" +{{ session.price.price|currency:session.price.currency }} +``` +For example, if the price is `29.99` and the currency is `USD`, the output will be `$29.99`. The filter handles currency symbol placement and formatting based on the currency code. + +```django title="Example Product Price Display" +{% purchase_info_for_product request product as session %} +{% if session.price.exists %} + {% if session.price.price_retail %} + + {{ session.price.price_retail|currency:session.price.currency }} + + {% endif %} + + {{ session.price.price|currency:session.price.currency }} + +{% endif %} +``` + ## Files ### asset_url diff --git a/content/docs/storefront/themes/templates/meta.json b/content/docs/storefront/themes/templates/meta.json index 5e474d2..18b68ca 100644 --- a/content/docs/storefront/themes/templates/meta.json +++ b/content/docs/storefront/themes/templates/meta.json @@ -1,4 +1,4 @@ { "title": "Templates", - "pages": ["index", "tags", "objects", "urls-and-template-paths"] + "pages": ["index", "tags", "objects", "filters", "urls-and-template-paths"] } diff --git a/content/docs/storefront/themes/templates/objects.mdx b/content/docs/storefront/themes/templates/objects.mdx index f38f115..aa3c45e 100644 --- a/content/docs/storefront/themes/templates/objects.mdx +++ b/content/docs/storefront/themes/templates/objects.mdx @@ -57,8 +57,7 @@ Returns a list of active storefront languages you can iterate over, see [languag ### menus - -Allows you to access a menu's items by it's code to iterate over to generate a menu from the backend, see [menu items](#items-menu). +Allows you to access a menu's items by its code to iterate over to generate a menu from the backend, see [menu items](#items-menu). Menus are configured in the dashboard at **Storefront > Navigation**. ```django title="Example Dynamic Menu" @@ -204,6 +203,9 @@ Returns a list of post categories you can iterate over, see [post_category](#pos Content from store Privacy Policy settings, typically used in a "Privacy Policy" page to automatically pull content in from settings. + +Store policies are configured in the dashboard at **Settings > Policies**. The content entered there is automatically available as global template variables. + ```django title="privacy_policy" {{ privacy_policy }} @@ -340,7 +342,7 @@ Object have many properties that can be accessed in templates. ### branding -Store branding properties accessed through the [store](#store) object to leverage within templates. +Store branding properties accessed through the [store](#store) object to leverage within templates. Branding values are configured in the dashboard at **Settings > Branding**. | Property | Type | Description | | ----- | ------ | ------ | @@ -596,7 +598,7 @@ Product review object. | `id` | String | Review ID. | | `title` | String | Review title. | | `score` | Integer | Review score. | -| `user` | Object | The customer that created the review, see [user](#user). | +| `user` | Object | The customer that created the review. | ### voucher @@ -607,3 +609,199 @@ Voucher object. | ----- | ------ | ------ | | `title` | String | Voucher title. | | `code` | String | Voucher code. | + + +## View-Specific Objects + +View-specific objects are available in the templates rendered by their corresponding views. See [Template Contexts](#template-contexts) below for which objects are available in each template. + + +### session + +The session object is returned by the [`purchase_info_for_product`](/docs/storefront/themes/templates/tags#purchase_info_for_product) and [`purchase_info_for_line`](/docs/storefront/themes/templates/tags#purchase_info_for_line) template tags. It contains pricing and availability information for a product in the current user's currency. + +```django title="Example Product Price with Session" +{% purchase_info_for_product request product as session %} +{% if session.price.exists %} + {% if session.price.price_retail %} + + {{ session.price.price_retail|currency:session.price.currency }} + + {% endif %} + {{ session.price.price|currency:session.price.currency }} +{% endif %} + +{% if not session.availability.is_available_to_buy %} + Out of Stock +{% endif %} +``` + +**session.price** + +| Property | Type | Description | +| ----- | ------ | ------ | +| `exists` | Boolean | Whether a price exists for this product. | +| `price` | Decimal | The current selling price. | +| `price_retail` | Decimal | The retail/compare-at price, if set. | +| `currency` | String | The currency code for this price. | +| `excl_tax` | Decimal | The price excluding tax. | + +**session.availability** + +| Property | Type | Description | +| ----- | ------ | ------ | +| `is_available_to_buy` | Boolean | Whether the product can be purchased. | + + +### variant_form + +The variant selection form object available on product detail pages (`catalogue/product.html`). Used to render variant attribute selectors (size, color, etc.) for products with variants. + +```django title="Example Variant Selection" +{% if variant_form %} +
+ {% for field in variant_form %} +
+ + {% render_field field class+="form-select" %} +
+ {% endfor %} +
+{% endif %} +``` + +### filters + +The `filters` object is a list of product filter/facet objects available on category pages (`catalogue/category.html`). Filters allow customers to narrow product listings by attributes like price, color, size, etc. The `has_active_filter` boolean indicates whether any filter is currently applied. + +There are three filter types: `price_range`, `boolean`, and `list`. Each type has different properties for rendering the appropriate UI. + +```django title="Example Category Filters" +{% if filters %} +
+ {% for filter in filters %} +
+
{{ filter.label }}
+ + {% if filter.type == 'price_range' %} + + + + {% elif filter.type == 'boolean' %} + + + {% else %} + {% for value in filter.values %} + + {% endfor %} + {% endif %} +
+ {% endfor %} + + {% if has_active_filter %} + {% for filter in filters %} + {% for active in filter.active_values %} + Remove {{ active }} + {% endfor %} + {% endfor %} + {% endif %} +
+{% endif %} +``` + +**Common filter properties:** + +| Property | Type | Description | +| ----- | ------ | ------ | +| `type` | String | Filter type: `'price_range'`, `'boolean'`, or `'list'`. | +| `label` | String | Display label for the filter. | +| `active_values` | List | List of currently selected filter values. | +| `url_to_remove` | String | URL to remove this active filter. | + +**Price range filter properties:** + +| Property | Type | Description | +| ----- | ------ | ------ | +| `min_value.value` | Decimal | Current minimum price value. | +| `min_value.param_name` | String | Query parameter name for the minimum. | +| `min_value.label` | String | Display label for the minimum input. | +| `max_value.value` | Decimal | Current maximum price value. | +| `max_value.param_name` | String | Query parameter name for the maximum. | +| `max_value.label` | String | Display label for the maximum input. | +| `range_max` | Decimal | Maximum possible range value. | + +**Boolean filter properties:** + +| Property | Type | Description | +| ----- | ------ | ------ | +| `true_value.param_name` | String | Query parameter name for true selection. | +| `true_value.active` | Boolean | Whether true is currently selected. | +| `true_value.count` | Integer | Number of results matching true. | +| `false_value.param_name` | String | Query parameter name for false selection. | +| `false_value.active` | Boolean | Whether false is currently selected. | +| `false_value.count` | Integer | Number of results matching false. | + +**List filter value properties:** + +| Property | Type | Description | +| ----- | ------ | ------ | +| `param_name` | String | Query parameter name for this value. | +| `active` | Boolean | Whether this value is currently selected. | +| `count` | Integer | Number of results matching this value. | +| `value` | String | The filter value. | +| `label` | String | Display label for this value. | + + +## Template Contexts + +All templates receive the [Global Objects](#global-objects) (`store`, `settings`, `currencies`, `languages_active_storefront`, `menus`, `products`, `product_categories`, `posts`, `post_categories`, `privacy_policy`, `terms_and_conditions`, `subscription_terms_and_conditions`, `request`, `storefront_geos`). The table below lists additional view-specific context variables passed to each template. + +| Template | View-Specific Context | +| ----- | ------ | +| `templates/index.html` | Global objects only. Use the [`where`](/docs/storefront/themes/templates/tags#where) tag to query products and categories. | +| `templates/catalogue/product.html` | `product`, `variant_form`, `interval_count_choices` | +| `templates/catalogue/index.html` | `products` (paginated), `paginator`, `page_obj` | +| `templates/catalogue/category.html` | `category`, `products` (paginated), `filters`, `has_active_filter`, `paginator`, `page_obj` | +| `templates/search.html` | `query`, `products` (paginated), `paginator`, `page_obj` | +| `templates/blog/index.html` | `posts` (paginated), `paginator`, `page_obj` | +| `templates/blog/post.html` | `post` | +| `templates/pages/page.html` | `page` | +| `templates/support/index.html` | `categories` | +| `templates/support/category.html` | `category`, `articles` | +| `templates/support/article.html` | `article` | +| `templates/reviews/index.html` | `product`, `reviews` (paginated), `paginator`, `page_obj` | +| `templates/reviews/form.html` | `product`, `form` | +| `templates/reviews/review.html` | `product`, `review` | + + +Use the [`purchase_info_for_product`](/docs/storefront/themes/templates/tags#purchase_info_for_product) tag in any template to get pricing and availability for a product. Use [`cart_form`](/docs/storefront/themes/templates/tags#cart_form) on product pages to generate add-to-cart forms. + + + +**Cart and user data must use the [Storefront GraphQL API](/docs/storefront/graphql).** All storefront pages are fully cached per language and currency combination. Per-user data (cart contents, authentication state, wishlists) rendered in server-side templates would be cached and served to other visitors. Use client-side JavaScript with the GraphQL API for all cart and user interactions. + + + +## Dashboard Cross-Reference + +Some template variables are populated from dashboard settings. Use this reference to understand where data originates when building or debugging templates. + +| Template Variable | Dashboard Path | Description | +| ----- | ------ | ------ | +| `store.branding.logo` | Settings > Branding | Store logo image. | +| `store.branding.icon` | Settings > Branding | Store icon/favicon image. | +| `store.branding.primary_color` | Settings > Branding | Primary brand color (HEX). | +| `store.branding.accent_color` | Settings > Branding | Accent brand color (HEX). | +| `store.name`, `store.tagline` | Settings > General | Store name and tagline. | +| `store.legal_name`, `store.address` | Settings > General | Legal details and address. | +| `menus.{menu_key}.items` | Storefront > Navigation | Navigation menu items (up to 3 levels). | +| `privacy_policy` | Settings > Policies | Privacy policy content. | +| `terms_and_conditions` | Settings > Policies | Terms and conditions content. | +| `subscription_terms_and_conditions` | Settings > Policies | Subscription T&C content. | +| `settings.*` | Storefront > Themes > Customize | Theme settings from `settings_schema.json`. | diff --git a/content/docs/storefront/themes/templates/tags.mdx b/content/docs/storefront/themes/templates/tags.mdx index d450426..1657263 100644 --- a/content/docs/storefront/themes/templates/tags.mdx +++ b/content/docs/storefront/themes/templates/tags.mdx @@ -32,6 +32,47 @@ import AppHookLocations from '../../../../_snippets/_app-hook-locations.mdx'; +### add_query_param + +The `add_query_param` tag appends or updates a query parameter on the current URL. Commonly used for building pagination links and filter URLs while preserving existing query parameters. + +```django title="add_query_param" +{% add_query_param request 'page' page_obj.next_page_number %} +``` + +```django title="Example Pagination with add_query_param" +{% if paginator.num_pages > 1 %} + +{% endif %} +``` + +| Argument | Description | +| --- | --- | +| request | The current `request` context object. | +| param_name | The query parameter name to set, eg `'page'`. | +| value | The value to assign to the parameter. | + +### annotate_form_field + +The `annotate_form_field` tag adds HTML attributes to a form field based on its Django form field properties (required, type, etc.). Useful for adding client-side validation and accessibility attributes. + +```django title="annotate_form_field" +{% annotate_form_field field %} +{{ field }} +``` + ### boolean operators If tags may be used in combination with boolean operators for conditional control flow. @@ -51,6 +92,32 @@ If tags may be used in combination with boolean operators for conditional contro | `<=` | less than or equal to | | `>=` | greater than or equal to | +### cart_form + +The `cart_form` tag generates an add-to-cart form for a product. Required on every product page to enable purchasing. + +```django title="cart_form" +{% cart_form request product 'single' as cart_form %} +``` + +```django title="Example Product Add to Cart Form" +{% cart_form request product 'single' as cart_form %} +
+ {% csrf_token %} + {{ cart_form }} + +
+``` + +| Argument | Description | +| --- | --- | +| request | The current `request` context object. | +| product | The `product` context object. | +| form_type | The form type, typically `'single'`. | +| variable | Assigned template variable name for the form. | + ### comment Ignores everything between `{% comment %}` and `{% endcomment %}`. An optional note may be inserted in the first tag. For example, this is useful when commenting out code for documenting why the code was disabled. @@ -62,6 +129,27 @@ Ignores everything between `{% comment %}` and `{% endcomment %}`. An optional n {% endcomment %} ``` +### core_js + +The `core_js` tag outputs the platform's core JavaScript bundle. This is required in every theme's base layout and powers cart functionality, AJAX form submissions, CSRF token handling, and other platform features. + +```django title="core_js" +{% core_js %} +``` + +```django title="Example Placement in Base Layout" + {# jQuery must be loaded before core_js #} + + {% core_js %} + + + +``` + + +jQuery must be loaded before `{% core_js %}`. The platform's core JavaScript depends on jQuery being available in the global scope. + + ### csrf_token This tag is used for CSRF protection and required on any template with a form that sends a POST request to the back end. @@ -211,6 +299,48 @@ The `purchase_info_for_product` tag is used to retrieve the price of a product i | product | Must pass the current `product` context object. | +### purchase_info_for_line + +The `purchase_info_for_line` tag retrieves the price and availability of a cart line item in the current session's currency. Works the same as `purchase_info_for_product` but accepts a cart line object. + +```django title="purchase_info_for_line" +{% purchase_info_for_line request line as session %} +{% if session.price.exists %} + {{ session.price.price|currency:session.price.currency }} +{% endif %} +``` + +| Argument | Description | +| --- | --- | +| request | Must pass the current `request` context object. | +| line | Must pass a cart `line` context object. | + +### render_field + +The `render_field` tag renders a form field with additional HTML attributes. Use it to add CSS classes, placeholders, and other attributes to Django form fields in templates. + +```django title="render_field" +{% render_field field class+="form-control" placeholder="Enter your email" %} +``` + +```django title="Example Form with render_field" +
+ {% csrf_token %} +
+ + {% render_field field class+="form-control" %} + {% if field.errors %} +
{{ field.errors.0 }}
+ {% endif %} +
+
+``` + +| Argument | Description | +| --- | --- | +| field | The form field object to render. | +| attributes | HTML attributes to add, using `attr="value"` or `attr+="value"` (append) syntax. | + ### seo The `seo` tag generates SEO meta data for products in standardized format for consumption by 3rd party systems. diff --git a/content/docs/storefront/themes/templates/urls-and-template-paths.mdx b/content/docs/storefront/themes/templates/urls-and-template-paths.mdx index 51e23bc..f7f1fde 100644 --- a/content/docs/storefront/themes/templates/urls-and-template-paths.mdx +++ b/content/docs/storefront/themes/templates/urls-and-template-paths.mdx @@ -15,6 +15,13 @@ import IntroTheme from '../../../../_snippets/_view-intro-theme.mdx'; Ensure your template paths match with expected template paths for built-in storefront views. Use the public themes on [Github](https://github.com/NextCommerceCo/) as a reference guide and starting point. All URL paths are automatically localized to the users language following your store's Localization settings. + +### Homepage + +| URL Name | URL Path | Template Path | +| --- | --- | --- | +| N/A | / | templates/index.html | + ### Blog | URL Name | URL Path & Arguments | Template Path | @@ -27,6 +34,10 @@ Ensure your template paths match with expected template paths for built-in store | URL Name | URL Path | Template Path | | --- | --- | --- | | cart:summary | /cart/ | templates/cart.html | +| cart:add | POST /cart/add/:product_slug/ | N/A (action endpoint) | +| cart:saved | /cart/saved/ | templates/cart.html (saved items) | +| cart:vouchers-add | POST /cart/vouchers/add/ | N/A (action endpoint) | +| cart:vouchers-remove | POST /cart/vouchers/remove/:voucher_id/ | N/A (action endpoint) | ### Catalogue @@ -68,10 +79,35 @@ Ensure your template paths match with expected template paths for built-in store | URL Name | URL Path | Template Path | | --- | --- | --- | -| support:cateogry-list | /support/categories/ | templates/support/index.html | +| support:category-list | /support/categories/ | templates/support/index.html | | support:article-list | /support/categories/:category_slug/ | templates/support/category.html | | support:article-detail | /support/articles/:article_slug/ | templates/support/article.html | +### Customer / Authentication + +| URL Name | URL Path | Template Path | +| --- | --- | --- | +| customer:login | /accounts/login/ | N/A (platform-managed) | +| customer:logout | /accounts/logout/ | N/A (platform-managed) | +| customer:summary | /accounts/ | N/A (platform-managed) | +| customer:support-ticket-create | /accounts/support/create/ | N/A (platform-managed) | + +### Localization + +These are POST action endpoints used in forms for switching language, currency, or storefront geo. + +| URL Name | Method | Description | +| --- | --- | --- | +| set_language | POST | Change the active language. | +| core:set-currency | POST | Change the active currency. | +| core:set-storefront | POST | Change the active storefront geo (country, language, currency). | + +### API + +| URL Name | URL Path | Description | +| --- | --- | --- | +| storefrontapi:graphql | /api/graphql/ | [Storefront GraphQL API](/docs/storefront/graphql) endpoint. | + ### Error Pages | URL Name | URL Path | Template Path |