SmartEdit Contract in Spartacus
Note: Spartacus 2.x is no longer maintained. Please upgrade to the latest version.
The following sections describe how the SmartEdit Contract is implemented in Spartacus.
For information on setting up SmartEdit in Spartacus, see SmartEdit Setup Instructions for Spartacus.
For general information on SmartEdit Contracts, see SmartEdit Contract for Storefronts.
SmartEdit contract implementation
To make Spartacus work with SmartEdit, we need implement the SmartEdit contract in Spartacus.
The SmartEdit Contract consists of the following
1. The webApplicationInjector.js file that must be included in each page
SmartEdit Setup Instructions for Spartacus has the details of how to include this js file into your app.
2. A preview ticket API mechanism
2.1. Get cmsTicketId
(also called previewToken
)
When Spartacus is launched in SmartEdit, SmartEdit sends a request to Spartacus with cmsTicketId
as the parameter.
e.g. https://localhost:4200/cx-preview?cmsTicketId=6477500489900224fda62f41-167a-40fe-9ecc-39019a64ebb9
By default, SmartEdit appends /cx-preview
to the storefront URI so that it can preview your storefront. But you can configure SmartEdit to route the request to the another endpoint in your app. Use the storefrontPreviewRoute property in an impex to specify your custom storefront route as shown in the following example:
INSERT_UPDATE SmartEditConfiguration;key[unique=true];value
;storefrontPreviewRoute;"""my-custom-preview"""
cmsTicketId
is generated in backend. It contains many information required by SmartEdit, such as site-id
or catalogVersion
. For the details, pleae read “Preview API” section in SmartEdit Contract for Storefronts.
Spartacus gets cmsTicketId
from the request sent from SmartEdit.
2.2. Smartedit Interceptor
To make SmartEdit be able to load pages in Spartacus, it needs to get all the required context data, which includes site, content catalog, and content catalog version, and can also be for a specified language, or date and time. Therefore, cmsTicketId
needs to be appended to any CMS requests sent from Spartacus to backend.
In Spartacus, we have CmsTicketInterceptor
. If cmsTicketId
exists and requests are cms
specified, it adds cmsTicketId
as one of the request parameters.
e.g. https://localhost:9002/rest/v2/electronics-spa/cms/pages?fields=DEFAULT&lang=en&curr=USD&cmsTicketId=6477500489900224fda62f41-167a-40fe-9ecc-39019a64ebb9
3. HTML Markup Contract
The HTML markup contract stipulates that every CMS component and every content slot must be wrapped in an HTML tag and include specific elements.
3.1 properties
in CMS items received from backend
Sending CMS requests with cmsTicketId
, there will be properties
field in the response JSON data. properties
contains groups of dynamic attribute required for the containing CMS items. For example, properties
in CMS page may have these data:
...
"label" : "homepage",
"properties" : {
"smartedit" : {
"classes" : "smartedit-page-uid-homepage smartedit-page-uuid-eyJpdGVtSWQiOiJob21lcGFnZSIsImNhdGFsb2dJZCI6ImVsZWN0cm9uaWNzLXNwYUNvbnRlbnRDYXRhbG9nIiwiY2F0YWxvZ1ZlcnNpb24iOiJTdGFnZWQifQ== smartedit-catalog-version-uuid-electronics-spaContentCatalog/Staged"
}
}
}
In the group smartedit
, there is classes
. It is the required SmartEdit contract for this CMS page. So, we need add these “classes” into the class list of the html body tag. If you check the html page source, you will see the body tag has the “classes”.
<body class="smartedit-page-uid-homepage smartedit-page-uuid-eyJpdGVtSWQiOiJob21lcGFnZSIsImNhdGFsb2dJZCI6ImVsZWN0cm9uaWNzLXNwYUNvbnRlbnRDYXRhbG9nIiwiY2F0YWxvZ1ZlcnNpb24iOiJTdGFnZWQifQ== smartedit-catalog-version-uuid-electronics-spaContentCatalog/Staged">
<cx-storefront ng-version="8.0.0" class="stop-navigating"><header><cx-page-layout section="header" ng-reflect-section="header" class="header"><!--bindings={
...
CMS slots and components also contain the properties
. We need add these attributes to component/slot tags. The following is an exmpple of “HelpLink” component.
{
"uid" : "HelpLink",
"uuid" : "eyJpdGVtSWQiOiJIZWxwTGluayIsImNhdGFsb2dJZCI6ImVsZWN0cm9uaWNzLXNwYUNvbnRlbnRDYXRhbG9nIiwiY2F0YWxvZ1ZlcnNpb24iOiJTdGFnZWQifQ==",
"typeCode" : "CMSLinkComponent",
"modifiedTime" : "2019-07-02T13:44:27.77-04:00",
"name" : "Help Link",
"container" : "false",
"external" : "false",
"url" : "/faq",
"linkName" : "Help",
"properties" : {
"smartedit" : {
"catalogVersionUuid" : "electronics-spaContentCatalog/Staged",
"componentType" : "CMSLinkComponent",
"componentId" : "HelpLink",
"classes" : "smartEditComponent",
"componentUuid" : "eyJpdGVtSWQiOiJIZWxwTGluayIsImNhdGFsb2dJZCI6ImVsZWN0cm9uaWNzLXNwYUNvbnRlbnRDYXRhbG9nIiwiY2F0YWxvZ1ZlcnNpb24iOiJTdGFnZWQifQ=="
}
},
"target" : "false"
}
In the page source, you will see this:
<cx-link data-smartedit-catalog-version-uuid="electronics-spaContentCatalog/Staged" data-smartedit-component-type="CMSLinkComponent" data-smartedit-component-id="HelpLink" class="smartEditComponent" data-smartedit-component-uuid="eyJpdGVtSWQiOiJIZWxwTGluayIsImNhdGFsb2dJZCI6ImVsZWN0cm9uaWNzLXNwYUNvbnRlbnRDYXRhbG9nIiwiY2F0YWxvZ1ZlcnNpb24iOiJTdGFnZWQifQ==" data-smart-edit-component-process-status="removeComponent" data-smartedit-element-uuid="8505cd4a-11b3-4fc8-b278-6f8ff74e50b3" style="position: relative;">
3.2 DynamicAttributeService
In Spartacus, we have DynamicAttributeService
. It can add dynamic attributes to DOM. These attributes are extracted from the properties
of CMS items received from backend.
Note: There can by many different groups of properties, one of them is smaredit
. But EC allows addons to create different groups. For example, personalization may add script
group etc.
To add SmartEdit HTML Markup contract to Slot, we have this function:
private addSmartEditContract(slot: ContentSlotData): void {
this.dynamicAttributeService.addDynamicAttributes(
slot.properties,
this.hostElement.nativeElement,
this.renderer
);
}
4. Rerendering Components and Content Slots After Editing
After the user makes changes to components or content slots, the user will want to see the changes reflected on the page. SmartEdit optimizes this by rerendering only the changed content.
For frontend-rendered pages, the storefront rerenders the pages and not SmartEdit. In this case, Spartacus implements the renderComponent function in the window.smartedit namespace
as shown in the following code excerpt:
window.smartedit.renderComponent = function(componentId, componentType, parentId) { ... };
If parentId
does not exist, the CMS item is a slot, then renderComponent
actually refresh the whole CMS page. If parentId
exists, the CMS item is component. Only this CMS component is refreshed.
Default Preview Category/Product
Each site has defaultPreviewCategory
, defaultPreviewProduct
and defaultPreviewCatalog
. For example:
UPDATE CMSSite;uid[unique=true];defaultPreviewCategory(code, $productCV);defaultPreviewProduct(code, $productCV);defaultPreviewCatalog(id)
;$spaSiteUid;575;2053367;$productCatalog
When open category or product pages in SmartEdit, you will find that not only the CMS pages are loaded, the default preview product/category is also loaded.
In SmartEdit, product with code 2053367 is opened in the product details page:
Same for the category page, category 575 is opened in the product list page:
WCMS Cockpit Preview URL and Spartacus Context
The WCMS Cockpit Preview URL must match the default context for your Spartacus web site.
For example, if you go to https://localhost:4200
, you will see the default URL path (or context), such as https://localhost:4200/en/USD
. The Preview URL (set in Backoffice) must match the default context uses, or errors will occur using SmartEdit. The default context installed by Spartacus Schematics is https://localhost:4200/en/USD
.