OutSystems Dynamic Themes

Luís Santos Monteiro
Noesis Low-Code Solutions
5 min readFeb 19, 2020

In the world of OutSystems, there is no lack of customizability when you know your way around CSS and JavaScript. In this article, we’ll be sharing how we handled one of the requisites from a client, who needed a web application that changed its color scheme, that we’ll call theme, based on the logged-in user. These themes could be one of 5 predefined themes, or a completely new one, customized by the user on our application. We will explain how we achieved this on 3 sections. First, we’ll explain the backend part of the solution, then, how we built the frontend to support the finite number of predefined themes and finally how we supported the customized themes.

1 — The backend:

Our application is based on services, so for us, what we do on the User Provider is ask for the information regarding the user trying to login using a REST call and then we’ll receive which type of theme does the user have, so we’ll receive something like “NAME1”, “NAME2”, “NAME3” or “CUSTOM”. These names are constant and agreed upon. We then store this information on a session variable.

If we were not based on services we could just save this information associated to the User Id and query it upon login.

In the case that the user is using a “CUSTOM” theme, there is also another REST service that returns the color that the user picked on our theme edition page. Again, on a non-service based app, we would just store this information on the database associated to the User ID and query it.

With this information stored, we can move then the frontend part.

2 — Predefined themes frontend:

Using OutSystems platform 11 we know that the CSS style sheet is based on CSS variables like these:

/* Color — Brand */
— color-primary: #146ef5;
— color-secondary: #303d60;

Such variables make changing themes super easy since we only need to change their value and all the application will display the new values! This is great and is the foundation of our solution. We know that we can easily change the theme of our application, now we only need a way to make it dynamically!

To approach this issue there are a lot of solutions that we could think of, like having some javascript that ran while the page is rendering that would change the value of these CSS variables using the style.setProperty() method.

However, we wanted something clean, only based on CSS, to maximize performance and maintainability of the code. The CSS based solution must rely then on having a simple class for each possible theme and then adding these classes dynamically to the body or wrapper div of the application. In this way, we could declare the CSS variables for each theme in advance and make these values override the main ones. In the end, on our Theme application’s CSS file we ended up with something like this:

.theme-NAME1{
— company-main-color: #990000;
— company-main-color-lighter: #ae0000;
— company-main-color-darker: #550000;
}
.theme-NAME2{
— company-main-color: #59595b;
— company-main-color-lighter: #ae0000;
— company-main-color-darker: #e7e7e7;
}
.theme-NAME3{
— company-main-color: #499442;
— company-main-color-lighter: #499442;
— company-main-color-darker: #fff139;
}

Then, we needed a way to add the class “theme-NAME1”, “theme-NAME2” or “theme-NAME3” based on the user. For this, we added a single input variable to our theme’s Layout web block which would have the value of “NAME1”, “NAME2” or “NAME3” based on the user. This input variable is given the value of a session variable that is initialized upon login on our user provider. We check what is the theme that the user trying to login should use and then simply initialize the session variable accordingly. Finally, we just need to add the correct class to the body or wrapper div of the application. We did it like this:

3 — Custom theme frontend:

Layout Extended Class

We are left now with one last challenge. What about the users who’ve created their own theme?

In those cases, since we didn’t want to run JavaScript at run time, we decided that the best approach was to do it with a different CSS file. This idea came from this OutSystems forum post. Basically, whenever we get a user with a Custom theme, we generate a CSS file with the declaration of the CSS variables of the theme, assigning to them the values that we got from the REST endpoint and set it not to be downloaded to the disk of the user, but rather to be used as a source of the web page.

Looking at it with detail, on the preparation of our Layout web block we added this condition:

Style Sheet Tag

which adds a <style> tag to the header of the HTML code, with the source URL given, in this case, the site property CustomColorsEntryURL.

This URL is very important. It will be the entry point of another page on our application. This page will have no visible content, we only need to run its preparation, which will be the place where we’ll create the new CSS file and download it. It looks like this:

The TextToBinaryData server action will have Encoding “utf-8” and the Text will be the contents of our CSS file, in our case:

Download CSS file
".theme-CUSTOM{- company-main-color: " + EncodeHtml(GetCustomColors.CompanyMainColor) +";- company-main-color-lighter: " + EncodeHtml(GetCustomColors.CompanyMainColorLighter) +";- company-main-color-darker: " + EncodeHtml(GetCustomColors.CompanyMainColorDarker) +";
}"

Then there is only one thing left to do, which is to download this CSS as a file with the .css file extension. We did it like this:

This is it! In this way, we are able to have 2 different types of themes, using simple CSS classes and variables we can create predefined themes and even give the user the possibility to have his own custom theme! We need only to add the correct CSS class according to the desired theme and, in the case that the theme is custom, create and download the new CSS file with the custom colors of the user.

Live example here

--

--