10 Content - ecellar/remote-widgets GitHub Wiki
The eCellar Designer Widgets system provides a separation of “markup” (HTML) and “content” (data and wording). These are combined to render what your site visitor sees.
The markup comes from 08 HTML Templates.
The content can come from either:
A. The winery’s database
or
B. Messages managed by the SPA
Let’s look at a relatively large template:
This template has various “placeholders” that are wrapped in curly braces, like this:
{message:product_name}
At runtime, the SPA replaces each placeholder with its specified data or message.
In this example, the placeholder will be replaced by the product’s product_name
datapoint, resulting in something like “2015 Cabernet Sauvignon
”.
This is another placeholder in the ProductDetail template:
{message:ProductDetail/AddToCartButton}
This one specifies that the system’s ProductDetail/AddToCartButton
message should be used to replace the placeholder. At runtime that might result in something like “Add To Cart”.
Messages are stored as JSON-formatted data loaded as needed by the SPA. The SPA supports internationalization and messages can be provided in any language. We provide the English (“en”) version.
Each HTML template used by the SPA is grouped under a specific widget (Products, Cart, Checkout, Account, etc). Corresponding messages are grouped in the same way.
This is part of the “en” JSON content used by the Products widget. It shows the messages for the ProductDetail template:
{
"en": {
"epub": {
"products": {
"ProductDetail": {
"AddToCartButton": "Add To Cart",
"AddMoreToCartButton": "Add More To Cart",
"CartCount_template": "You have {cart_quantity}",
"TechnicalNotesTitle": "Winemaker Notes",
"ReviewNotesTitle": "Reviews",
"ViewPDFLink": "View PDF Factsheet",
"SecondaryNotesTitle": "Additional notes",
"Status": {
"BackOrdered": "This item is back-ordered",
"Call": "Currently unavailable: please call",
"Discontinued": "This item has been discontinued",
"PreOrdered": "This item is pre-ordered",
"RestrictedAllocated": "This item is allocated",
"RestrictedWineClub": "This item is for club members",
"SoldOut": "This item is sold out",
"Unknown": "This item is unavailable"
}
}
}
}
}
}
If you refer back to our earlier example:
{message:ProductDetail/AddToCartButton}
You will see the corresponding message in the JSON, here:
"AddToCartButton": "Add To Cart"
The SPA locates that message by:
a) looking for the JSON for the Products (as lowercase “products”) widget
b) looking for a key named “ProductDetail”
c) looking for a key under that named “AddToCartButton”
I then takes the message found there and replaces the template’s placeholder with it. The template is then rendered, displaying “Add To Cart”.
You may have noticed that the examples above all have message:
at the beginning of the placeholder. That is a formatting instruction. It means “treat the content as a string-based message”.
There are other formatters available:
- number
: formats number into a string appropriate for the active locale. Uses the correct decimal and thousands separators.
- currency
: formats number into a string appropriate for the active locale in US Dollars. Uses the correct decimal and thousands separators.
- datetime
: formats a javascript date object into a string appropriate for the active locale and adjusted to the local timezone. Defaults to ll (localized short date) format, can be customized by including the format in your merge string: {datetime:LL:create_date}. If you want to use a fully customized format string be sure to replace any “:” characters with pipes “|” which will ultimately output in the string as colons. Example: {datetime:YYYY-MM-DD HH|mm:create_date}. See http://momentjs.com/docs/#/displaying/ for full details.
Examples:
{number:display_order} & {display_order: 582940} && {locale:"en"} == "582,940"
{number:display_order} & {display_order: 582940} && {locale:"de"} == "582.940"
{currency:cart_regular_price} & {cart_regular_price: 27.99} && {locale:"en"} == "$27.99"
{currency:cart_regular_price} & {cart_regular_price: 27.99} && {locale:"de"} == "$27,99"
{datetime:order_date} & {order_date: "2018-09-25T23:05:50.695Z"} && {locale:"en"} == "Sep 25, 2018"
{datetime:order_date} & {order_date: "2018-09-25T23:05:50.695Z"} && {locale:"de"} == "25. Sep. 2018"
{datetime:YYYY-MM-DD HH|mm:order_date} & {order_date: "2018-09-25T23:05:50.695Z"} && {localTimeZone:"PDT"} == "2018-09-25 16:19"
Templates sometimes have placeholders that might seem a little odd at first. Here are some examples:
Looks like it should use a number
formatter, but it doesn’t:
<div data-ecp-id="{message:product_id}">
The product_id is known to be a number, but we use the message
formatter just in case we start using string-based id’s.
Message is a URL:
<img src="{message:header_image}">
We are using a placeholder for the src
url in an HTML img
element. The data from the db comes to the SPA as a fully formed URL, so this works just fine.
Message that’s a self-contained template:
{message:ProductDetail/CartCount_template}
Notice that the lookup key name has _template
tacked on the end of it. That does not serve any functional purpose: it’s a standard that we use to indicate that the value found in the key has at least one placeholder inside of it (it could have more than one).
In the JSON, the key has this value:
"CartCount_template": "You have {cart_quantity}"
The SPA gets the CartCount_template and then replaces the {cart_quantity}
placeholder with the current cart’s cart_quantity
data, resulting in something like this:
You have 12
You may customize messages, add your own and create messages for multiple languages.
To learn more, go to our 11 Custom Messages page.