Skip to Content
Technical Articles

SmartEdit Customization

Introduction

For a Customer, we needed to customize SmartEdit.

The Requirement was to customize the WYSIWYG Editor in SmartEdit. The Editor is a CKEditor included as a third-party library by the SmartEdit Extension.

We needed to add an additional Format “H1 Red” with a special Red defined by the Customer.

“H1 red” should add the class is-red to the h1 Tag (<h1 class="is-red">My H1 Red Title</h1>)

The Class is defined in the Storefront correctly via CSS.

 

Final Result:

The Final Result should look like this:

Prerequisites

In order to work with Smart Edit, you need to set up your Smart Edit Development Environment.

An explanation is provided by SAP here:

https://help.sap.com/viewer/86dd1373053a4c2da8f9885cc9fbe55d/1905/en-US/0955af7dd5154a8db28dfce327d8dae5.html

https://help.sap.com/viewer/86dd1373053a4c2da8f9885cc9fbe55d/1905/en-US/6d55d5fba206425b9acecda9f2311483.html

https://help.sap.com/viewer/86dd1373053a4c2da8f9885cc9fbe55d/1905/en-US/87f5f49cb9f2475e8aa3fba51c8d5a20.html

During the Trail, you will create a new Extension based on the ysmarteditmodule Template.

The template contains an example Customization called abAnalytics.

We first used the SAP Commerce Version 1905 without any Patches and had run in some trouble where the SmartEdit Page reloaded endlessly. Because of this we Upgraded to the latest Patch of 1905 and could finally get the SmartEdit with our Custom Extension working.

If you have successfully set up your SmartEdit Development Environment you can start with developing.

 

Customization

For Extending Services and Features in our Customized SmartEdit Extension there exist a dedicated page: https://help.sap.com/viewer/86dd1373053a4c2da8f9885cc9fbe55d/1905/en-US/af037831649b4b88b6f0fddcee81f45c.html. Unfortunately the Page was not enough for me to directly understand how to customize the Editor.

To Customize SmartEdit we already created a new Extension based on ysmarteditmodule Template.

There we have different Scopes for different purposes called:

  • smartedittrail
  • smartedittrailcommons
  • smartedittrailContainer

The purposes of these Scopes are different. The Scope smartedittrail is to define Decorators.

smartedittrailcommons is for providing common Services, etc and the smartedittrailContainer is to provide Containers like the Rich Text Editor is one.

Standard Implementation of the Rich Text Editor

Hybris has implemented the Rich Text Editor at smartedit/web/app/common/components/genericEditor/richText

The Important file for us is here the SeRichTextFieldModule.ts where the general configuration is provided for the CKEditor.

The configuration is provided in the constant SE_RICH_TEXT_CONFIGURATION_CONSTANT  which is defined as a SeValueProviderand added to the list of Providers via @SeModule.

/* @internal */
export const SE_RICH_TEXT_CONFIGURATION_CONSTANT: SeValueProvider = {
	provide: 'seRichTextConfiguration',
	useValue: {
		toolbar: 'full',
		toolbar_full: [
			{
				name: 'basicstyles',
				items: ['Bold', 'Italic', 'Strike', 'Underline']
			}, {
				name: 'paragraph',
				items: ['BulletedList', 'NumberedList', 'Blockquote']
			}, {
				name: 'editing',
				items: ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock']
			}, {
				name: 'links',
				items: ['Link', 'Unlink', 'Anchor']
			}, {
				name: 'tools',
				items: ['SpellChecker', 'Maximize']
			},
			'/',
			{
				name: 'styles',
				items: ['Format', 'FontSize', 'TextColor', 'PasteText', 'PasteFromWord', 'RemoveFormat']
			}, {
				name: 'insert',
				items: ['Image', 'Table', 'SpecialChar']
			}, {
				name: 'forms',
				items: ['Outdent', 'Indent']
			}, {
				name: 'clipboard',
				items: ['Undo', 'Redo']
			}, {
				name: 'document',
				items: ['PageBreak', 'Source']
			}
		],
		disableNativeSpellChecker: false,
		height: '100px',
		width: '100%',
		autoParagraph: false,
		enterMode: CKEDITOR.ENTER_BR,
		shiftEnterMode: CKEDITOR.ENTER_BR,
		basicEntities: false,
		allowedContent: true,
		fillEmptyBlocks: false,
		extraPlugins: 'colorbutton, colordialog'
	}
};
...
@SeModule({
	imports: [
		'ngSanitize',
		'smarteditServicesModule'
	],
	providers: [
		SE_RICH_TEXT_CONFIGURATION_CONSTANT,
		...
	],
	...
})
export class SeRichTextFieldModule {}

 

After some debugging in the SeModule i could find the line where the Configuration is applied as constant.

function addProviderToModule(module: angular.IModule, provider: SeProvider) {
if ((provider as SeValueProvider).useValue) {

		provider = provider as SeValueProvider;
		module.constant(provider.provide, provider.useValue);

	}
...
}

How we customized the WYSIWYG Editor

As the module constant is just a key-value pair we could just add another Constant with the same name but different value.

To do this we needed to add a new SmartEdit Feature in our custom SmartEdit extension under smartedittrail/web/features/smartedittrailContainer/.

So we created a new Feature Folder named richText and in this folder, we created a new JavaScript File smartedittrailRichText.js to define a new angular module:

angular.module('smartedittrailRichTextModule', ['seRichTextFieldModule', 'ngSanitize',
    'smarteditServicesModule'
])

Before we start with Implementation we also need to add it to our webweb/features/smartedittrailContainer/smartedittrailcontainerModule.ts as import:

@SeModule({
	imports: [
		...
		'smartedittrailRichTextModule'
	]
...
})
export class SmartedittrailContainer {
}

We now can enhance our new Feature with:

var smartedittrailRichTextConfig = {
    name: 'seRichTextConfiguration',
    useValue: {
        toolbar: 'smartedittrailCustom',
        toolbar_smartedittrailCustom: [{
                name: 'basicstyles',
                items: ['Bold', 'Italic', 'Strike', 'Underline']
            }, {
                name: 'paragraph',
                items: ['BulletedList', 'NumberedList', 'Blockquote']
            }, {
                name: 'editing',
                items: ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock']
            }, {
                name: 'links',
                items: ['Link', 'Unlink', 'Anchor']
            }, {
                name: 'tools',
                items: ['SpellChecker', 'Maximize']
            },
            '/',
            {
                name: 'styles',
                items: ['Format', 'FontSize', 'TextColor', 'PasteText', 'PasteFromWord',
                    'RemoveFormat'
                ]
            }, {
                name: 'insert',
                items: ['Image', 'Table', 'SpecialChar']
            }, {
                name: 'forms',
                items: ['Outdent', 'Indent']
            }, {
                name: 'clipboard',
                items: ['Undo', 'Redo']
            }, {
                name: 'document',
                items: ['PageBreak', 'Source']
            }
        ],
        disableNativeSpellChecker: false,
        height: '100px',
        width: '100%',
        autoParagraph: false,
        enterMode: CKEDITOR.ENTER_BR,
        shiftEnterMode: CKEDITOR.ENTER_BR,
        basicEntities: false,
        allowedContent: true,
        fillEmptyBlocks: false,
        format_h1red: {
            name: 'H1 red',
            element: 'h1',
            attributes: {
                'class': 'is-red'
            }
        },
        format_tags: 'p;h1red;h1;h2;h3;h4;pre',
        contentsCss: '/smartedittrail/css/editor/smartedittrailCKEditorContent.css',
        extraPlugins: 'colorbutton, colordialog'
    }
};

angular.module('smartedittrailRichTextModule', ['seRichTextFieldModule', 'ngSanitize',
    'smarteditServicesModule'
]).constant(smartedittrailRichTextConfig.name,
    smartedittrailRichTextConfig.useValue);

The self-defined Variable is, in general, the same as from the Hybris Standard. but with additional settings. The Variable is only used for defining the Key and the Value for the constant.

The name of the Constant needs to be the same. Because of this smartedittrailRichTextConfig.name is the same as the standard (see above).

The customized Configuration is saved in smartedittrailRichTextConfig.useValue. The applied Structure here is compliant with the config options of CKEDITOR.

Our Custom part is the following:

 format_h1red: {
  name: 'H1 red',
  element: 'h1',
  attributes: {
    'class': 'is-red'
  }
},
format_tags: 'p;h1red;h1;h2;h3;h4;pre',

Explanation:

with format_h1red we defined a new style which is added to the list of styles with format_tags .The new Style is defined with the element: 'h1' and the class is-red. We also needed a name for displaying in SmartEdit name: 'H1 red' .

With this, the new Style is added with the name H1 red to the list of available styles and can be applied. In the Text Source something like this will be added :

<h1 class="is-red">My H1 red Title</h1>

Providing Style for the Format Name in the WYSIWYG Editor

With the above implementation, the new Style is already usable but will not be displayed correctly in the WYSIWYG Editor. As the CSS Class is-red is only known by the Storefront but not by the Editor the Name of the Style, as well as the applied Style will be displayed as Black Text in the Editor.

On the Storefront itself, the Color will be correct, but if you are using a WYSIWYG editor you, of course, want to see how it looks, so we need to apply the style here as well.

To provide the style CSS we need to create one first or reuse an existing one if possible.

We decided to create a new one in smarteittrail/web/css/editor with the name smartedittrailCKEditorContent.css where we defined the style.

We now need to use it in the CKEditor, so we added it with contentCSs: '/smartedittrail/css/editor/smartedittrailCKEditorContent.css'

Our Customization is looking like this now.

 format_h1red: {
  name: 'H1 red',
  element: 'h1',
  attributes: {
    'class': 'is-red'
  }
},
format_tags: 'p;h1red;h1;h2;h3;h4;pre',
contentsCss: '/smartedittrail/css/editor/smartedittrailCKEditorContent.css',

 

Conclusion

Our Customization is now working and is as already presented at the top like this:

During Setting Up the Development Environment for SmartEdit we run in some Issues with the default Hybris. These issues were already discussed in different answers.sap.com Threads without much information.

It was quite a trial and error process to figure out what went wrong. After applying the latest patch for SAP Commerce 1905 everything worked without a reason. Maybe there were some Issues regarding SmartEdit that was not discovered previously or something has gone wrong with setting up SmartEdit Development Environment on a Windows Machine; as there are special Steps needed  Setting up NPM on Windows .

After finally getting SmartEdit with the custom Extension running we could investigate at how to customize the CKEditor in SmartEdit. For us, the provided help.sap.com wiki didn’t provide enough information to get an easy start with SmartEdit Customization in this regard. What was good documented was how to create new Decorators etc. but customizing a Standard in Hybris was some hazel.

Finally, I could break the Editor and I thought: “If I can break it, I can customize it as well”

The only difficulty was to get the Information about how the Structure needs to look. As the CKEditor is a third-party tool I had a look at the developer Documentation for CKEditor. I then tried to set these properties straight and forward with the already used Structure from the Standard.

After this the rest of the customization was easy; as I knew how the structure needs to be defined and where I get the information which configurations can be applied to the CKEditor I just needed to test the Configuration.

 

After doing this Customization I now have a deeper understanding of how to customize SmartEdit.

At first, it was very frustrating as I couldn’t see any progress but after I reached a certain point I was finally able to see a light on the horizon and was able to customize the Editor as I wanted.

5 Comments
You must be Logged on to comment or reply to a post.
  • Hi Stefan,

    Can you please provide more information about NPM Install thing. As i made change in custom ts file but changes are not reflecting in js after ant clean all. Please tell me how to setup this to make it work.

    • Hey Akash,

      npm install will install only the necessary npm dependencies and will setup the npm project. To build the project, you still need to run ant build additional have a look at the Gruntfile.js where the grunt targets are defined for compiling the TypeScript and JavaScript files.

       

  • Hi Stefan,

    Thank you for the post. This really helped me. I want to override SeRichTextFieldComponent.ts component constructor as well. Can you please help me on that?

  • Hi Stefan,

     

    Is it possible that there is a general issue with the justification Buttons (“justifyLeft”, “justifyBlock”,…)? They are not rendered in the demo version. Also your guide is obviously populating the “editing”-items, but still these buttons are NOT rendered in your result example.

     

    I’m struggling with this very issue, not being able to populate these edit buttons to the wysiwyg editor

     

    greets.

    • Hi Sergej,

       

      for the Buttons, I do not know, as we are using the Standard and we only added additional Format Styles.