Localizing VMware vSphere ESXi UI
Surfing the web I found some interesting posts here, here, here by William Lam, about how to change VMware vCenter and ESXi Host UI to get a different look. Focusig on ESXi, i doscovered some directories involved in the WebUI presentation logic which could be modified to change behaviour, look and feel.
In this post, I’d like to show how I realized the Italian localization for the ESXi 6.5 Web UI.
A single page UI with some key files
Staring with version 6.5 every ESXi host are equipped with a HTML5 UI to substitute the old vSphere Client. This is based on Angular Framework and some customized functions: from system perspective, this is a set of HTML, js and css files placed under the directory /usr/lib/vmware/hostd/docroot/ui/. Connecting to ESXi host the browser will redirect to /ui/index.html, a simple single page application that include a set of css and js files. The core of the UI is main.js (located under scripts sub-directory), which is responsible for:
- load internationalization files (under i18n sub-directory)
- render the template/templates according to the viewed section (the first access will show the login template)
- interact with XHR to the host using the api (https://hostip/sdk/)
The main.js (and the other files) are reachable for view or modify simply connecting via SFTP to the host, obviously after enabling ssh service through console UI or web UI.
Yes it’s obfuscated! But no panic: using a tool like JStillery it’s possible de-obfuscate the file clarifying functions, objects and variables.
Add another localization
The localization engine is a javascript file named i18n.js and located under bower_components/i18n-js/app/assets/javascripts. This contains the class to gather translation elements from internationalization files and substitute the template string according to the browser locale. In fact during main.js execution, there is a I18n method to ask if current locale is supported or not. If the current localization is not supported the locale variable will be set to “en-US”. (For Italian client this is the default)
Now it’s time to add another language: under i18n directory, for every supported languages, there are some sub-directories which contain the elements to translate composed by the following files:
- events.txt
- host.txt
- messages.txt
- network.txt
- option.vmsg
- resourcepool.txt
- storage.txt
- task.txt
- vfeed.txt
- vm.txt
- vui.txt
Now, copy the directory en_US (with its content) in the same directory (i18n) renaming with “it_IT” (or your locale identification). Then modify the content of all txt files according to your language.
In order to load all the new translation files you must modify the main.js at the following level adding the new directory:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
var supportedLocales = [ { locale: 'en-us', dir: 'en_US' }, { locale: 'fr-fr', dir: 'fr_FR' }, { locale: 'es-es', dir: 'es_ES' }, { locale: 'de-de', dir: 'de_DE' }, { locale: 'zh-cn', dir: 'zh_CN' }, { locale: 'zh-tw', dir: 'zh_TW' }, { locale: 'ko-kr', dir: 'ko_KR' }, { locale: 'ja-jp', dir: 'ja_JP' },// Here the new localization { locale: 'it-it', // localization id dir: 'it_IT' // localization directory } ]; |
Now to test the UI with the correct translation, you should set your browser language with the desired locale. Here my result:
Force Localization
This strict dependency with your locale could be not welcomed in all scenario: keeping the main.js file with only last modification, the only way to change the translation language is modify browser primary language. But there is a way to force the localization.
Find this function:
1 |
function ($rootScope, $state, $log, $window, $filter, Utils, PhoneHomeService, ClientSettingsService, vuiLocale, ENV) { |
then locate the following instruction:
1 |
var loadLocaleData = function () { |
and finally substitute or re-instantiate the userLocale variable with the desired language
1 2 3 |
var userLocale = ClientSettingsService.getRequestedLocale(); // Force here: userLocale = "en-US"; |
Enjoy your Hacking!
This is hacking! The natural fuel to bring the tech world a step ahead. For this reason cool companies like VMware are literally involved in projects and events to let the developers happy and free to show their idea to the entire community.
Want to learn more? Join {code}