Customising the NetScaler 11 User Interface – Adding Extra Content

I am finally getting round to playing with NetScaler 11, and working on a side-by-side migration from our working 10.5 installation. The configuration of all of the services, servers, monitors etc has all been pretty smooth sailing. However, the customisation of the user interface has been somewhat challenging.

With one hand, Citrix have given us a simple GUI method of applying customisations to the various vservers. They have also allowed customisations to be applied to individual vservers – a blessing as it allows simple customisation of different vservers without having to put in complex responders/rewrite rules.

Another advantage is the abstraction of the configuration (Nitro) UI from the public user interface. A few times when setting up our 10.5 installation I got something wrong and ended up accidentally breaking the admin UI. With the new mode, the admin UI is separate.

On the other hand, Citrix has taken away the immense flexibility that we had before. They may not have liked it, but you could customise any of the configuration files – index, scripts, css, and really go to town with your customisation. We appear to now be limited to specifying a handful of images and some CSS options. Not even a way of specifying a ‘Help and Support’ URL or anything potentially useful for a user.

There is a solution though! I have been working on a way which adds in two new sections to the login page. These sections pull in information from two HTML files that are a part of the customisation. It may not be perfect – and does involve modifying a couple of files outside of the customisation folder. However, the flexibility offered by this solution is fairly wide.

Below is a simple example of what can be done. The text at the top is part of the header that I have added and the text with hyper-links at the bottom is part of the footer file that I have added.

There are four main steps to achieving this:

  1. Modify the script file which generates the login page to add in two new <div> sections
  2. Modify the rc.netscaler file to copy this updated script file to the correct location every time that the Netscaler boots
  3. Create a header.html and/or footer.html file in the customisation folder
  4. Make it look pretty through the use of the custom.css file in the customisation folder

Making the page pretty is what takes the most work. The rest of the work should take you around 15 minutes.

1. Modifying the Script

Using WinSCP or a similar tool, download a copy of this file from the Netscaler: /var/netscaler/gui/vpn/js/gateway_login_view.js

You can make a backup of the original file in the same folder. Files in this folder are not removed or updated when the Netscaler is rebooted.

Open the file up, and modify the following lines that are highlighted in bold:


               //start header code
        var header_row1= $("<tr></tr>").attr("id","row1").append($("<td></td>").attr("class","header_left"));
        var header_row2 = $("<tr></tr>").attr("id","row2").append($("<td></td>").attr({"colspan":"2","class":"navbar"}));
        var header_table = $("<table></table>").attr("class","full_width").append(header_row1,header_row2);
        var logonbelt_topshadow= $("<div></div>").attr('id','logonbelt-topshadow');
        logonbelt_topshadow.append(header_table);
        //end header code
        //generic logonbox markup:can be used on majority gateway pages
        var authentication = $("<div></div>").attr('id','authentication');


        var logonbox_container = $("<div></div>").attr('id','logonbox-container');
        var logonbelt_bottomshadow = $("<div></div>").attr('id','logonbelt-bottomshadow');

        var logonbox_innerbox = $("<div></div>").attr('id','logonbox-innerbox');

        // Add in a Header DIV if the header.html file can be found
        var headerfile = new XMLHttpRequest();
        headerfile.open('GET', "../logon/themes/Default/header.html", false);
        headerfile.send();
        while (headerfile.readyState !=4) {sleep(10);};
        var logonbox_header = "";
        if (headerfile.status == 200) { logonbox_header = "<div id=logonbox-header>" + headerfile.responseText + "</div>" };

        var logonbox_logoarea = $("<div></div>").attr('id','logonbox-logoarea');
        var logonbox_logonform = $("<div></div>").attr({'id':'logonbox-logonform','class':'clearfix'});

        // Add in a Footer DIV if the footer.html file can be found
        var footerfile = new XMLHttpRequest();
        footerfile.open('GET', "../logon/themes/Default/footer.html", false);
        footerfile.send();
        while (footerfile.readyState !=4) {sleep(10);};
        var logonbox_footer = "";
        if (footerfile.status == 200) { logonbox_footer = "<div id=logonbox-footer>" + footerfile.responseText + "</div>" };

        authentication.append(logonbelt_topshadow,logonbox_container,logonbelt_bottomshadow);
        logonbox_container.append(logonbox_innerbox);
        //logonbox_innerbox.append(logonbox_logoarea,logonbox_logonform); // Original Line
        logonbox_innerbox.append(logonbox_header,logonbox_logoarea,logonbox_logonform,logonbox_footer); // Modified line adding in the extra DIV
        this._parent.append(authentication);

What these changes do is tell the logon page to look for a header and footer html file int he current theme directory, and if it finds them add the content into the display of the web page.

Leave the rest of the file as it is. Copy the file back to the same location on the Netscaler. Put a copy of the script in the live location by running the following command from the Netscaler shell:

cp /var/netscaler/gui/vpn/js/gateway_login_view.js /netscaler/ns_gui/vpn/js/ gateway_login_view.js

2. Modify the rc.netscaler file to copy this file at every boot

By default the files in the /netscaler folder get re-set every time that the NetScaler boots. The rc.netscaler file is used to perform actions every time that the system is booted – and so we can use this to copy the script to the correct location every time. From the shell prompt run the following command

echo cp /var/netscaler/gui/vpn/js/gateway_login_view.js /netscaler/ns_gui/vpn/js/ gateway_login_view.js >> /nsconfig/rc.netscaler

3. Create a header.html and/or footer.html file inside the customisation folder

Each of these files should contain raw html, without any headers or body tags. An example of the code in the files above is below:

Header

<div style="float: left">
	<h1>Citrix Remote Access</h1>
</div>
<div style="float: right; height: inherit; width: 300px; background-size: cover; background-position:center center; background-repeat: no-repeat; background-image: url(../logon/themes/Default/custom_media/logo.png);"></div>

Footer

<table style="width:100%">
	<tr>
		<td align="center">
			<a class="plain input_labels form_text" href="https://support.yourcompany.co.uk" target="_new">For further information on how to access and use this service, please click here.</a>
		</td>
	</tr>
	<tr>
		<td align="center">
			<a class="plain input_labels form_text" href="http://receiver.citrix.com/" id="DownloadLinksFont" target="_new">Download The Latest Citrix Receiver For Your Client</a>
		</td>
	</tr>
</table>

Save the files with their respective names in the following location: /netscaler/logon/themes/<THEMENAME>/

If the files are not called the correct name, then the div will not be displayed on the login page.The name should be all lowercase with a .html extension. The pages inherit the CSS that is already applied to the pages, so applying further style settings inside these html files can be counter-productive. There are enough style files already applying to the login page – this could be too much or the simple solution to making the header and footer sections do exactly what you want.

If you want to reference other content, such as images, from within these files, then the paths that you enter need to be relative to the /vpn folder. Netscaler, through some magic, always presents the current theme in the same location though, and the path to the root of your theme is “../logon/themes/Default/. As an example, if you wanted to add an image to your header file and the image is saved in the same location as the header file, you could do so with the following:

<img src=”../logon/themes/Default/header_image.jpg” alt=”Header Image” />

The same path and logic applies for linked in script files or any other content. My only recommendation would be to keep the code that you create as lightweight as you possibly can. You do not want to be increasing the logon times for the page more than you need to.

4. Customise your login page

Using the custom.css file, you can now customise the entire page, including the display of the header and footer <div> tags that are included in the login page.
I have to be honest, that getting to a reasonably pretty page may take some time. I am not a web developer, so I may not have been approaching this in the best way. I ended up using the Firefox developer tools to make changes to the live style sheet until I worked out exactly what settings and values I wanted. I then put my changes into the custom.css file.

You can make changes to the css file direct on the Netscaler, but you then have to be aware of caching that is taking place in browsers and on the Netscaler that mean that your changes may not be reflected instantly on the site.

In case it helps someone else out, I have included the changes that I made to the CSS file in order to get the result above. This may serve as a baseline to help you achieve your desired result.


.header {
 width: 100%;
}

/* This is the actual auth box in the centre, contains the header, form, and footer */
#logonbox-innerbox {
    background : #FFFFFF;
    display: block;
    border-radius: 15px;
    border-style: none;
    padding: 0px;
}

/* The new header div that we added. Curve the top corners and apply a background colour */
#logonbox-header {
    background-color: #422E5D;
    border-radius: 15px 15px 0px 0px;
    height: 100px;
    padding: 15px;
}

/* The new footer div */
#logonbox-footer {
    padding: 0px 10px 20px 10px;
}

/* The header we put inside our header div */
#logonbox-header h1 {
    font-family: citrixsans-light;
    font-weight: unset;
    font-size: 40px;
    color: #FFFFFF;
}

/* Actual logon form */
#logonbox-logonform {
    width: 80%;
    margin: auto;
    padding: 30px 47px 20px 20px;
}

/* I needed to make the titles of the form fields larger. Set these 2 */
#logonbox-logonform .plain.input_labels {
    width: 200px;
}
#logonbox-logonform .field .left {
    width: 200px;
}

#authentication {
    width: 900px; /* Set the overall width of the authentication dialog */
    margin: 0px auto; /* Make the auth box sit in the centre of the page */
}

Done!

That’s it. You should now have the ability to add much more content to your login pages, and customise that content on a theme by theme basis. Be patient when testing, as I found various caches kept sending me back the old versions of css and content files.

I get a blank page after making the changes

This occurred for me when I had incorrectly formatted HTML in either of my files. All HTML should be properly terminated.

Important Note about NetScaler Updates
When you upgrade the software on your Netscaler, the script file that you edited will be replaced. You will need to make the changes in step 1 again. Any files that you include as part of the theme file are retained though.

3 people found this post useful.


12 thoughts on “Customising the NetScaler 11 User Interface – Adding Extra Content

  1. Since there is only one gateway_login_view.js file, does this mean you can only use this with one theme on the entire netscaler? In the case, with a theme called Default? Or is there a way I could use this with more than one theme?

    1. The gateway_login_view.js file is shared amongst all of the themes running on the NS, so the new sections will be added to all themes. You would just need to create custom header and footer files for each of the themes.

  2. Hi,
    I implement it and it works with external html files except for one thing that I could not figure out how to solve it.
    If my header.html or footer.html files contain sections, these entry are deleted from the final result.
    All xxxx is gone.

    Anyone succeeded using scripts in header and footer ?

    Regards

    1. I’ve never tried to put a script in the header or footer, and to be honest I wouldn’t expect it to work. From what I recall the code you put in gets embedded into the page, so the script block you add would not end up in the right place in the document to be evaluated.

      I haven’t looked at this in a while though, so I might be totally wrong. Be interested if you did get it to work though.

    1. I added this block to the custom.css file:

      #logonbox-logonform input[type=”text”], #logonbox-logonform input[type=”password”] {
      border-style: solid;
      border-width: 1px;
      }

  3. Hi Craig,
    first of all: many thanks for sharing your experience with us – good work. Of course I ran into this customization thing with NSOS 11.0 and nothing worked, but your way does. Unfortuantely, using JavaScript with e.g. footer.html (in order to use i8n strings defined in XML ressource files) breaks the whole logon page. So you’re bound to native HTML.

    1. Hi Jochen,

      Thanks for the feedback. Interesting about the scripts – I would have thought that you could put inline scripts as it would process them as it went through, but I didn’t try it as we ad no need. If you do happen to find a way it would be good to hear about it.

Leave a Reply

Your email address will not be published. Required fields are marked *