Backoffice Customization

What is Backoffice Framework?

Backoffice Framework is new SAP Hybris Backoffice Framework designed to facilitate the creation of business tools and user interfaces in an easy and consistent way. It is shipped with SAP Hybris Commerce in the backoffice extension. It makes it possible to create a variety of components that can be reused later on in all kinds of applications. These components are standalone and deployable widgets can be easily modified without touching the code base.

In this tutorial, we will show you, how to create a custom widget using the Backoffice Framework. Our custom widget will have one input and one submit button. Suppose we enter some input and press the button, If the entered value is an integer then one pop up appears and it contains a message that Input value is an integer otherwise it will display an error that entered input is not an integer.

Steps to create a custom widget

  1. Create a custom  backoffice extension

  2. Create a widget definition

  3. Creating a widget view

  4. Create a service for widget/Use existing service for a widget

  5. Create a controller for the widget

  6. Build and start the server

  7. Deploy the widget

1. Create a custom  backoffice extension

Here we will create one custom backoffice extension named hybrisdiary using the BackOffice template extension. In this custom backoffice extension (hybrisdiary) we can create our custom widgets. To create custom backoffice extension(hybrisdiary) follow the following steps:-

  1. Open the command prompt and navigate to  <%HYBRIS_HOME_DIR%>/hybris/bin/platform directory and run the setantenv.bat file as shown in below image.setantenv.bat
  2. Now run ant extgen command.ant extgen
    Extgen prompts you to specify values for the technical aspects of an extension. Extgen comes with default values for all these technical aspects.
    These default values are defined in the project.properties file in the extgen directory. The default value is displayed in brackets ([ and ])
  3. Now we enter ybackoffice as shown in below image.ybackoffice
  4. Now enter extension name hybrisdiary as shown in below image.
    hybrisdiary custom backoffice name
  5. Now enter the package name(de.hybris.hybridiary) as shown in below  image
    package name
  6. If you want to register  SASS support for your extension then press enter otherwise type false and then press enter. Here we are using default value so we will press enter.
  7. If you want to create sample widget then press enter otherwise type false and then press enter. Here we are creating sample widget so will press enter.
  8. If you want to create a sample style sheet then type true and then press enter. If you do not want to create a sample style sheet then simply press enter.
    SASS extension sample widget sample style sheet
  9. Navigate to <%HYBRIS_HOME_DIR%>/config and open local.properties file and specify the following entry and save it.
    backoffice.sass.enabled=true
  10. Now run ant sasscompile from the platform.
    ant sasscompile
  11. Now we will add our custom backoffice extension(hybrisdiary) to localextensions.xml
    localextensions.xml
  12. Now we will do ant clean all.
    ant clean all

If the build successful then your custom backoffice extension successfully generated. If you are using eclipse then import your custom backoffice extension in to eclipse.

2. Create a widget definition

To create a widget definition, we must keep in mind that widget-definition id must be unique. If your widget-definition id matches with existing widget-definition id then your new widget will not appear on the list of widgets in the choose widget wizard. Now do the following steps to create the widget definition:-

  1. Navigate to hybrisdiary->backoffice->Resources->widgets and create a new folder called as mycustominput
    mycustominput folder location
  2. Now create a definition.xml file inside the newly created folder(mycustominput).
  3. Now add the following lines of code to the file(definition.xml).

    definition.xml
    definition.xml

3.Creating a widget view

The view of our widget will be defined in the ZUL file and the name of the file must match with last part of the widget ID as defined in the definition.xml file. The last part of widget ID is mycustominput so the view file name will be mycustominput.zul. In mycustominput.zul file, we will define all frontend component. To check whether the entered input is an integer or not we need one textbox for input and one button to submit. So we will define one textbox and one button in mycustominput.zul file. Now follow the following steps to create the widget view:-

  1. Now create a mycustominput.zul file inside the mycustominput folder.
  2. Now add the following lines of code to the mycustominput.zul file.
    mycustominput.zul
    mycustominput.zul

     

4.Create a service for widget/ Use existing service for a widget

For our example, we need some service to do some action. Either we can create our custom service to do some logic or we can use existing services. In our example, we will create a custom service that will check that the entered input is an integer or not. To create a service for our custom widget, we need to follow the following steps:-

  1. Navigate to hybrisdiary->src folder and create MyCustomInputService.java file in de.hybris.hybrisdiary.mycustominput package.
  2. Add the following lines of code to the MyCustomInputService.java file.

    MyCustomInputService.java file
    MyCustomInputService.java
  3. Navigate to hybrisdiary->resources and open hybrisdiary-backoffice-spring.xml file and define the bean for MyCustomInputService as shown in below image.
    mycustominputservice bean
    mycustominputservice bean

     

5. Create a controller for the widget

Here we have not defined any action for submit button so when we click on the button nothing will happen. To do some action we need to define a controller for the widget. To create a controller for the custom widget we need to follow the following steps:-

  1. Navigate to hybrisdiary->backoffice/src and create MyCustomInputController.java in de.hybris.hybrisdiary.widgets.mycustominput package.
  2. Add the following lines of code to the file.

    MyCustomInputController
    MyCustomInputController.java
  3. Navigate to hybrisdiary->backoffice->Resouces->widgets->mycustominput and open definition.xml file and we add a controller class to this file as shown in the image.

    definition.xml
    definition.xml

6.Build and start the server

Now we will build the system by running ant clean all and we start the server by running the hybrisserver.bat file.

7.Deploy the widget

Now we will deploy our custom widget. To deploy the custom widget do the following steps:-

  1. Open the internet browser.
  2. Enter https://localhost:9002/backoffice  in the browser’s address bar.
  3. Enter your credentials and log in.
    backoffice login
  4. Press F4 to enter into Application Orchestrator mode and click on the symbol(+ symbol inside an orange circle) to add the new widget as shown in below image.
    Application Orchestrator mode
    Application Orchestrator mode

    The choose widget appears, which contain all the available widgets and choose My Custom Input widget. You can easily learn the process of adding a widget to backoffice by observing the image.
    add widget process

  5. Now press F4 to enter into normal mode and you will see the newly added widget in backoffice.
    new widget in backoffice
  6. Now we enter 54 in the input box and which is an integer and we press the submit button. Now message box will appear which show us that “input value is an integer“.
    working widget

Navigation management in SAP Hybris Commerce

Navigation management through impex

When we create a website based on an existing content catalog, a default navigation structure is created for our content catalog. If we create a website based on a new content catalog, we must build navigation structure for our new content catalog. So we will learn here how to create navigation nodes using impexes.

Create new navigation node using impex

To explain this we will create one new custom navigation node in apparel storefront. In apparel storefront, there are 5 navigation nodes as shown in the image and we will add another navigation node at the end of navigation nodes.

Apparel Store
Apparel Storefront

Steps to create a new navigation node

Step-1

Create a new CMSNavigationNode. Like created in below image.

CMSNavigationNode

Step-2

Create a new CMSNavigationEntry for CMSNavigationNode. Like created in below image.

CMSNavigationEntry

Step-3

Create a new CMSLinkComponent. Like created in below image.

CMSLinkComponent

Step-4

In this step, we do localization of CMSNavigationNode and CMSLinkComponent as shown in the image

Localiztion

The complete impex will look like this.

create_navigation_node
new_navigation_node.impex

Here we assume that your server has started already. Now run the above impex(new_navigation_node.impex) in HAC(Hybris Administration Console) and synchronize the content catalog(apparel-ukContentCatalog).

Now access the apparel storefront and you can clearly observe newly created navigation node. In below image, you can see new custom navigation node.

Apparel store with new node
Apparel store with new navigation node

Create Children nodes of Custom navigation nodes

Now we will create children of above-created navigation node. To create children of above-created navigation node, we need to follow the following steps

Step-1

Create a new CMSNavigationNode. Like created in below image.

ChildrenCMSNavigationNode

Custom Brands Nav Node is a child of Custom Nav Node and Custom Brands Nav Node is the parent of bitbyte Link and hybrisdiary Link.

Navigation tree structure

Step-2

Create a new CMSNavigationEntry for children nodes. Like created in below image.

CMSNavigationEntry For Children

Step-3

Create a new CMSLinkComponent. Like created in below image.

CMSLinkComponentForChildren

Step-4

In this step, we do localization of CMSNavigationNode and CMSLinkComponent as shown in the image.

Children's localization

The complete impex will look like this.

Complete impex for children node
new_navigation_children_node.impex

Here we assume that your server has started already. Now run the above impex(new_navigation_children_node.impex) in HAC(Hybris Administration Console) and synchronize the content catalog(apparel-ukContentCatalog).

Now access the apparel storefront and Hover on custom navigation node and you can clearly observe newly created children(HYBRISDIARY and BITBYTE) of custom navigation node. In the below image you can observe.

Apparel store with Childrens
Apparel store with new navigation node and with its children

Hot Deployment – Hybris

Introduction

In this tutorial I will be covering the configuration of JRebel with Hybris. With JRebel configured you will be able to modify java source classes and compile them on the fly.

“No need to build and start the server again and again”

The configuration is very simple, just 3 steps and you are good to go!

Step 1

  • Download JRebel: Archive can be downloaded from the below link http://zeroturnaround.com/software/jrebel/download/prev-releases/
  • Extract the zip file at a location of your preference, for eg: C:/jrebel
    unzip
  • Active JRebel:
    – Go inside bin folder of JRebel.
    – Start the activation utility by running “activate-gui.cmd” file.
    – It will open a Jrebel activation window. The window will contain 2 tabs:
    Try JRebel    for free and I already have a license.Choose Try JRebel for FREE and fill the basic information.

jrebelfreeform
OR
Buy a license and fill the information in the I already have a license section.

Step 2

  • Add the below given property in local.properties file
    tomcat.javaoptions=-agentpath:C:/jrebel/lib/jrebel64.dll
    ** change the version of the jrebel[XX].dll according to the machine specifications.

 Creation of rebel.xml file:
– You will be required to add the rebel.xml file in the resource folder of each extension.

rebel.png

– Create a new rebel.xml class and copy/paste the below given content into the file:

<?xml version=”1.0″ encoding=”UTF-8″?>
<application xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xmlns=”http://www.zeroturnaround.com&#8221; xsi:schemaLocation=”http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_1.xsd”&gt;
<classpath>
<!– Make sure to replace Absolute_Path with your concrete values –>
    <dir name=”{Absolute_Path}/classes”/>
</classpath>
</application>

**   The absolute path should be the complete path to the classes folder.
Example: C:/hybris/bin/custom/demo/demofacades/classes

***The classes folder is the compiled source folder of Hybris and not IDE’s(eclipse).

Step 3

  • Change the IDE(eclipse) compile output path in “.classpath” file of the extension.classpath.png
    TO
    classpath1.png
    Path structure:
    path.png
    All the configurations are completed.You just need to recompile the code from IDE(eclipse) after making the changes in the Java source file.For Eclipse you need to do the below mentioned step:

    • Just go to Project -> Clean
    • Select “Clean projects selected below” option and select the extensions which contains the modified java source classes.
    • Select “Start build immediately”.
    • Select “Build only the selected projects”.
    • Press OK and you are done!

Understanding Spring Events in Hybris

We humans are known to celebrate certain milestones in our life journey. We do celebrate birth, tying knots etc. Similarly, in the buying journey of a customer, there are few milestones which are worth celebrating or react to. Order placement, registration of a customer is few of them. The reaction could be about sending a welcome email, or sending the order data to a third party system for fulfillment.

Further, let’s say, a customer registered on a web site, and wants to start browsing the cool products. But the lousy code of sending a fancy welcome email with a promotional voucher in it, took around one minute. He will regret his decision to register, and will walk away.

spring-listener.jpg

Spring based events, provides the exact same infrastructure. So now we know, whenever we have a situation where some lousy code is to be executed after some thing happens (an event), we will rely on events.

 First we need to create an Event class, that will hold the necessary data to pass to the listener.

protected AbstractCommerceUserEvent initializeEvent(final AbstractCommerceUserEvent event, final CustomerModel customerModel)
{
event.setBaseStore(getBaseStoreService().getCurrentBaseStore());
event.setSite(getBaseSiteService().getCurrentBaseSite());
event.setCustomer(customerModel);
event.setLanguage(getCommonI18NService().getCurrentLanguage());
event.setCurrency(getCommonI18NService().getCurrentCurrency());
return event;
}

Spring provides a way to publish an event.

getEventService().publishEvent(initializeEvent(new RegisterEvent(), customerModel));

There are dedicated listeners lying around, who listens to these wishes, and reacts the way, they are programmed.

Listeners can be bonded to publishing services via common event object.

public class RegisterEventListener extends AbstractEventListener
{
   @Override
   protected void onEvent(final AbstractEvent event)
   {
      if (event instanceof RegisteEvent)
      {
          // Do whatever you want. send email/voucher or whatever
      }
   }
}

Please note that since, listener code starts in a new thread, it will not hamper customer journey on your site. The listener code will execute as a back end process.

Adding a new attribute to edit view area in Product Cockpit.

I was working on a Project and there was a requirement to add a new attribute in edit view area In Product Cockpit.

I followed these few step to do this task.

1.Create a new Model e.g MyProduct that extends ProductModel in Items.xml, add attribute in this model e.g:

“<itemtype code=”MyProduct” extends=”Product”>
<description>my product that contains additional attributes.</description>
<attributes>
<attribute qualifier=”attribute1″ type=”localized:java.lang.String”>
<description>example for product cockpit</description>
</attribute>
</attributes>
</itemtype>”

after this,Build the project and start the server, do Update running system from Hac.

Add some product in your “Myproduct” Model.

2.Create  a editorArea_MyProduct.xml file in your Cockpit extension and add key for new attribute in xml file

editorArea_MyProduct

3. Localized the key name in  ProjetcNamecockpits-locales_en.properties and i3-label.properties file.

ProjetcNamecockpits-locales_en

 

4.Restart the server and do update from HAC. Open ProductCockpit in url “http://localhost:9001/productcockpit&#8221; and search your product which you added in “MyProduct” model .

5.Open that product and in left side you will find your new attribute in Editor_area.

Capture1

Hybris Mobile and Desktop Site

Most people face problem in understanding the difference between Desktop site and Mobile site in Hybris and how do we setup the Mobile site and what parameters control the switching of Desktop and Mobile site. Also, how does a responsive site differ from both Desktop and Mobile site?

Technical Difference in terms of UI

First of all, the mobile site differs from the desktop site generally in terms of the UI. The back end code mostly remains the same for both the mobile and desktop sites.

The UI change is controlled by CSS, JS and images.

Also, the UI, which is defined using Hybris WCMS, need to define different Page Template, ContentSlot, ContentPage, ProductPage and the relationship between them for Mobile site and Desktop site.

Technical Difference in terms of Java code

For accessing the UI of either the Mobile site or the Desktop site, we need set the UiExperienceLevel to corresponding device type for which we need to first of all detect the device from which request is coming. This is done using an interceptor i.e. DeviceDetectionBeforeControllerHandler using class DefaultDeviceDetectionFacade and more specifically in SpringMobileRequestDeviceDataPopulator.

After device detection, the detected device needs to be mapped to a UiExperienceLevel (i.e whether it is desktop, tablet, mobile), which is done in class DeviceDataUiExperiencePopulator.

After this the detected UiExperienceLevel is compared with the supported UiExperienceLevel and if matched then DetectedUiExperienceLevel is set to this value.

Parameters controling switching of Desktop and Mobile site

UiExperienceLevel is configured in your properties file using the property “uiexperience.level.supported”.

Please note the correct format of specifying the value for “uiexperience.level.supported” is comma separated Camel Case names like Mobile,Desktop or Desktop,Mobile for the functionality to work correctly.

There is one more interceptor SetUiExperienceBeforeControllerHandler called before the request reaches the controller. This interceptor checks for the parameter “uiel” (like ?uiel=Mobile) in the request and if set its value is used to override all previous UiExperienceLevel.

Based on the UiExperienceLevel set, the corresponding CSS, JS and images are set and we see either the Mobile site or the Desktop site.

Responsive

When we have constructed our website for Responsive UI then the UI automatically adjusts itself according to the device type and this is done because of the responsive JS used. Hybris has made the desktop site responsive hence eliminating the need for separate Desktop and Mobile sites.

Different Views for Electronics Site:

MobileSite
Mobile Site – Non Responsive
ResponsiveSite-MobileView
Mobile Site – Responsive

 

 

 

 

 

 

 

 

 

ResponsiveSite-DesktopView

Desktop Site – Responsive

ResponsiveSite-TabView

Tab Site – Responsive

 

Understanding Cronjobs

A Cronjob is a scheduler where we can schedule a particular Job to be performed at a specified time or over a period of time.

The 3 parts of a Cronjob are:

  1. CronJob
  2. Job
  3. Trigger

For understanding each of these clearly I would take an example:

1. CronJob:

First of all you need to identify what task you CronJob need to do.

In this case lets say that your cronjob needs to send NewsletterEmail periodically with a personalized message.

You would create a NewsletterEmailCronJob item in your items.xml file having attributes for storing a personalizedMessage

<itemtype code=”NewsletterEmailCronJob” autocreate=”true” generate=”true” extends=”CronJob”
jaloclass=”com.email.jalo.NewsletterEmailCronJob”>
<description>Cronjob for sending Newsletter Email</description>
<attribute qualifier=”personalizedMessage” type=”java.lang.String”>
<persistence type=”property”/>
</attribute>
</itemtype>

Now the above code would create the required Model class when you save it and run Ant Build script.

2. Job:

Job is where your business logic goes and it uses the CronJob Model you created as part of CronJob above.

Here you would create a class say NewsletterEmailJob which would extend AbstractJobPerformable and would work on NewsletterEmailCronJobModel.

You would override the perform method to write the business logic in it.

Code Snippet:

public class NewsletterEmailJob extends AbstractJobPerformable<NewsletterEmailCronJobModel>
{

@Override
public PerformResult perform(final NewsletterEmailCronJobModel cronJob)
{

….. Logic for sending News letter Email with Personalized Message ….

}

}

Also, you would define a bean for the above class in your spring.xml file as follows:

<bean id=”newsletterEmailJob” class=”com.email.NewsletterEmailJob”
parent=”abstractJobPerformable” >
</bean>

3. Trigger

Trigger defines the time event when the Job would be executed.

The trigger is linked to the Job via CronJob. You would first create a CronJob item and associate the bean id of the Job to it. Then you would create a Trigger item which contains the CronJob item reference and the time schedule for execution. The time schedule expression is written using Quartz Job Scheduler which can found at http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger

INSERT_UPDATE NewsletterEmailCronJob; code[unique=true];job(code);
 ;newsletterEmailCronJob;newsletterEmailJob;
INSERT_UPDATE Trigger;cronJob(code)[unique=true];active;year;month;day;hour;minute;second;maxAcceptableDelay;relative;weekInterval;daysOfWeek
 ;newsletterEmailCronJob;true;-1;-1;-1;-1;10;-1;1;true;