I have developed a rough method, including some basic code, for including multiple languages in the CMS. Its currently part-module, part-plugin, and partly involves some changes to the core - and as such I may well submit it for inclusion in either the existing Evolution and/or this project
http://forums.modx.com/thread/?thread=74766.
It adds to, rather than changes, the existing db structure. This is a must, otherwise we break all old sites.
The key feature is that I have used views - currently only tested in MySQL. If we want to include as an example, French translations, we have a modx_site_content_fr view i.e. which aside from the suffix to the name mimics the existing modx_site_content. Suffixes are all ISO639 two letter codes.
To make this work invisibly to existing code, I have changed $modx->getFullTablename to take into account the session's language. If the language is, for example, set to French, then for the 'site_content' table it will return modx_site_content_fr instead of modx_site_content.
Any existing code that bypasses $modx->getFullTablename will receive translations from the primary or default language as a fallback. However I anticipate that most existing code - core and extras - will work fully without any changes.
Extra languages can be added in the back end via a module, which alters the db by adding extra columns to modx_site_content and modx_tmplvar_contentvalues. The extra columns have ISO639 suffixes e.g. pagetitle_fr. The primary or default language has no suffix for backwards compatability. This however is 'under the hood' and can be ignored by existing code.
So far I have code for:
a) A 'Create Language' module, which gives the facility to add or remove languages, and takes care of the db changes required.
b) A 'Select Language' plugin for the manager, which changes the current language (in both back and front end).
c) A new $modx->getFullTablename:
// (TimGS)
function getFullTableName($tbl, $lang = null) {
if (is_null($lang) && ($tbl == 'site_content' || $tbl == 'site_tmplvar_contentvalues')) {
$lang = $_SESSION['language'];
}
if ($lang == $modx->config['manager_lang_attribute']) { // Primary language -> uses standard text fields
$lang = null;
}
return $this->db->config['dbase'] . ".`" . $this->db->config['table_prefix'] . $tbl . ($lang ? '_' . $lang : '') . "`";
}
(d) Caching of documents requires three changes:
(1) In document.parser.class.inc.php, change checkCache:
function checkCache($id) {
// $cacheFile= "assets/cache/docid_" . $id . ".pageCache.php";
// Changed by TimGS for translations
$cacheFile= "assets/cache/docid_" . $id . ($_SESSION['language'] ? '_'.$_SESSION['language'] : '') . ".pageCache.php";
(2) In document.parser.class.inc.php, change postProcess:
function postProcess() {
// if the current document was generated, cache it!
if ($this->documentGenerated == 1 && $this->documentObject['cacheable'] == 1 && $this->documentObject['type'] == 'document' && $this->documentObject['published'] == 1) {
$basepath= $this->config["base_path"] . "assets/cache";
// invoke OnBeforeSaveWebPageCache event
$this->invokeEvent("OnBeforeSaveWebPageCache");
// if ($fp= @ fopen($basepath . "/docid_" . $this->documentIdentifier . ".pageCache.php", "w")) {
// Changed by TimGS for translations
if ($fp= @ fopen($basepath . "/docid_" . $this->documentIdentifier . ($_SESSION['language'] ? '_'.$_SESSION['language'] : '') . ".pageCache.php", "w")) {
(3) In document_data.static.php, line 327
$filename = $modx->config['base_path']."assets/cache/docid_".$id. ($_SESSION['language'] ? '_'.$_SESSION['language'] : '') . ".pageCache.php";
I have not yet produced any frontend code to switch languages. However at this stage, for testing, if you are logged on to the backend you can use the select language plugin which changes the language for both back and front ends together.
This system could be extended to include versioning, but this would need more manager alterations. We would have views such as modx_site_content-fr and modx_site_content-fr-draft.
Please note that this is very much a work in progress. Do not use on any sites where you value the data! The module alters the db structure, and any bugs could have major consequences. Also note that it is as yet a rather crude UI, without even a confirm dialog box for deleting a language.
Attached are:
- A module for creating languages
- A plugin for OnManagerPageInit to change languages
- A sample partial db dump for a site with one page, three languages. It only includes the content and template tables so you will need to import it into an existing fresh install.
File attachments updated 6 May 2012, 22.32 GMT.
[ed. note: TimGS last edited this post 11 years, 11 months ago.]