Month: November 2017

14 Nov 2017

Hybris : How to replace base_{locale}.properties approach to fetch localized content for website

Introduction

In Hybris e-commerce platform, localization of certain content on the web pages is addressed by spring framework class “ReloadableResourceBundleMessageSource” which takes care of fetching the messages from base_{locale}.properties

base_{locale}.properties :

The keys and it’s values are referred in the jsp/tag files using spring framework tag library

Problem Statement or current limitations

The approach of fetching localized content from base_{locale}.properties has certain limitations that can be explained with the below mentioned scenario:

  • A website has launched and a long-awaited campaign is finally live. The site is experiencing heavy traffic with many customers accessing the site across the globe. The content manager suddenly realizes that some content on the site is incorrect and need to be corrected immediately.
    • What are the steps to correct the content on the site?
      • Inform the IT team that manages the site and explain the issue with the content.
      • IT team analyzes the issue and finds the root cause.
      • IT team informs the content manager that the content value in base_{locale}.properties needs to be corrected. It would take a few minutes to make this minor change and servers would need to be restarted to reflect the updated content.
      • Servers restarted after the changes are made in base_{locale}.properties and the updated content shows up on the site.

Instead of every such minor content change going through the above cycle:

  • What if such a change could be made without any server restart?
  • What if a content manager is given the ability to update content without relying on the IT team and have it reflect on the site immediately?

How amazing it would be if a content manager has the power to make changes to content just as he/she manages content in WCMS (Web Content Management System)!

Solution

Here’s an approach that will empower a content manager to make changes to content that is a part of base_{locale}.properties without having to chase an IT team to get a fix in place, without having to restart servers and still have the change reflect immediately on the site

  1. Create an item type which stores all the key=value that is defined in base_{locale}.properties.
    • The item type can be made catalog aware to ensure that the content value that is changed can be previewed before allowing the change to reflect on the site.
    • The value qualifier in the item type can be localized to ensure that this approach takes care of storing the values of locales that the website supports.
  2. Override the ReloadableResourceBundleMessageSource class of Spring framework which fetches the values from base_{locale}.properties with the new class  CustomBundleMessageSource. This takes care of fetching the value from the database.
  3. Make the newly created item type, that stores the key and values that are usually created in base_{locale}.properties, available in Back Office such that content managers can login to Back Office and make the necessary changes without relying on an IT team to make content corrections.

Performance considerations

As the proposed solution indicates that an item type is created to replace base_{locale}.properties for fetching the localized content. This implies that every request to fetch content will result in a call to the database, giving rise to performance concerns. To avoid making a database hit for every request, load the data from every query to the item type in the cache thereby any request for the same message content will be fetched from the cache and not from the database. This will prevent any subsequent database calls being made to fetch the content that’s already in cache.

To achieve this, introduce a class, say “BaseMessagesCacheRegion“, which extends “EHCacheRegion“. This will hold all the values that are returned by the queries to fetch the content messages from the database.

This leads to another point of consideration – when a content manager updates the content from Back Office, the changes will not reflect on the website immediately. The reason being that that particular value is already in the cache. When the system identifies the content’s key and its value in the cache, it will not query the database to fetch the value that has been updated by the content manager. To display the updated content on the website, one must login to HAC and clear the entire cache.

This implies that the cached data for the entire content is cleared and not just the one for which the content manager has made an update via Back Office. To address this, introduce an interceptor which will take care of updating the cache with recently updated content in Back Office. This will eliminate the need of clearing the entire cache from HAC.

Note: There are many ways to address updating of cached content; what has been used here is the approach of an interceptor to address the update of cached content.

References of a working example:

  • Snapshot of Back Office displaying “BaseMessages” item type created to load the base_{locale}.properties data.

  • “contentBaseMessageCacheRegion” that’s introduced to store the cached content of BaseMessages.