QUOTE: Kindness is always fashionable.

SAP Commerce Docs

A documentation for the SAP Commerce.

31. Jan 2024 toc: disabled view: slim

SAP Commerce

Create a custom CMS Component

examplecore-items.xml

<itemtype
  code="ExampleComponent"
  autocreate="true"
  generate="true"
  extends="SimpleCMSComponent"
  jaloclass="com.example.hybris.core.jalo.cms2.components.ExampleComponent"
>
  <description>A example component</description>
  <attributes>
    <attribute qualifier="text" type="java.lang.String">
      <modifiers read="true" write="true" search="true" unique="false" optional="true"/>
      <persistence type="property">
        <columntype>
          <value>HYBRIS.JSON</value>
        </columntype>
      </persistence>
    </attribute>
  </attributes>
</itemtype>

Groovy Scripting

Groovy scripts can be executed in the HAC (Hybris Administrative Console) under the section Console > Scripting Languages. Make sure you have set the script type to "groovy" and toggle the button under the editor from ROLLBACK to COMMIT in order to make your changes persistent.

The following groovy script searches for a specific CatalogVersionModel.

import de.hybris.platform.servicelayer.search.FlexibleSearchService;
import de.hybris.platform.servicelayer.model.ModelService;
import de.hybris.platform.servicelayer.search.FlexibleSearchQuery;
import de.hybris.platform.catalog.model.CatalogVersionModel;


FlexibleSearchService flexibleSearchService = spring.getBean("flexibleSearchService");
ModelService modelService = spring.getBean("modelService");

String version = "Staged";
String catalog = "exampleContentCatalog";

FlexibleSearchQuery flexibleSearchQuery = new FlexibleSearchQuery("SELECT {cv.pk} FROM {CatalogVersion AS cv LEFT JOIN Catalog AS c ON {cv.catalog}={c.pk}} WHERE {cv.version}='" + version + "' AND {c.id}='" + catalog + "'");
CatalogVersionModel catalogVersion = flexibleSearchService.searchUnique(flexibleSearchQuery);

Model Lifecycle

The following diagram show the lifecycle of a Model.

+--------------------------------------------------------------------------------------+
|                                     Model Runtime                                    |
| +----------------------------------------+                                           |
| |          Instantiate a Model           |          +--------------------------+     |
| | +------------------------------------+ | -------> |                          |     |
| | |     Model model = new Model();     | |          |    Modify Model Values   |     |
| | | +--------------------------------+ | |      +-> |                          | --+ |
| | | |  modelService.initDefaults();  | | |      |   +--------------------------+   | |
| | | |   (Init Default Interceptor)   | | |      |                                  | |
| | | +--------------------------------+ | |      |   +--------------------------+   | |
| | +------------------------------------+ |      +-- |   (Prepare Interceptor)  | <-+ |
| | +------------------------------------+ |          |    Saved Model Values    |     |
| | |        Load from Database          | | -------> |  (Validate Interceptor)  |     |
| | |        (Load Interceptor)          | |          +--------------------------+     |
| | +------------------------------------+ |                             |             |
| +----------^-----------------------------+                             |             |
+------------|-----------------------------------------------------------|-------------+
             |                                                           |
+------------|-----------------------------------------------------------|-------------+
|            |                        ModelService                       v             |
| +----------------------+    +-------------------------+    +-----------------------+ |
| |  modelService.get()  |    |  modelService.remove()  |    |  modelService.save()  | |
| |                      |    |  (Remove Interceptor)   |    |                       | |
| +----------------------+    +-------------------------+    +-----------------------+ |
+--------------------------------------------------------------------------------------+
                                     ^            |
                                     |            v
+--------------------------------------------------------------------------------------+
|                                       Database                                       |
+--------------------------------------------------------------------------------------+

Custom Validate Interceptor

The interceptor in this example, validates the String property text for the type Example, by checking the max length and returning an InterceptorException if the requirements are not met.

Register a new interceptor with the following beans definition.

examplecore-spring.xml

<bean
  id="exampleInterceptor"
  class="com.example.hybris.core.interceptor.cms.ExampleModelInterceptor"
  autowire="byName"
/>
<bean
  id="exampleInterceptorMapping"
  class="de.hybris.platform.servicelayer.interceptor.impl.InterceptorMapping"
>
  <property name="interceptor" ref="exampleInterceptor"/>
  <property name="typeCode" value="Example"/>
</bean>

Create the corresponding Java file and reference the required interceptor interfaces and implement the desired logic. For this example, we use the ValidateInterceptor interface.

ExampleModelInterceptor.java

package com.example.hybris.core.interceptor.cms;

public class ExampleModelInterceptor implements ValidateInterceptor
{
    private final int MAX_LENGTH_TEXT = 50;

    @Override
    public void onValidate(Object model, InterceptorContext context) throws InterceptorException
    {
        if (model instanceof ExampleModel)
        {
            final ExampleModel exampleModel = (ExampleModel) model;

            if (exampleModel.getText() != null && exampleMode.getText().length() > MAX_LENGTH_TEXT)
            {
                throw new InterceptorException("Text is too long!");
            }
        }
    }

}

Composable Storefront

SmartEdit

Editor Configuration

Use custom Editors for specific Properties

The following bean definition tells SmartEdit that, the property text for the type ExampleComponent should be editable with a rich text editor.

examplefacades-structuretypes-generic-config-spring.xml

<bean
  class="de.hybris.platform.cmsfacades.types.service.impl.DefaultComponentTypeAttributeStructure"
  p:typecode="ExampleComponent"
  p:qualifier="text"
>
  <property name="populators">
    <set>
      <ref bean="richTextComponentTypeAttributePopulator"/>
    </set>
  </property>
</bean>

Organize how Types should be displayed

The following bean definition tells SmartEdit, what properties of the type ExampleComponent should be displayed, hidden, and how they should be ordered.

  • includes = Which properties should be displayed
  • excludes = Which properties should be hidden
  • order = How the properties should be ordered

examplefacades-structuretypes-generic-config-spring.xml

<bean parent="cmsStructureTypeModeAttributeFilter">
  <property name="constrainedBy">
    <bean
      parent="cmsEqualsTypeAndModeBiPredicate"
      p:typeCode="ExampleComponent"
      p:mode="DEFAULT"
    />
  </property>
  <property name="includes">
    <list>
      <value>name</value>
      <value>text</value>
      <value>items</value>
    </list>
  </property>
  <property name="order">
    <list>
      <value>name</value>
      <value>text</value>
      <value>items</value>
    </list>
  </property>
  <property name="excludes">
    <list>
      <value>children</value>
      <value>parents</value>
    </list>
  </property>
</bean>

Define custom Property names

examplecore-locales_en.properties

Type.ExampleComponent.Name = Example Component
Type.ExampleComponent.text.Name = Text
Type.ExampleComponent.items.Name = Items