4.1. Maintenance of existing Commerce Cloud content pages
The FirstSpirit Connect module enables editors to maintain content pages that already exist in Commerce Cloud in FirstSpirit.
For this purpose, the content pages are displayed in ContentCreator via Omnichannel Manager, enabling them to be seamlessly integrated into the familiar FirstSpirit editorial process.
As well as integrating Omnichannel Manager, which is an installation step, the presentation channel of the page and section templates must be completed in order to maintain content pages in FirstSpirit.
In addition, the relevant page template must also be modified in Commerce Cloud.
Generally, content pages in a FirstSpirit project are edited based on a FirstSpirit page reference.
This reference and the page on which it is based must be created for content pages that already exist in Commerce Cloud.
In the FirstSpirit Connect Reference Project, the creation of this page reference and the associated page takes place in the background, in a process that is invisible to the editor.
The script page_type_mapping
uses the page template of the Commerce Cloud page to determine the corresponding FirstSpirit page template, which is referenced in the project settings.
When a content page is created, the ID of the associated Commerce Cloud page is stored in its form.
This ID is required to display the page in the preview.
The page template therefore contains the hidden input component pt_cc_identifier
.
If additional page templates are added to the project, their form must also contain this input component.
Input component pt_cc_identifier.
<CMS_INPUT_TEXT name="pt_cc_identifier" hFill="yes" hidden="yes" useLanguages="no">
<LANGINFOS>
<LANGINFO lang="*" label="Commerce Cloud Identifier"/>
</LANGINFOS>
</CMS_INPUT_TEXT>
The following code extract shows a shortened form of the presentation channel for the page template in the reference project:
Presentation channel for the page template.
$CMS_TRIM(level:1)$
$CMS_SET(json, {:})$
$CMS_SET(previewId, previewId(element:#global.node))$
$CMS_SET(void, json.put("previewId", "" + previewId))$
$CMS_SET(void, json.put("pageRevisionId", #global.page.revision.id))$
$CMS_SET(slotList, {:})$
$CMS_IF(#global.page.body("stage_body").children.toList().size > 0)$
$CMS_SET(dynamicContent, {:})$
$CMS_SET(content)$
$CMS_TRIM(level:4)$$CMS_VALUE(#global.page.body("stage_body"))$$CMS_END_TRIM$
$CMS_END_SET$
$CMS_SET(stage_body, {:})$
$CMS_SET(void, stage_body.put("content", content.toString))$
$CMS_SET(void, stage_body.put("dynamic",
if(dynamicContent.get("active") != null, dynamicContent.get("active"), false)))$
$CMS_SET(void, slotList.put("stage_body", stage_body))$
$CMS_END_IF$
[...]
$CMS_SET(void, json.put("slots", slotList))$
$CMS_VALUE(json.toJSON)$
$CMS_END_TRIM$
The page has three content areas - the stage_body
, tiles_body
, and main_body
- and represents a landingLayout2Page.jsp
page.
While the first two content areas are used to edit existing content from Commerce Cloud, the third allows further sections to be added.
In the reference project, the section templates banner_section
, category_teaser_section
, and text_picture_section
are available for this purpose.
The content of these templates is added to the JSON object slots
generated in the template.
For this purpose, two instructions are required for each content area to enable the system to distinguish between static and dynamic content.
Dynamic content can only be incorporated into combined text-image sections, as this is the only type of section that can include dynamic product data.
The section uses the link template a_product_price_link
, with the value of the active
parameter in the presentation channel configured as true
for the dynamicContent
variable.
In addition to the editorial content, the previewId
and pageRevisionId
of the page reference are also transferred to the JSON object created in the template:
The previewId
is stored in the PAGE_PREVIEW_DATA
object in the template in Commerce Cloud, and is used to identify the page reference.
Identification takes places via the JavaScript of Omnichannel Manager.
The pageRevisionId
is a technical dependency field and ensures that dynamic content is always displayed correctly in ContentCreator.
The JSON object is part of the CaaS item to be generated and can be read out within the Commerce Cloud templates.
The slots contained within a Commerce Cloud page are represented in FirstSpirit by the sections banner_section
, category_teaser_section
, and text_picture_section
.
If a corresponding content page is to be created in the FirstSpirit project for an existing Commerce Cloud page, the relevant sections are created automatically and populated with the existing content.
The following code extract shows the presentation channel for the text-image section from the reference project:
Presentation channel for the text-image section.
<div data-preview-id="$CMS_VALUE(previewId())$">
[...]
<div class="yCmsComponent" style="margin: 20px;">
$CMS_IF(!st_headline.isEmpty())$
<h1 style="text-align:center;">$CMS_VALUE(st_headline.convert2)$</h1>
$CMS_END_IF$
$CMS_IF(!st_picture.isEmpty())$
<img
data-preview-id="$CMS_VALUE(previewId(element:st_picture))$"
class="js-responsive-image"
style="margin: 20px;float:$CMS_VALUE(st_picturePosition, default:"left")$"
$CMS_IF(!st_pictureDescription.isEmpty())$
title="$CMS_VALUE(st_pictureDescription.convert2)$"
alt="$CMS_VALUE(st_pictureDescription.convert2)$"
$CMS_END_IF$
data-media="{}"
src="$CMS_REF(st_picture,resolution:"CATEGORY_TEASER_ITEM",abs:1)$">
$CMS_END_IF$
$CMS_IF(!st_text.isEmpty())$
$CMS_VALUE(st_text)$
$CMS_END_IF$
</div>
[...]
</div>
This section has various input components for entering a heading and text and adding an image with a definable position and image description.
The heading, text and image are displayed within a DIV, with a data-preview-id
attribute configured to the value $CMS_VALUE(previewId())$
.
This attribute serves to decorate and identify the section; again, this process is executed by the JavaScript of Omnichannel Manager.
To enable media-specific actions, such as release or image cropping, the same attribute is also provided for the img tag.
4.1.3. Commerce Cloud Page Template
In FirstSpirit, the editorial content is created and edited in ContentCreator.
With the help of the Omnichannel Manager, the staged storefront of the Commerce Cloud is embedded in it.
The Staged Storefront in turn accesses the Preview CaaS and determines the current FirstSpirit contents from it.
This also applies to the online storefront and the Online CaaS.
This link requires modifications to the page template of the Commerce Cloud content page; these modifications are explained in this chapter.
The modifications are contained in the landingLayout2Page.jsp
page, which is part of the delivery, and can be reproduced in this page.
The following code extract shows the querying of a CaaS item that is saved in the variable caasItem
.
The first step of this process is to determine the CaaS collection in which the data is stored:
The FirstSpirit content pages from the reference project are always stored in the contentpages collection, while other content is stored in the standard collection content.
Example - Querying of the CaaS item.
<%@ taglib prefix="caas" uri="/WEB-INF/tld/addons/fscontentconnect/caas.tld" %>
<c:choose>
<c:when test="${cmsPage.typeCode == 'ContentPage'}">
<c:set var="caasCollection" value="contentpages"/>
</c:when>
<c:otherwise>
<c:set var="caasCollection" value="content"/>
</c:otherwise>
</c:choose>
<caas:request itemId="${cmsPage.uid}" collection="${caasCollection}" var="caasItem" />
To edit editorial content, ContentCreator displays the familiar EasyEdit buttons, which appear together with a frame while hovering.
Via Omnichannel Manager, ContentCreator can display external content.
However, Omnichannel Manager requires information from Commerce Cloud to highlight this content.
This information is read from a data object, which is populated via the corresponding page template in Commerce Cloud.
The following code extract shows an example of how this type of data object may be populated; the page type, preview ID, and page ID are transferred to this object.
The preview ID matches the ID of the previously determined CaaS item.
If it was not possible to query a CaaS item, the preview ID in the data object remains empty.
Example - Population of a data object.
[... Determine the CaaS item (see above) ...]
<c:set var="pagePreviewId" value="${not empty caasItem and not empty caasItem['previewId'] ? caasItem['previewId'] : ''}"/>
<caas:whenFirstSpiritPreview>
<script type="text/javascript">
const PAGE_PREVIEW_DATA = {
pageType: '${cmsPage.typeCode}',
pagePreviewId: '${pagePreviewId}',
pageId: '${cmsPage.uid}',
pageTemplate: '${cmsPage.masterTemplate.uid}'
};
</script>
</caas:whenFirstSpiritPreview>
|
For product detail pages, the product code must be defined as the page ID instead of the UID:
Example - Defining the product code.
const PAGE_PREVIEW_DATA = {
[...]
pageId: '${productCode}',
[...]
};
|
In addition to determining the CaaS item and populating the data object, the output must also be defined.
As part of this process, a check is needed whether the previously determined CaaS item includes content for the relevant content area.
If this is not the case, fallback content can be defined.
The following code extract shows the definition of the output for the content area stage_body
:
Example - Definition of output.
<%@ taglib prefix="caas" uri="/WEB-INF/tld/addons/fscontentconnect/caas.tld" %>
[... Determine the CaaS item and set the PAGE_PREVIEW_DATA object (see above) ...]
<c:choose>
<c:when test="${not empty caasItem and not empty caasItem['slots']['stage_body']}">
<div data-slot-name="stage_body">
${caasItem['slots']['stage_body']}
</div>
</c:when>
<c:otherwise>
<div data-slot-name="stage_body" data-fs-content-editing>
<cms:pageSlot position="Section1" var="feature">
<cms:component component="${feature}"/>
</cms:pageSlot>
</div>
</c:otherwise>
</c:choose>
Whether the outcome is positive or the fallback is applied, a Dom element must be defined to mark the FirstSpirit content area.
This element allows external content to be visually highlighted and maintained in ContentCreator.
The name of the content area must be transferred to the Dom element via the data-slot-name
attribute.
In the event of a fallback, the Dom element also requires the attribute data-fs-content-editing
.
This attribute controls the display of a plus button in ContentCreator, which shows the label override content
or add content
when hovering.
- override content
-
If the fallback is applied and existing content from Commerce Cloud is displayed, the button is displayed with the override content
label while hovering.
This means that there is not yet any content in FirstSpirit for the content area.
For this reason, the existing content can only be overwritten and not edited.
The previously described code extract shows this option.
- add content
-
If the fallback is applied and the Dom element does not contain any content, the button is displayed with the add content
label while hovering.
This situation can arise when there is no content on an empty page for the area in Commerce Cloud, or if no content has been defined for the Dom element.
Within the landingLayout2Page.jsp
page, which is included in the delivery, this option is used for the output of the main_body
content area:
Example - Fallback for output of main_body content area.
<c:choose>
<c:when test="${not empty caasItem and not empty caasItem['slots']['main_body']}">
[... show Content ...]
</c:when>
<c:otherwise>
<div data-slot-name="main_body" data-fs-content-editing></div>
</c:otherwise>
</c:choose>
4.2. Maintaining content on new Commerce Cloud content pages
The maintenance of content on new Commerce Cloud content pages is subject to the same requirements as the maintenance of existing Commerce Cloud content pages.
However, the creation of new pages must be configured in the project component.
Once this configuration is complete, the familiar ContentCreator functions can be used to create new pages.
|
The label attribute of new Commerce Cloud content pages is set by the FirstSpirit Connect module and by default starts with a slash (/ ).
|
The FirstSpirit Connect module allows the maintenance of dynamic content.
This content is code that is defined in the presentation channel of the FirstSpirit template and stored in the generated CaaS item.
This content is evaluated when the content area is output in the Commerce Cloud page template.
Modifications in FirstSpirit
In the supplied reference project, the dynamic content is integrated via the link template a_product_price_link
.
This can be used in text-image sections and uses the template language Apache Velocity to integrate the name and price of a product.
To do so, it accesses the context objects productOptions
and productFacade
, which provides the add-on in the storefront during the evaluation process:
The following code extract shows the presentation channel of the link template a_product_price_link
in the reference project:
Presentation channel for the link template.
$CMS_SET(productCode,lt_productRef.values.iterator.next.getValueMap().get("code"))$
$CMS_SET(void,dynamicContent.put("active",true))$
<span data-dynamic-content="true">
#set( $product = $productFacade.getProductForCodeAndOptions("$CMS_VALUE(productCode)$", $productOptions))
#if( $product )
<a href="$CMS_RENDER(template:"product_link_render", prodRef:lt_productRef)$">
$product.getName()
#set( $priceData = $product.getPrice())
#if ( $priceData )
($priceData.getFormattedValue())
#end
</a>
#end
</span>
Within the template, the first action is to determine the product code of the referenced product and to transfer it to the getProductForCodeAndOptions
method together with the productOptions
context object.
This step ensures that all product information is available within the product
variable.
The dynamicContent
variable is needed to determine the product information to be used in the generation of the CaaS item.
This variable is evaluated in the FirstSpirit page template and the active
parameter must be set to true
.
Unlike static content, dynamic content is pulled from the staged storefront for display in ContentCreator, so it must be identifiable.
For this purpose, this content must be enclosed in a Dom element with the attribute data-dynamic-content
set to true
.
Furthermore, the page template must also indicate the pageRevisionId
.
This ID is used to ensure that the revision of the CaaS item always corresponds to the pages displayed in ContentCreator and allows the content to be updated if necessary.
The dynamic content must be queried from the staged storefront as the initial evaluation of this content takes place in this location.
If the content were to be determined directly from FirstSpirit, like static content, ContentCreator would only show the code defined for it in the presentation channel.
Modifications in Commerce Cloud
The code for dynamic content is evaluated in the Commerce Cloud page template.
This evaluation is executed during access to the relevant content area within the result object of the caas:request tag; the process returns a string.
The output is therefore the same as that for static content and is defined as such.
The following code extract shows a shortened form of the definition of the output for the content area stage_body
on the landingLayout2Page.jsp
page, which is included in the delivery:
Example - Definition of output.
<%@ taglib prefix="caas" uri="/WEB-INF/tld/addons/fscontentconnect/caas.tld" %>
[... Determine the CaaS item and set the PAGE_PREVIEW_DATA object (see above) ...]
<c:choose>
<c:when test="${not empty caasItem and not empty caasItem['slots']['stage_body']}">
<div data-slot-name="stage_body">
${caasItem['slots']['stage_body']}
</div>
</c:when>
<c:otherwise>
[...]
</c:otherwise>
</c:choose>
4.4. Maintaining content on product detail pages
To maintain content on product detail pages, in addition to the relevant storefront expansions, the modifications to the presentation channel of the templates - as described in chapter Maintenance of existing Commerce Cloud content pages - must also have been implemented.
Once these requirements are met, product detail pages can be maintained in the same way as content pages.
|
Product detail and content pages must be stored in different structure and content folders in FirstSpirit and in different collections in CaaS.
|
4.5. Deleting content pages managed in FirstSpirit
When maintaining content on CCommerce Cloud content pages, FirstSpirit is the leading system used to manage and delete pages.
The FirstSpirit executable CMSItemRemoval
can be used to delete these pages from Commerce Cloud.
This executable can be called up by entering an itemUid
parameter that contains the UID of the page reference to be deleted.
Alternatively, the executable can be used within a workflow.
In such cases, ensure that a trigger_finish_full
transition exists, as the executable will move on to this transition once deletion has been completed successfully.
This allows the deletion of pages from Commerce Cloud to be integrated into a deletion workflow.
The following code extract shows the call-up of the executable within a script.
Call-up of the CMSItemRemoval executable.
#!executable-class
com.espirit.moddev.contentconnect.sap.module.catalogs.cmsitem.CMSItemRemoval
|
After deleting a page, the editor is redirected to the start page.
|
4.8. Generating the navigation structure
The FirstSpirit Connect module allows the navigation structure to be generated in FirstSpirit.
The generation process produces a JSON document in CaaS.
To use this function, a navigation function that generates the JSON document is required.
The following code extract shows an example of this kind of function, taking into account all of the elements in the structure folder contentpages
.
Navigation function.
<CMS_HEADER>
<CMS_FUNCTION name="Navigation" resultname="nav">
<CMS_PARAM name="root" value="pagefolder:contentpages" />
<CMS_PARAM name="expansionVisibility" value="all"/>
<CMS_PARAM name="siteMap" value="0" />
<CMS_ARRAY_PARAM name="beginHTML">
<CMS_ARRAY_ELEMENT index="0..4">{</CMS_ARRAY_ELEMENT>
</CMS_ARRAY_PARAM>
<CMS_ARRAY_PARAM name="delimiter">
<CMS_ARRAY_ELEMENT index="0..4">,</CMS_ARRAY_ELEMENT>
</CMS_ARRAY_PARAM>
<CMS_ARRAY_PARAM name="selectedDelimiter">
<CMS_ARRAY_ELEMENT index="0..4">,</CMS_ARRAY_ELEMENT>
</CMS_ARRAY_PARAM>
<CMS_ARRAY_PARAM name="innerBeginHTML">
<CMS_ARRAY_ELEMENT index="0..3">,"children":[</CMS_ARRAY_ELEMENT>
</CMS_ARRAY_PARAM>
<CMS_ARRAY_PARAM name="unselectedHTML">
<CMS_ARRAY_ELEMENT index="0..4">
"label":"$CMS_VALUE(#nav.label)$",
"id":"$CMS_VALUE(#nav.id)$",
"pageRef":"$CMS_VALUE(#nav.ref.getUid())$"
</CMS_ARRAY_ELEMENT>
</CMS_ARRAY_PARAM>
<CMS_ARRAY_PARAM name="selectedHTML">
<CMS_ARRAY_ELEMENT index="0..4">
"label":"$CMS_VALUE(#nav.label)$",
"id":"$CMS_VALUE(#nav.id)$",
"pageRef":"$CMS_VALUE(#nav.ref.getUid())$"
</CMS_ARRAY_ELEMENT>
</CMS_ARRAY_PARAM>
<CMS_ARRAY_PARAM name="innerEndHTML">
<CMS_ARRAY_ELEMENT index="0..3">]</CMS_ARRAY_ELEMENT>
</CMS_ARRAY_PARAM>
<CMS_ARRAY_PARAM name="endHTML">
<CMS_ARRAY_ELEMENT index="0..4">}</CMS_ARRAY_ELEMENT>
</CMS_ARRAY_PARAM>
</CMS_FUNCTION>
</CMS_HEADER>{"navigation":[$CMS_IF(!nav.isEmpty)$$CMS_VALUE(nav)$$CMS_END_IF$]}
The execution of this function requires a page and a page reference based on this page, which must also be created.
|
The page reference must contain the reference name main_navigation .
|
|
The navigation function shown only incorporates the start page of a menu level.
If you wish to incorporate all page references, the function must be modified accordingly.
|
Each time an element is created, modified, moved, or deleted in the structure area, the FirstSpirit Connect module starts generating the page reference main_navigation
.
As a result, the document in CaaS always reflects the most up-to-date navigation structure in FirstSpirit.
The CaaS configuration for the higher level structure folder determines which collection the document will be stored in.
The name of the document saved in CaaS is main_navigation_<LANGUAGE>
.
4.11. Calling up a content page or product/category detail page
Content pages as well as product and category detail pages can be accessed via the shop navigation and via the product, category or search report.
In the report, these pages are called up by clicking on one of them.
Thereby detail pages that are not yet available in the shops main navigation can also be called up.
To determine the URL of product and category detail pages, the reports use the URLs from the fields PDP URL
and CDP URL
that must be specified during the configuration of the project component.
Content pages can have specific URLs that are optionally specified during the definition of the Template Mappings
.
If a content page does not have a specific URL, the general Contentpage URL
is used for it instead.
If one of these fields contains a relative URL, this is converted into an absolute URL based on the URL of the current shop page.
|
The product report shows all of the products in the configured product catalog.
This means that the detail pages of all products in the catalog must be accessible.
To ensure that this is the case, the configuration of the FlexibleSearch Restrictions must be checked.
|
4.12. Editing page attributes
In contrast to the delivery of content, its creation and maintenance shifts from the Commerce Cloud to FirstSpirit.
Therefore FirstSpirit provides the ContentCreator.
In it, both new and existing Commerce Cloud pages can be displayed and edited.
The maintenance of specific page attributes, such as a SEO URL, requires a corresponding FirstSpirit page template for all Commerce Cloud content pages.
This has a form consisting of various input components that are used to store the attributes and are editable in the ContentCreator via the edit dialog of the currently displayed page.
The editing dialog can be called up via the Open page settings entry in the page information display area, which opens when the cursor hovers over the page status.