Accessibility for no-script situations
First up, we need to keep in mind that the page should still be accessible when scripting is not available. We are storing the different language parts in separate files, such as military-english.html and military-prydeinig.html, so the most accessible technique is to link to those pages. That allows people without scripting to get to the content they need, and when scripting is available it can replace those links with the retrieved content.
<div id="content">
<a href="military-english.html">English content</a>
<a href="military-anglisc.html">Anglisc content</a>
<a href="military-prydeinig.html">Prydeinig content</a>
<a href="military-francais.html">Francais content</a>
<a href="military-deutsch.html">Deutsch content</a>
</div>
Selecting the language
The above links are only for a “no scripting” situation though.
With the select box, we give it values so that the script can easily find the appropriate file. The language suffix on the above filenames match the below option values, so that the script can automatically determine the correct file to retrieve.
<select id="language">
<option value="english">English</option>
<option value="anglisc">Anglisc</option>
<option value="prydeinig">Prydeinig</option>
<option value="francais">Francais</option>
<option value="deutsch">Deutsch</option>
</select>
Retrieve the file with Ajax
When someone selects Prydeinig we want the content section to be replaced with that which is in the military-prydeinig.html file. Ajax is used for that, for which there’s a very good book called Bulletproof Ajax. When we go to its [url=“http://bulletproofajax.com/code/”]code and examples we can see that Chapter 4 contains code to retrieve content from an HTML page and display it within the existing page.
The code to do that (slightly modified in the parseResponse() function to work with our content section) is:
function getHTTPObject() {
var xhr = false;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
xhr = false;
}
}
}
return xhr;
}
function grabFile(file) {
var request = getHTTPObject();
if (request) {
request.onreadystatechange = function() {
parseResponse(request);
};
request.open("GET", file, true);
request.send(null);
}
}
function parseResponse(request) {
if (request.readyState == 4) {
if (request.status == 200 || request.status == 304) {
var content = document.getElementById("content");
content.innerHTML = request.responseText;
}
}
}
Put scripts in a separate file at the bottom
Now is a good time to bring up that scripting code should not be embedded in the HTML code for the page. Instead, it should be in a separate script file that you load at the end of the body with:
<script src="js/script.js"></script>
</body>
</html>
That allows the page to load even faster than if the script were in the head, and the script can be used on more than one page without needing to download the script again.
Which content file to retrieve?
As the page loads, we attach an onchange event to the select field that retrieves the content.
While it’s possible to use ‘military-’ + language + ‘.html’ to create the file name, I want the script to be more flexible so that it can be used on more than just the military page, so I’ll instead use a regular expression to find the filename, split it, and then append the language on to the filename.
var select = document.getElementById('language');
select.onchange = function () {
var language = this.options[this.selectedIndex].value,
filename = location.href.match(/([^\\/]*).html/)[1];
grabFile(filename + '-' + language + '.html');
return false;
}
select.onchange();
So if the page was history.html and the chosen language is Francais, it will try to load the content from history-francais.html
The last part triggers the onchange event, so that the content can be automatically retrieved as the page loads.
Load the page with a desired chosen langauge
So the page now automatically retrieves the content when you select different language settings. How can we get the page to load with a language of our choice?
We can load the page with a querystring such as ?lang=prydeinig
The script can then set the select box value to whatever it provided as that value. If the select box contains a matching value, it will set the select box to that value.
Then the typical page-load checking of the select value can take place.
JavaScript doesn’t provide a way to easily interpret the querystring value, so we’ll roll our own solution:
function getQueryString() {
var qs = {},
terms = location.search.substr(1).split('&'),
i,
split;
for (i = 0; i < terms.length; i += 1) {
split = terms[i].split('=');
qs[split[0]] = split[1];
}
return qs;
}
Now, in-between defining the select variable and checking the select box, we can get the querystring and set the select box to that which is specified in lang.
var select = document.getElementById('language'),
qs = getQueryString();
if (qs.lang) {
select.value = qs.lang;
}
select.onchange = function () {
...
So now we can load the page as history.html?lang=prydeinig and the page will set the select box to Prydeinig, and then loads the content from history-prydeinig.html to show within the page.
Test page to demonstrate the code in action
I’ve put up a test demo of this using your history page as an example, over at http://paulwilkinsdev.110mb.com/i18n/military.html
I’ve edited the quotation for the French and German languages too, to help you see things working in action.
Next steps?
The next step to take from here would be for the page to remember your chosen language. That can be done by storing the chosen language as a cookie value, so that other pages on the site can automatically retrieve that chosen language. But that can be for later on once the basic setup is in place.