Change system language with CUTE

A short 5-step-guide how to use the Confluence add-on CUTE to easily make a system language switch without knowledge in the Confluence plugin development.

During my daily work with Confluence I often need some kind of functionality more than other kinds. In those moments, I wish these functions can be easier and faster to achieve. This is especially true if the click path is very long. One such case is the change of the Confluence system language of my current user account.

But you can meet this requirement quickly by using CUTE. For this, I need no knowledge in the Confluence plugin development. It is enough if I am familiar with Velocity, Javascript and CSS.

Step 1: Creating a new extension

After the installation of the plugin using the Atlassian Marketplace, I can start right away. Via global Administration > CUTE  the configuration view of the tool appears. Here I choose “Add Extension” and fill in a name and a unique key for my extension.

After this, I can finally begin working on the extension by clicking “Edit”.

Step 2: Generate a list of all confluence installed languages

First of all, I need the information which language versions are actually installed in the confluence system. For this purpose, I search in the Atlassian Confluence API and promptly find the LanguageManager that provides the method “getLanguages​​”. So I create a new template resource in my extension.

With this, I can create any structure using HTML and Velocity. The code will be inserted automatically to all pages and is hidden by default. I conclude that the list of languages should be located in the global navigation bar of Confluence. So I look at the existing global Confluence menu and create my own structure similar to this. Furthermore, I’ll get the LanguageManager directly inside the template by using the provided service “applicationService” and its method “getComponent”:

#set($languageManager = $applicationService.getComponent("com.atlassian.confluence.languages.LanguageManager"))

I want to use no text for the top menu item. So I look for a meaningful logo and add this to the extension. Below the added logo, a path appears which I can simply import into my template.

This is the final template code for my language list menu:

#set($languageManager = $applicationService.getComponent("com.atlassian.confluence.languages.LanguageManager"))
<div id="cutelanguagebox">
    <li id="cutelanguagemenuwrapper">
        <a id="browse-cutelanguages-link" href="#">
            <span>
                <img id="cutelanguage-icon" src="@contextPath/plugins/cute/static/resource/communardo.language.switch/globe.png" >
            </span>
        </a>
        <div hidden="">
            <ul>
                #foreach( $language in $languageManager.languages )
                    <li>
                        <a href="#" locale="$language.name" title="">
                            <span>$language.displayLanguage</span>
                        </a>
                    </li>
                #end
            </ul>
        </div>
    </li>
</div>

Step 3: Moving the template Container

The template code is now embedded in every page (except the administration views). However, it is hidden and needs to be moved to the appropriate location by using Javascript. So I create a new javascript resource.

Since I have marked my navigation in the template code with the id “cutelanguagebox”, I can now simply move the container to the navigation menu and re-initialize the menu afterwards. Here is the javascript code:

AJS.toInit(function() {
    jQuery("#header-menu-bar").prepend( jQuery("#cutelanguagemenuwrapper"));

    //reinitialize menu after modification
    jQuery("#header-menu-bar *").unbind();
    jQuery("#header-menu-bar").ajsMenu({
        isFixedPosition : true
    });
});

Step 4: Change the system language

The change of the system language after clicking on one of the language menu items is done by using javascript. I use the same action as it is used in the user profile configuration. For this I use a new javascript resource which executes an AJAX request in the background. If this was successful, I reload the page using Javascript. Here’s the code:

AJS.toInit(function() {
    jQuery("#cutelanguagemenuwrapper .cutelanguagelink").click( cuteChangeLanguage);
});

function cuteChangeLanguage() {
    jQuery.post(contextPath+"/users/doeditmysettings.action", {atl_token: jQuery("#atlassian-token").attr("content"), preferredUserLocale : jQuery(this).attr("locale")}, function(data){
        window.location.reload();
    });
    return false;
}

Step 5: Polish the edges

Now, the result can be seen. However, the icon is too big for the top navigation bar. This can be fixed by using a little bit of CSS. I add a new style sheet resource.

In there, I define a style that brings up the icon to a good size. Here is the CSS:

#cutelanguage-icon {
    width: 20px;
    vertical-align: middle;
}

The Result

And thats it! The new menu item in the global navigation fits great into the existing style and also works with the other default themes (Documentation and Easy Reader). In addition, the extension is compatible from Confluence 3.4 up to Confluence 4.2. This is ensured by the minimum engagement of the system. The chance of compatibility with new versions is very high because there was no plugin developed which overrides central Confluence templates.

The extension itself can now be easily exported and imported to any other Confluence system.

Copy it and make it more beautiful!

I have stored the extension to our support portal so you can use it on your own system. It is a good starting point for extensions going in a similar direction.

Leave a reply