Situation
- There are N regional websites, one per country.
- The global marketing teams are responsible for global content.
- The local marketing teams should be able to manage local content only.
- Global teams should also be able to manage some local content if they have sufficient permissions.
- The system should be foolproof, meaning that any changes made by regional administrators should affect only their own website, not other local websites.
There are two ways to implement this partially:
- “Multi-language”: This is a good approach if all websites have the same design and components. Any exceptions should be implemented as hybris CMS restrictions. It is impossible, or very difficult, to configure the proper permissions. In this solution, the CA website administrator can change US website content, which is why this solution is only partial. When the number of regions/countries is more than 3–4, this solution is also inconvenient.
- Different pages for different countries. Per-page permissions. It will work, but with data duplication. Out-of-the-box apparel stores are implemented this way.
Complexity
Although the data model supports multiple content catalogs assigned to a single website (CMSSite), the cockpit itself is not ready. For a single content catalog, out-of-the-box hybris doesn’t have any capability to hide a particular content slot from users who don’t have sufficient permissions to manage it.
Challenge
Hide particular content slots in hybris WCMS, depending on the current administrator’s rights.

Solution
Technical solution
Architecture
WCMS part
There is an “interceptor” — the hybris layer between the model class and the service class. This interceptor replaces slot names on the fly.

Sequence diagram of WCMS-LoadInterceptor interaction
Storefront part
The Page Controller or Filter should set a variable, “region”, and push it into JSP.
JSP’s pageSlot tag has an attribute, “position”. In our solution, we will build the value of the “position” attribute dynamically using the value of the “region” variable.

PageTemplateModel.onLoad Interceptor
public class LoadVelocityTempateInterceptor implements LoadInterceptor<PageTemplateModel> {
@Resource
UserService userService;
@Resource
SessionService sessionService;
@Resource
CMSSiteService cmsSiteService;
@Override
public void onLoad(PageTemplateModel o, InterceptorContext var2) throws InterceptorException
{
// check if the request is from backoffice (WCMS)
if (cmsSiteService.getCurrentSite() != null) { return; }
String vt = o.getVelocityTemplate();
UserModel currentUser = userService.getCurrentUser();
Set<UserGroupModel> groups = userService.getAllUserGroupsForUser(currentUser);
Iterator<UserGroupModel> iter = groups.iterator();
while (iter.hasNext()) {
UserGroupModel ugm = iter.next();
String groupStr = ugm.getUid();
if (groupStr.indexOf("reg_") != -1) {
vt = vt.replace("_regional_", "_reg_" + groupStr);
o.setVelocityTemplate(vt);
return;
}
}
}
}Page Controller
...
model.addAttribute("regional", AreWeOnCanadianWebsite() ? "reg_ca" : "reg_us");
...JSP template

Velocity Template (for WCMS)

© Rauf Aliev, June 2016