Skip to Content
Technical Articles

SAP Commerce | Create New Structure Type in SmartEdit

Introduction

In this blog, we will create new Structure Type in SmartEdit and assign it to one of the CMS Component.

We will enhance OOTB CMSTimeRestriction with cronExpression and add a Guide link to this component which takes CMS Manager to third party site.

This blog is based on SAP Commerce 1811.

Customization (Core Part)

  • Extend OOTB CMSTimeRestriction with new attribute cronExpression in myextension-items.xml
       <itemtype code="CMSTimeRestriction" extends="AbstractRestriction" autocreate="false" generate="false">
			<attributes>
				<attribute type="java.lang.String" qualifier="cronExpression">
					<persistence type="property" />
				</attribute>
			</attributes>
		</itemtype>
  • Update Localization in myextension-locales_en.properties
type.CMSTimeRestriction.cronExpression.name=Cron Expression
  • Extend OOTB CMSTimeRestrictionEvaluator with cron expression support
public class CustomCMSTimeRestrictionEvaluator extends CMSTimeRestrictionEvaluator
{
	private static final Logger LOG = LogManager.getLogger(CustomCMSTimeRestrictionEvaluator.class);

	@Override
	public boolean evaluate(final CMSTimeRestrictionModel timeRestriction, final RestrictionData context)
	{
		final boolean isEvaluate = super.evaluate(timeRestriction, context);
		return isEvaluate && evaluateCronExpression(timeRestriction);
	}

	private boolean evaluateCronExpression(final CMSTimeRestrictionModel timeRestriction)
	{
		if (StringUtils.isBlank(timeRestriction.getCronExpression()))
		{
			return true;
		}

		Date now = (Date) getSessionService().getAttribute("previewTime");
		if (now == null)
		{
			now = Boolean.TRUE.equals(timeRestriction.getUseStoreTimeZone()) ? getTimeService().getCurrentTime() : new Date();
		}

		try
		{
			final CronExpression cronExpression = new CronExpression(timeRestriction.getCronExpression());
			return cronExpression.isSatisfiedBy(now);
		}
		catch (final ParseException e)
		{
			LOG.error("Provided CronExpression {} is not valid.", timeRestriction.getCronExpression(), e);
		}

		return false;
	}
}
  • Override bean definition in myextension-spring.xml
    <bean id="cmsTimeRestrictionEvaluator" class="com.sap.core.restrictions.PharmacyCMSTimeRestrictionEvaluator" autowire="byName">
		<property name="sessionService" ref="sessionService" />
		<property name="timeService" ref="timeService" />
	</bean>

 

Our Core functionality is done. Now CMSTimeRestriction support cronExpression as well and CMS Manager can control component visibility based on cron expression as well.

Customization (SmartEdit Part)

The newly created attribute (cronExpression) in CMSTimeRestriction will automatically visible in SmartEdit. Lets begin creating new CMS Structure Type -> cronExpressionGuide which will have link which takes CMS Manager to third party site (e.g. https://www.freeformatter.com/cron-expression-generator-quartz.html).

  • Lets first create one custom SmartEdit extension. Please follow these links to setup & create one custom extension e.g. trainingsmartedit.

https://help.sap.com/viewer/9d346683b0084da2938be8a285c0c27a/1811/en-US/0955af7dd5154a8db28dfce327d8dae5.html

https://help.sap.com/viewer/9d346683b0084da2938be8a285c0c27a/1811/en-US/6d55d5fba206425b9acecda9f2311483.html

https://help.sap.com/viewer/9d346683b0084da2938be8a285c0c27a/1905/en-US/5fd2da27ae50410592b4a8d04af1a02f.html

  • Once new extension is created, Go to trainingsmartedit/web/features/trainingsmarteditContainer folder and create a new package structure /components/genericEditor/cronExpressionGuide (Here we will define our new structure type html).
  • Create cronExpressionGuideTemplate.html inside cronExpressionGuide folder as per below.
<a href="https://www.freeformatter.com/cron-expression-generator-quartz.html" target="_blank">Generate Cron Expression</a>
  • Now we need to create Generic Editor Mapping Service to map new structure type cronExpressionGuide to a virtual field (CronExpressionGuide). This virtual field we can assign to CMSTimeRestriction.
  • Create new folder config inside genericEditor (/components/genericEditor/config) and add one new file cmsTrainingGenericEditorMappingService.js under config folder.
  • Create new field mapping like this inside cmsTrainingGenericEditorMappingService.js
angular.module('cmsTrainingGenericEditorConfigurationServiceModule', ['cmsGenericEditorConfigurationServiceModule', 'editorFieldMappingServiceModule'])
    .run(function(editorFieldMappingService) {
        
        // CronExpressionGuide is the virtual field
        editorFieldMappingService.addFieldMapping("CronExpressionGuide", null, null, {
            template: "cronExpressionGuideTemplate.html"
        });
});
  • Here we have added a mapping of our newly created Structure Type with virtual field CronExpressionGuide.
  • Inject editor field mapping service into trainingsmarteditcontainerModule.ts file.
...........
@SeModule({
	imports: [
		'smarteditServicesModule',
		'abAnalyticsToolbarItemModule',
		'cmsTrainingGenericEditorConfigurationServiceModule'
	],
...........
  • Finally add this virtual field to CMSTimeRestriction. Add the below bean definition in trainingsmartedit-spring.xml
	<bean id="cronExpressionGuideTypeAttributePopulator" class="de.hybris.platform.cmsfacades.types.populator.CmsStructureTypeComponentTypeAttributePopulator">
		<property name="cmsStructureType" value="CronExpressionGuide" />
	</bean>
	
	<bean class="de.hybris.platform.cmsfacades.types.service.impl.DefaultComponentTypeAttributeStructure" p:typecode="CMSTimeRestriction" p:qualifier="cronExpressionGuide">
		<property name="populators">
			<set>
				<ref bean="i18nComponentTypeAttributePopulator" />
				<ref bean="cronExpressionGuideTypeAttributePopulator" />
			</set>
		</property>
	</bean>
  • Update localization in myextension-locales_en.properties
type.CMSTimeRestriction.cronExpressionGuide.name=Cron Expression Guide
  • Optionally, we can define ordering as well like this
	<alias name="customCmsStructureTypeModeAttributeFilterList" alias="cmsStructureTypeModeAttributeFilterList"/>
	<bean id="customCmsStructureTypeModeAttributeFilterList" class="org.springframework.beans.factory.config.ListFactoryBean" parent="defaultCmsStructureTypeModeAttributeFilterList">
		<property name="targetListClass" value="java.util.LinkedList"/>
		<property name="sourceList">
			<list merge="true">
				
				<bean parent="cmsStructureTypeModeAttributeFilter">
					<property name="constrainedBy">
						<bean parent="cmsEqualsTypeAndModeBiPredicate" p:typeCode="CMSTimeRestriction" p:mode="DEFAULT"/>
					</property>
					<property name="order">
						<list>
							<value>name</value>
							<value>activeFrom</value>
							<value>activeUntil</value>
							<value>cronExpressionGuide</value>
							<value>cronExpression</value>
						</list>
					</property>
				</bean>
																
			</list>
		</property>
	</bean>

 

Build Step –

Make sure at the time of SmartEdit setup, assuming you have already done ant npminstall.

  • Now run ant clean all and this will compile our newly added service and generate new trainingsmarteditContainer.js file.
  • Once build is successful, start the Hybris Server and open SmartEdit.
  • Make sure that the following impex run at the time of setup.
INSERT_UPDATE SmartEditConfiguration;key[unique=true];value
;applications.trainingsmartedit;{"smartEditLocation":"/trainingsmartedit/trainingsmartedit/js/trainingsmartedit.js","extends": "cmssmartedit"}
;applications.trainingsmarteditContainer;{"smartEditContainerLocation":"/trainingsmartedit/trainingsmartedit/js/trainingsmarteditContainer.js","extends": "cmssmarteditContainer"}
  • Finally test the changes, Create new CMSTimeRestriction, and you will see Cron Expression Guide with “Generate Cron Expression” link.

Conclusion

This way we can create any type of custom Structure Type and map it to the component by introducing virtual field.

 

Thanks

Shreshtt Bhatt

/
Be the first to leave a comment
You must be Logged on to comment or reply to a post.