Another Moodle activity that I've been tasked with is: 'ensure that different users are presented with user interfaces that match their language choices'.
I understand that software localisation (or internationalisation) is an industry in its own right, replete with its own tools and practices. When you scratch the surface of the subject you're immediately presented with different character sets, fonts and issues of text direction (whether text flows from left to right or visa versa).
My question is: how is Moodle localised into different languages, and does it use any approaches that could be considered to be common between other systems?
This post will only scratch the surface of what is an interesting (and often rather challenging) subject. For example, what is the Moodle approach to dealing with plurals, for example? There's also the issue of how internet browsers send their localised settings to web servers and application engines... Before I've even started with this post, I'm heading off topic!
Let's begin by considering three different perspectives: the students perspective, maintainers perspective and the developers perspective.
A student shouldn't really need to concern themselves with their locale settings, since the institution in which they are enrolled are likely use a sensible default setting. But if students wish to change the LMS interface language (and providing your particular Moodle installation permits the changing of user preferences), a student user could click on their name hyperlink that they see after logging on and click on an 'Edit Profile' tab and search for the 'preferred language' drop down box.
In my test installation, I initially had only one language installed: English (en). In essence, my students are not presented with a choice. I might, at some point during my project need to offer 'student users' a choice of four different languages: German, Italian, Greek and Spanish. Obviously something needs to be done, leading us swiftly to the next perspective.
I log out from my test student account and log back in as an administrator and discover something called a 'Language' menu, under which I discover a veritable treasure trove of options.
The first is entitled 'Language Settings'. This allows an administrator to choose the default language for a whole installation and also to do other things such as limit the choice of languages that users can choose.
The second menu option is entitled 'Language Editing'. It appears that this option allows you to edit the words and phrases (or strings) that appear on the screen of your interface. The link between a 'bit on a screen' and a language specific description is achieved by an identifier, or a 'placeholder' that indicates that 'this piece of text should go here'.
What is interesting is that individual strings are held within Moodle programming files. This makes me wonder whether the action of editing the strings causes some internal programming code to change. This process is mysterious, but interesting.
As a useful aside (which relates to an earlier project related post), I click on 'resource.php' to see what identifiers (and text translations) I can find. I see loads of resource types, including names for resource types, which are numbered. Clearly, when adding new functionality, a developer needs to understand how software localisation occurs.
Continuing my user perspective exploration (after being a little confused as to what 'new file created' means after choosing to view the 'resource.php' translation page), I click on the 'Language Packs' option. Here I am presented with a screen that tells me about what language packs I have installed. By default, I only have a single language pack: English (EN). Underneath, I see a huge list of other language packs, along with a corresponding 'download' link. Apparently, because of a problem connecting to the main Moodle site (presumably because one of my development machines is kindly shielded from world from different nasties), things won't install automatically and have to save (unzipped) language packs to a directory called 'moodledata/lang'.
Let's see what happens by downloading and unzipping the language packs I need.
After unzipping the language packs, I hit my browser 'refresh' button. As if my magic, Moodle notices the presence of the new packs and presents you with a neat summary of you have installed.
So, how does this magic work, and what does a developer have to know about localisation in Moodle?
One place to start is by exploring the anatomy of a downloaded language pack by asking the questions: 'what does it contain, and how is it structured?' Out of all the four packs that I have downloaded the German pack looks by far the most interesting in terms of its file size. So, what does it contain?
The immediate answer is simply: files and directories. In the German pack I see three folders: doc, help and fonts. The doc and fonts folder do not contain very much, mostly readme files, whereas the help folder in turn contains a whole load of subfolders. These subfolders contain what appears to be files containing fragments of HTML that are read using PHP code and presented to the user. At this point I can only assume that Moodle reads different help files (and presents different content to the user) depending upon the language that a user has selected.
At the root of a resource pack I see loads of PHP files. Some of these have similar file names, i.e. some begin with quiz, and presumably correspond to the quiz functionality, and others begin with repository, enrol and so on (my programmer sense is twitching, wondering whether this is the most efficient way to do things!)
A sample of a couple of these PHP files shows that they are simply definitions of localised strings which are stored in an associative array, which is indexed by a name. Translated into 'human speak', there's a fixed 'programming world' name which is linked to a 'language world' equivalent. You might ask the question of why do 'language localisation' this way? The answer is: to avoid having to make many different versions of the same Moodle programming code, which would be more than a nightmare to maintain and keep track of.
A number of questions crawl out of the woodwork. The main one being, 'how are the contents of these resource packs used when Moodle is running?', but there is the earlier question of 'what happens when you make a change to a translation?' that needs to be answered. Both are related.
Moodle has two areas where localisation records are stored. The first can be described as a 'master' area. This is held within the 'programming code' area of Moodle within a directory unsurprisingly named 'lang'. This contains files which contains identifiers and strings for the default language, which is English. The second area is a directory, also called 'lang', which can be found within the Moodledata directory area. Moodledata is a file area that can be modified by the PHP software engine (the software that Moodle itself is written in). Moodledata can store course materials and other data that is easier to store using 'file storage' area as opposed to using the main Moodle database.
As mentioned earlier, language packs are stored to the Moodledata area. If a user chooses to edit a set of localised strings, a new version of the edited 'string set' is written as a new file to a directory that ends with '_local'. In essence, three different language resources can exist: the 'master' language held within the programming area, the installed 'language pack', and any changes made to the edited language pack.
During earlier development work, I created a new resource category called an 'adaptable resource'. After installing the German resource pack, using the 'master language pack', Moodle can tell you whether there are some translations that are missing.
After making the changes, the newly translated words are written to a file. This file takes the form of a set of identifier definitions which are then read by the Moodle PHP engine. Effectively, Moodle writes its own programming script.
Using this framework, developers shouldn't have to worry too much about how to 'localise' parts of their systems, but before stating that I understand how 'localisation' works, there's one ore question to ask.
How does Moodle choose which string to use?
When viewing a course you might see a the 'topic outline' headline. How does Moodle make a choice about which language pack to use? I begin my search by looking through the code that appears to present the course page, 'course/view.php'. There isn't anything in there that can directly help me, so I look further, stumbling upon a file within a 'topics' sub-directory called 'format.php'.
In the format file I discover a function called get_string, which references an identifier called 'topicoutline'. This is consistent with the documentation that I uncovered earlier. The get_string function is the magic function that makes the choice about where your labels come from.
Get_string is contained within a file called 'moodlelib.php' which is, perhaps unsurprisingly, contained within a directory called 'lib'. Moodlelib is a huge file, weighing in at about eight thousand lines. It is described as (in the comments) as a file that contains ‘miscellaneous general-purpose Moodle functions’.
Get_string is a big function. One of the first things it does is figure out what language is currently set by looking at different variables. It then creates a list of places to look where localised strings can be found. The list begins with the location of where language packs are installed to, followed by areas within the Moodle codebase that are installed by default. It then checks to see if any ‘local’ (or edited) versions of the strings that have been created (as a result of user editing the language packs). When the function knows which file the strings are held in, Moodle reads (includes) the file and caches the contents of the 'string file' into a static variable (so Moodle doesn’t have to read the file every time it needs to fetch a string) and returns the matching localised string.
In the middle of this function there is extra magic to present sensible error messages if no strings are found, and other code to help with backwards compatibility with earlier versions of Moodle. It also seems to check for something called 'parent languages', but I've steer clear of this part of the code.
Testing language installation
Has all my messing around the languages worked? Can I now assign different users different languages? (Also, can users choose their own language preferences?) There is only one way to find out. Acting as an administrator I created a new user and set the users default language to Italian. I logged out and logged in using the new user account.
It seems to work!
The one thing that I have not really explored is whether Moodle will automatically detect the language a user has configured on their internet browser. A little poking around, indicates that Moodle can indeed be clever and change its language dynamically by using the hidden 'language' information that is sent to a web server whenever a HTTP request is made.
The 'dynamic language adaptation' functionality is turned on by default, and a switch to turn it on and off can be found within the 'language settings' menu that the administrator can use.
The fact that Moodle can dynamically change in response to browser (and potentially operating system) settings is interesting. One of the things that the EU4ALL project is exploring is whether it might be possible to tell web-based systems whether certain categories of assistive technology are being used. This may open up the possibility of user interfaces that are more directly customised to users individual needs and preferences.
I've described (rather roughly) how Moodle takes care of software localisation, but how is it handled in other programming languages. I've used Java and the .NET framework in the past, and each system provides its own way to facilitate localisation.
Java makes use of something called a resource bundle (Sun Microsystems). dotNET, on the other hand, uses something called resource files (Code Project). One question remains: is there a generally recommended approach for PHP, the language on which PHP is based? Like with so many different things in software, there is more than one way to get the same result.
The author of the PHP Cookbook describes another way to think about localisation. This approach differs in the sense that it focuses more on demonstrating localisation by using object-orientation (an approach that Moodle has historically tried to steer away from, but this seems to be changing), and doesn't really address how a user might be able to edit or change their own strings should they not like what they see.
Software localisation, like accessibility, is a subject that software developers and web designers need to be aware of. This rather long post has outlined how software localisation is broadly achieved in Moodle. Much, however, remains unsaid. Issues such as how plurals, right to left scripts and multi-character fonts have been carefully side stepped.
What is clear is that Moodle appears to have a solid infrastructure for localisation which seems to work, and provides site maintainers the ability to add different languages without too many headaches. Also, whilst browsing the documentation site I stumbled across a documentation page that hints at potential future localisation developments.
Although I have mentioned one other way to approach localisation within PHP it might be useful at some point to explore how comparable learning management systems tackle the same problem, perhaps also looking at how localisation is handled in other large projects.
Localisation will always be something that developers will need to address. Whenever new functionality is introduced, developers will obviously make provision to ensure that whatever is developed is understandable to others.