Making Liferay Portal RTL friendly - the story behind.
Company Blogs January 27, 2014 By Iliyan Peychev
The previous versions of Liferay Portal already supported RTL (right-to-left text) in limited way, but since we started the development cycle of Liferay 7.0 we really wanted to improve it. In front of us there were two main goals:
- to convert automatically as much as possible of the UI when language direction is changed
- to free the developer as much as possible from the task of supporting these two modes
As most of you probably know, in Liferay 6.2 we did one of the most important changes in the UI we ever made - we get rid of our home brewed CSS framework in favor of Bootstrap and Font Awesome. Among many other good things these changes provided, they allowed us to have stable base for further improvements. One of these was that we were finally able to add support for RTL in a proper and smart way.
How did we make it?
The whole idea is very simple - when we build the CSS files, once we execute the Sass2CSS task, we run one more. Its purpose is to convert automatically properties like “margin-left”, “left”, “padding-left” to “margin-right”, “right”, “padding-right” and so on. In order to achieve this, we involved in the game an excellent Open Source project - R2. Our initial results looked incredible good, even more than we expected. It turned that applying R2 to Portal converted most of the UI properly. However, as usually happens, the devil is in the details. “Most of the UI” does not mean all of the UI. And we wanted to do it properly.
The problems we met
I can categorize these in two main categories - glitches in our UI and issues with the third party tools and frameworks we use.
It turned we didn’t have many issues in our own UI. We had a few - glitches with Dockbar, with some input text fields and so on, which we solved successfully and relatively fast.
About the libraries and frameworks, one of the issues we had with R2 was how exactly to execute it as part of our build process? For those which are not aware of R2, this is a NodeJS project but for different reasons, we cannot use NodeJS in Portal. The only option we had now was to use Rhino. When we started to use R2, they weren’t using any external NodeJS projects so it was very easy for us to make it working with Rhino.
However, we discovered very soon an issue (they weren’t parsing some comments properly), which was fortunately fixed in their new version. The point was that in this new version they not only fixed that, but also started to use another Open Source project - css-parse. This is another NodeJS project which has its own dependencies and we were unable anymore just to get R2 script and execute it with Rhino. The solution turned to be simple - we used Browserify to extract all dependencies and create a single file and (with only one very small patch) we were able to execute R2 in Rhino again.
We had to fork both R2 and css-parse in order to resolve some different issues. For example, css-parse throws exception when an at-rule is being placed in some qualified rule’s block. Because we prefix with .aui class the whole Bootstrap, Sass parser generates invalid CSS, which the browsers simple ignore, but css-parse dislikes so much, that it throws exception. We reported that issue and it seems they will consider to fix it. Until then, we patched css-parse to simple ignore such rules and to exclude them from the AST.
The fork of R2 was needed not only because we had to include our patched version of css-parse, but also in order to add support for cases which were not yet supported. We also introduced in our fork the conception of plugins. One of these plugins is about swapping icons in Font Awesome, another one is to fix the resize handlers CSS in YUI3 Resize module and so on.
Fixing an issue in YUI3
During our testing process, we discovered an issue in YUI3. Basically, updating the position of an element via setXY in Y.DOM does not work properly with right positioned elements. We filled an issue and also proposed a fix, so let’s hope we will have it fixed there (otherwise we will have to fix our fork of YUI3). Apart from that, the process of tuning up both AlloyUI and YUI was flawless.
Supporting RTL turned to be an interesting task from engineering point of view. It wasn’t quite simple and required dealing with issues in both our UI and our core frameworks.
Ok, perfect, so what’s next?
Well, from engineering point of view, the task is finished. We will backport the solution to 6.2 very soon and voilà, we are good to go!
At the end, I would like to say thanks to the people who also get involved in this task and made great job - namely Chema, Eduardo Garcia, Robert Frampton and Nate.
[Edit] As requested by James Falkner, here are some screenshots.
Edit page in RTL mode:
Document Library in RTL mode: