It used to be only mad dog and Englishmen who went out in the midday sun but now, according to that secret roomful of scientists who produce ridiculous research, everyone should nip out for a varying period of time, round about midday, for some much needed vitamin D production:
Banish your midday blues
It’s not as simple as downing keyboards and rushing out for 15 minutes each day. You have to make sure it’s exactly midday, as apparently the amount of vitamin D produced is a function of the height of the Sun!
The duration of exposure is also proportional to your latitutde. For example, if you live in Athens, you need only laze outside for 6.5 minutes. If you live in Edinburgh, you need to bare all for almost twice that time, 11 mins.
It doesn’t mention Skye, where you’d probably get hypothermia and/or eaten by midges long before your vitamin D indicator reached full.
So why do we need our vitamin D levels boosted? Is it because we sit at a keyboard all day? Perhaps not. There’s a general movement away from outdoor pursuits, in favour of nice, warm, UVB protected activities, such as indoor climbing walls. Indeed, the latest development in the bagging game is Bing Bagging, where you bag old shale bings in Central Scotland. This isn’t new, as I have an old friend to whom we refer to as the “Bing King”.
What next? Will an enterprising individual catch on to this new phenomenon and buy up bings and put a roof over them. http://ratho.ezoneinteractive.net/category_home/climb2.html
This pattern decribes a way to implement cross domain cookies, which are at the heart of the Shibboleth Cookie Monster (as I call it)
This Sun site contains an interesting chronological history of Liberty Alliance. Seems to stop at 2003 though
I’m building in some form of AA authentication on the Guanxi IdP and I’ve started to get Shibboleth SP errors:
session_is_valid preFetch populate getNewResponse send: caught SAML exception during SAML attribute query: SAMLSOAPBinding::send() failed while contacting SAML responder: SSL read error: 1
I’ve traced it to this line in the IdP:
X509Certificate[] x509Certs = (X509Certificate[])request.getAttribute(“org.apache.coyote.request.X509Certificate”);
The Servlet spec says you should be able to get at the client certs using:
request.getAttribute(“javax.servlet.request.X509Certificate”)
but this just returns null. It doesn’t cause the SP to barf though. Accessing “org.apache.coyote.request.X509Certificate” does.
Bodington templates are composed of 3 main types of localisable content:
Type 1 – Raw content:
<p>Instructions for eating cakes</p>
Type 2 – Input elements:
<input type=”submit” name=”ok_to_proceed” value=”OK” />
Type 3 – String literals in Facility calls:
<literal type=”String”>Enter Web Site</literal>
Localisation overview
All the localised strings for Bodington are stored in the file WEB-INF/lib/res.jar. If you’re building from source, you can find the strings under the res directory at the root of the source distribution. The res directory contains generic system-wide resources as well as template specific resources. If you add new templates you should follow these guidelines for adding new localised content to the res directory:
If you have content that could be used by other entities in the system, you should put them in a Properties file under res/generic.
Your new template’s localised strings should go under res/templates/NEW_TEMPLATE_NAME_LANGCODE.properties
We’ll step through the creation and localisation of a new template, cakes.html. The new template is shown below. It contains all 3 types of localisable elements and the content requiring translation is in bold:
Unlocalised template
<template facilityclass=”org.bodington.servlet.facilities.Facility”>
<html>
<head>
<!– Type 1 – raw content –>
<title>People should eat more cakes!</title>
</head>
<body>
<!– Type 1 – raw content –>
<p>People are not eating enough cakes</p>
<form name=”eat_more_cakes” method=”POST” action=”">
<!– Type 2 – input elements –>
<input type=”submit” name=”submit” value=”I agree” />
<input type=”submit” name=”submit” value=”Cancel” />
</form>
<h2>
<call>
<target method=”loginOriginalLink”><variable name=”facility”/></target>
<parameters>
<variable name=”request”/>
<variable name=”writer”/>
<!– Type 3 – Facility string literal –>
<literal type=”String”>The system has eaten some cakes on your behalf</literal>
</parameters>
</call>
</h2>
</body>
</html>
</template>
Creating the localised text files
Now that we’ve created the new template, we’ll create new resource files for it. These resource files will hold the translated strings for the new template. The format of the files is quite simple, consisting of a set of key/value pairs:
key1=value1
key2=value2
We’ll create a separate file for each language for which we have translations, which in this case means two, English and Gaelic.
In general, it’s a good idea to put all the localised files for a template under a directory of the same name as the template, under the res/templates directory in Bodington.
Create a new directory:
res/templates/cakes
Create two new files:
res/templates/cakes/strings_en.properties – to store the English strings
res/templates/cakes/strings_gd.properties – to store the Gaelic strings
The filenames must always end in .properties as this is what the localisation system uses to find translated content.
The _en and _gd postfix on the files denote the language that the file represents. The two letter language codes are defined by the ISO 639 standard. At the moment it’s not possible to specify the language variant using ISO 3166 but it’s coming.
As you can see from the bold items in the template, there are 5 strings that need to be localised. 4 that are specific to the template and the last one, which is quite useful and could be used by other templates. So, we split our content between our template’s resource files and system-wide generic files.
Template specific content
res/templates/cakes/strings_en.properties:
page.title=People should eat more cakes!
page.explanation=People are not eating enough cakes
page.message=The system has eaten some cakes on your behalf
button.agree=I agree
res/templates/cakes/strings_gd.properties:
page.title=Bu choir do dhuine tuilleadh c?®icean ithe!
page.explanation=Chan eil duine ag ithe c?®icean gu-le??r
page.message=Tha an t-siostem air ithe c?®icean ?†s ur leth
button.agree=Tha mi ag aontachadh
System-wide content
res/templates/generic/strings_en.properties:
button.cancel=Cancel
res/templates/generic/strings_gd.properties:
button.cancel=Dubh a-mach
Now that we have our translated content, we can now modify the template to make use of Bodington’s localisation system.
Setting up the template for localisation
We must add a “resources” attribute to the root <template> element:
<template facilityclass=”org.bodington.servlet.facilities.Facility” resources=”res.generic.strings,res.templates.cakes.strings”>
As you can see, templates can make use of multiple resource files. In this case, we’re loading the system-wide generic strings bundle as well as the template specific strings. In general, if you want to use multiple resource files for a template, you should specify them as a comma separated list. The Localiser will take care of which bundle the strings are in when you add localisation tags to the template, so you don’t have to remember where each string is.
The other point to note is you don’t add the _en, _gd or .properties parts of the resource filename. You just use the root filename, strings. The system takes care of loading the correct strings when you change the language in Bodington’s user options page.
Localising Type 1 – Raw content
This is done by a straight substitution of the text with a <localise> element, with an “id” attribute specifying the key in a resource file that we created:
<title>People should eat more cakes!</title>
<title><localise id=”page.title” /></title>
<p>People are not eating enough cakes</p>
<p><localise id=”page.explanation” /></p>
Localising Type 2 – Input elements
To localise the value attribute in <input> elements in a template, replace the text with the corresponding key from the resource file but prefix the key with localise. When the localisation system encounters localise. in front of text in a value attribute it will replace that text with it’s corresponding value in the resource file:
<input type=”submit” name=”submit” value=“I agree” />
<input type=”submit” name=”submit” value=“localise.button.agree” />
<input type=”submit” name=”submit” value=“Cancel” />
<input type=”submit” name=”submit” value=“localise.button.cancel” />
You’ll notice that localise.button.agree and localise.button.cancel are in two separate resoource files. The system will sort out which file each key is in, as we told it what files to load at the top of our template resources=”res.generic.strings,res.templates.cakes.strings”
Localising Type 3 – String literals in Facility calls
Facility calls such as this instruct Bodington to do internal things and then output the text in the <literal type=”String”> element. To localise the text in Facility calls, use the same procedure as for Type 1 – Raw content:
<literal type=”String”>The system has eaten some cakes on your behalf</literal>
<literal type=”String”><localise id=”page.message” /></literal>
That’s it. We’ve created a new template and localised it to English and Gaelic. The complete localised template is shown below.
Happy munching!
Localised template
<template facilityclass=”org.bodington.servlet.facilities.Facility” resources=”res.generic.strings,res.templates.cakes.strings”>
<html>
<head>
<!– Type 1 – raw content –>
<title><localise id=”page.title” /></title>
</head>
<body>
<!– Type 1 – raw content –>
<p><localise id=”page.explanation” /></p>
<form name=”eat_more_cakes” method=”POST” action=”">
<!– Type 2 – input elements –>
<input type=”submit” name=”submit” value=”localise.button.agree” />
<input type=”submit” name=”submit” value=”localise.button.cancel” />
</form>
<h2>
<call>
<target method=”loginOriginalLink”><variable name=”facility”/></target>
<parameters>
<variable name=”request”/>
<variable name=”writer”/>
<!– Type 3 – Facility string literal –>
<literal type=”String”><localise id=”page.message” /></literal>
</parameters>
</call>
</h2>
</body>
</html>
</template>
Finally removed bodington.properties from the language debug switching. Now use the Request object to pass the level about. This also means that it’s basically user specific now instead of system-wide.
The sysadmin can now turn on localisation debugging to see what’s causing any problems that another user might report, without other users of the system seeing the debug information in the strings.
I also took the opportunity to change the template’s resource attribute from “resource-file” to “resources” to reflect the new support for multiple resource files.
The following files were modified:
- org.bodington.servlet.BuildingServlet – modifed doProcessing() to put the language debug level in the Request
- org.bodington.servlet.template.XmlTemplate – modified compile(Document, File, String, String) to use the Request object when writing language debug level choosing code into the template. Also modified it to use the new “resources” template attribute
- templates/style_default/default/useroptions.html – modified to change “resource-file” attribute to “resources”
You can now specify multiple resource files for a template:
<template facilityclass=”org.bodington.servlet.facilities.Facility” resource-file=”res.generic.strings,res.templates.useroptions.strings”>
To use multiple resource files, specify the class names as a comma separated list. The Localiser will take care of matching keys with resources:
<localise id=”button.ok” /> – this comes out of the system-wide res.generic.strings bundle
<localise id=”page.title” /> – this comes out of the template specific bundle res.templates.useroptions
The following files were modified:
- org.bodington.servlet.facilities.Facility – modified displayLanguageSelectionList() to use res.generic.languages bundle to output a localised language selection list. Also added displayLanguageDebugLevelList(), controlled by res.generic.lang_debug_levels
- org.bodington.i18n.Localiser – modified to support multiple resource bundles
- templates/style_default/default/useroptions.html – added res.generic.strings to the list of resource files for the template. Added <call> to new displayLanguageDebugLevelList in Facility
The following files were added:
- res.generic.strings_en.properties – English version of system-wide strings
- res.generic.strings_gd.properties – Gaelic version of system-wide strings
- res.generic.languages_en.properties – English version of supported languages
- res.generic.languages_gd.properties – Gaelic version of supported languages
- res.generic.lang_debug_levels_en.properties – English version of support language debug levels
- res.generic.lang_debug_levels_gd.properties – Gaelic version of support language debug levels
The two methods in Facility, displayLanguageSelectionList() and displayLanguageDebugLevelList() show how to localise content coming out of this class
Buttons can now be localised via their “value” attribute. The system works thus. If the text in “value” is prefixed by “localise.” then the i18n system will substitute the remainder of the text with it’s value from the current resource file(s):
<input type=”submit” name=”ok_to_proceed” value=”localise.button.ok” />
“localise.button.ok” will be replaced by the localised string identified by “button.ok”
<input type=”hidden” name=”mode” value=”secret_mode” />
the value above won’t be touched by the i18n system as it’s not marked as such by prefixing with “localise.”
The following files were modified:
- org.bodington.servlet.template.XmlTemplate – added compileInputCall() and a hook to catch <input> elements
- templates/style_default/default/useroptions.html – localised the buttons
Due to the i18n intialisation being in the <1i8n> node, all the setup was done in process(), which wasn’t very efficient. So, I’ve now binned the node and all i18n info is specified on the root <template> node:
<template facilityclass=”org.bodington.servlet.facilities.Facility” resource-file=”res.templates.useroptions.strings”>
The following files were modifed:
- org.bodington.servlet.template.XmlTemplate – removed compileI18NConfig() and moved all the i18n initialisation to compile( Document, File, String, String)
- templates/style_default/default/useroptions.html - removed the <1i8n> node and added the resource info to the root <template> node
The main change is moving from Properties files to ResourceBundle. This means that the resource files must be in the CLASSPATH. To facilitate that, a new res directory has been created, which the build should copy to WEB-INF/classes.
The structure of the res directory is:
res/templates/[TEMPLATE_NAME]/[RESOURCE_FILE_NAME]_Locale.properties
Locale is determined from the User’s preferred language.
Modified the following files:
- org.bodington.servlet.template.XmlTemplate – modified compileI18NConfig() to remove file paths and use the class name for the ResourceBundle instead
- org.bodington.i18n.Localiser – Changed to use ResourceBundle
- templates/style_default/default/useroptions.html – changed to use class name of ResourceBundle in “resource-file” attribute. Removed the “resource-path” attribute
Added the following files:
- res/templates/useroptions/strings_en.properties – English translation for useroptions.html
- res/templates/useroptions/strings_gd.properties – Gaelic translation for useroptions.html