Using themeDisplay in javascript, but be aware of types

Hi everyone,

Having worked with Liferay, you are probably well aware of the useful ThemeDisplay. The ThemeDisplay object can be accessed through javascript as well - a global variable called themeDisplay. While you don't have as much information on the javascript version of themeDisplay, you can still get some very useful information from the object. Check it out yourself by logging to the console (using Firebug):

AUI().ready('',function(A) {
    console.log(themeDisplay);
});


However, beware of one thing. The attributes available through the javascript version of themeDisplay are strings. This could bring some serious confusion when working with the attribute. Consider the following code:

AUI().ready('',function(A) {
    
    var isPrivateLayout = themeDisplay.isPrivateLayout();
    
    if(isPrivateLayout) {
        console.log('I am a private layout.');
    }
    else {
        console.log('I am a public layout.');
    }

});


If you visit a public layout in Liferay, you would assume that "I am a public layout" would be logged to the console. But since the attributes accessed through themeDisplay are of the type string, the if statement will always be evaluated as true, since the variable isPrivateLayout will always have a value (either 'true' or 'false').

You can check type by running for example:
console.log(typeof(themeDisplay.isPrivateLayout()))

Now, some might think, this is easy, let's just double negation (!!) to type convert the string:

AUI().ready('',function(A) {
    
    var isPrivateLayout = !!(themeDisplay.isPrivateLayout()); // Evaluates to true
    
    if(isPrivateLayout) {
        console.log('I am a private layout.');
    }
    else {
        console.log('I am a public layout.');
    }

});


This won't work, however, since in javascript any string that is not empty will evaluate to true. Same thing would go for parsing the string through the Boolean operator:

var isPrivateLayout = Boolean(themeDisplay.isPrivateLayout()); // Evaluates to true

So what do we do? The best way is to set the value of isPrivateLayout using string comparision with the conditional operator:
var isPrivateLayout = (themeDisplay.isPrivateLayout() == 'true') ? true: false;

This says that if the value returned from themeDisplay.isPrivateLayout() has the string value 'true' then the variable isPrivateLayout should be true. Otherwise the value should be false.

Cheers,
Erik

Edit 2011-09-28

Just discovered that the discussion above does not apply to all properties accessible throught the ThemeDisplay object. The isSignedIn (themeDisplay.isSignedIn() ) function will return a boolean, and not a string.

As described above, you can check the type of each property using the following:
console.log(typeof(themeDisplay.isPrivateLayout()))

Blogs
Hi Erik, Thanks for this. themeDisplay is indeed very used in JS. Do we always have to use themeDisplay inside AUI.ready() function ? or is accessible directly on any Liferay page with AUI.ready() ?
Hi Advait, the themeDisplay object is put on the global context object (in general the window object) so yes it can be accessed outside the AUI sandbox, i.e. outside the AUI.ready() function.
Adrian, yes of course that works and is better than using the conditional operator in this case. Thanks.
Hi, this looks very promising. However my themeDisplay object is always empty, is there some setting in portal-ext.properties to enable it?
Hi Kyrre, no you should not have to enable anything in portal-ext.properties for this. What version of Liferay are you running? Do you get any empty themeDisplay object both inside and outside the the AUI.ready() function? Also, are you sure that your themeDisplay object is empty? If you log it to the console with console.log(themeDisplay) the output will look like "Object {}". Thus it appears to be empty, but if you click on "Object {}" you can browse down the object.