Skip to Content

Switching Themes by Topic – A Color Code System for the Portal

Have you ever wanted to change the color palette of the portal according to the current top level topic (i.e. entry point)?  Like on ,, or (sorry, all German sites).  Well, with this bit of code you’ll be able to do so.  And the best for frightened aah-no-we-sure-don’t-want-to-modify-the-standard managers: you don’t have to modify anything, you just enhance the standard!</p>

The code

Here is the recipe:

Create a new Portal Application (say: and a new Portal Component (say:, class name: ThemeSwitcher).

Then place the following Javascript code into the component (either with repeating response.write() statements or by including a JS/JSP):

// contains the ID of the currently displayed theme

var oldTheme = “”;

// the matching table is an associative array (with the exception of the default entry)

// having the match strings as keys and the theme IDs as values

var matchTable = new Array();

matchTable[0] = ‘sap_standard’;

// the default theme

matchTable[‘/super_admin/super_admin_role/’] = ‘sap_chrome’;

matchTable[‘/every_user/general/eu_role/’] = ‘sap_tradeshow’;

/…add more matches here…/

// themeSwitcher function subscribed to the “UpdateTLN” event,

// which is fired before the actual navigation takes place

function themeSwitcher(evt) {

     // get the current NavigationTarget

     var navigationTarget = evt.dataObject;


     // decide on theme by looking at the current NavigationTarget

     var theme = matchTable[0];

     for (var match in matchTable) {

          if(navigationTarget.indexOf(match)>-1) {

               theme = matchTable[match];





     // do nothing more if the theme has been set already,

     // otherwise save theme in oldTheme (for performance opts)

     if(oldTheme == theme)



          oldTheme = theme;


     // add – if not already happened – the post parameter (-> form input) “theme” to

     // the form “frmChangeContent” that is posted against the innerpage when navigating;


     // the additional parameter will cause the innerpage to load with the new theme

     var themeInput = document.getElementById(‘themeInput’);

     if(themeInput == null)

          document.getElementById(‘frmChangeContent’).innerHTML += ‘Remember to exchange the match table with your data (here: match strings and resulting themes) as stated in the comment.  The match strings should be substrings of the names of navigation nodes (like ROLES://portal_content<b>/every_user/general/eu_role/</b>  If you rewrite the code a bit you could even switch themes using a “dynamical” match table by including the theme name in the technical name of the role (by using some convention, like<b>__theme__topic_one</b> for the theme topic_one) and cutting out the theme name with Javascript.

The theme switch could even be done for (sub)nodes other than entry points – just provide corresponding match strings.

If you just want the inner page to load with the new theme and not the framework page as well, then leave out the last for-loop.

Nota bene:
(1) This code currently works only for themes that are stored in the theme root folder (not “customer” or alike).
(2) And it has been successfully tested for a NW portal (mine is currently SPS 12). It might work for previous SPS’ as well. But I don’t guarantee it for future versions ;-).

Why does that work?

The mystery behind the code is that navigation in the portal is done by calling EPCM.doNavigate().  This in turn will internally raise a portal event (EPCM.raiseEvent(“urn:com.sapportals:navigation”, “Navigate”, navigationTarget)) that is caught by a subscribing function named onNavigate(evt).  That function then raises an update event (EPCM.raiseEvent(“urn:com.sapportals:navigation”, “UpdateTLN”, navigationTarget)) before the actual navigation takes place, i.e. before the new NavigationTarget parameter is posted to the inner page.  Well, this is exactly when we want the theme switch to happen.</p>

You must be Logged on to comment or reply to a post.
  • Hi Sven,<br/><br/>This code works really well.  I'm using it myself, and it works like a dream.<br/><br/>This is the code change (the for statement at the end):<br/><br/>   for (var s=0; s<document.styleSheets.length; s++) {<br/>       var styleSheet = document.styleSheets[s];<br/>       var href = styleSheet.href;<br/>       var pos = href.indexOf('/themes/portal/');<br/>       var posCus = href.indexOf('/themes/portal/customer/');<br/>       if(posCus > -1) {<br/>          pos += '/themes/portal/'.length;<br/>          posCus += '/themes/portal/customer/'.length;<br/>          var nextSlashPos = href.indexOf('/', posCus);<br/>          styleSheet.href = href.substring(0, pos) + theme + href.substring(nextSlashPos);<br/>       } else if(pos > -1) {<br/>          pos += '/themes/portal/'.length;<br/>          var nextSlashPos = href.indexOf('/', pos);<br/>          styleSheet.href = href.substring(0, pos) + theme + href.substring(nextSlashPos);<br/>       }<br/>   }<br/><br/><br/>It's funny how I have been trying to figure this out for the last week and this blog comes up.  Perfect timing.<br/><br/>Cheers,<br/>Kevin

    • Hello Kevin, I tried to implement the code as mentioned but the inner page is not working. I have coded as mentioned in the forum.


  • Hi Sven,

    Did you test this code in a SP15 Portal? Seems that changes were made to the Portal logic.

    The header area is updated with the new themes. However, the inner page is not affected by the theme changes and also additional links other than entry points are not updated as well (all of them still using the default theme)

    Could you please help me to understand what is happening?

    Thanks in advance

    • Hi,
      the answer is simple: since SPS14 there is this new feature called "Short/Hashed URLs", i.e. a NavigationTarget of type "ROLES://portal_content/path_to_role/role/path_within_role/page" can be shortened to something like "navurl://a1c86b637e4a836f689ef74ae4663b79". My code described here actually *needs* the first version since it tries to find patterns therein. So, if you want this piece of code to work then turn off the Short URLs: System Administration > Navigation > Short URLs >> Use Short ULRs = false. Otherwise you'd have to develop a new Theme Switcher component/iView that reads the NavigationTarget parameter, get's the corresponding NavigationNode and its (long) name (via API), and once it has recognized a pattern causes a reload of the request together with the new "theme=" parameter. Sort of like this. Remember, I gave no guarantee for future versions 🙂
      Best regards
      • Hi Sven,We have the following issue.
        The header area is updated with the new themes. However, the inner page is not affected by the theme changes. We are trying to change the back color of the portal, but when we change the theme it only changes in the header area but not in the content area
    • Hello Sven,
      I was trying this code on the Light framework page and it does not work!!. Also when we navigate from one top level navigation to other this theme change component automatically dis appears .. Dotn know why...... I checked from the browser view source and I just cant find the theme component ... Please advice !!.

  • Sven

    Is there any way to get this to work on SP2? I have tried but the theme does not appear to be applied before the URL's are built in the detailed navigation.

    Thank you

  • Hi.

    Congratulations for this code. I'ts genial.

    But ... have you tested with Firefox/Mozilla?

    I've run on IE and work's perfect, but not in Mozilla.


  • Having a problem when using portal with Right To Left (Habrew and Arabic) there java script makes a long scroll in the lower part of the window and the masthead is moved a bit with no relation to the position of the other sections of the screen.
    Anyone got idea why and how can this be fixed?