I want to support translations between e.g. different versions of English, but have a common fallback.
The following is an example of how the setup could be:
locales/en_AU.json
locales/en_US.json
locales/en.json
locales/fr_BE.json
locales/fr_FR.json
locales/fr.json
...
I want to have e.g. some Australian specific strings in en_AU.json, but have the rest in en.json.
In code I would like something like:
$translateProvider.fallbackLanguage(['en_*' : 'en', 'fr_*' : 'fr'])
Or to generally attempt to fallback to whatever is before the underscore.
I would also like to have a general fallback language
Is there a way to accomplish this?
I ended up listening for language changes, and if the new language key contained an underscore (eg. da_DK), I changed the fallback stack to be ['da','en'] and the called refresh.
$translate.use(languageKey);
// Check if language has a country code and add general language as fallback along with English
if (languageKey.indexOf('_') !== -1) {
$translate.fallbackLanguage([languageKey.substring(0,languageKey.indexOf('_')), 'en']);
}
$translate.refresh();
I'm using partial loaders and it didn't work for me initially. It loaded the language I changed to OK, but not the extra fallback language. The last $translate.refresh() was important
Related
In android, I am able to retrieve the language information from the language code itself using Locale class as shown below.
Locale locale = new Locale("fr");
locale.getDisplayName(locale); // Français
locale.getDisplayName(Locale.ENGLISH)); // French
I need the above information to be retrieved in angularjs from the language code alone. Is it possible to retrieve in HTML directly ?
A little late on this one, though there is a native API for this, window.Navigator.language.
For example:
console.log(window.Navigator.language); // 'en-US'
I am creating a website using CakePHP that requires translation not only into multiple languages but also multiple phrases per language depending on the type of the logged in user. This will allow the same functionality but with more formal or more friendly language without duplication.
As a very simple example:
Type 1: "Customer", "purchase","shopping cart"
Type 2: "Client", "buy", "basket"
Type 3: "User", "order","invoice"
Each of these types would be available in multiple languages.
I've got the standard localization working in CakePHP (one of the reasons I chose it!) and have the appropriate default.po files in the /Locale/[lang]/LC_MESSAGES/ directory and all is working fine there (thank you to the user who noted on this site that ger needed to be deu to work ;) ).
Before I get too far into the app I'd like to add the phrasing so I can set e.g. the language as French and phrasing as type2. If I was doing this outside of a framework I'd have a matrix look-up to find the correct string based on language and phrase keys but am unsure of how to do this within CakePHP's localization.
Currently I'm using the standard __([string]) convention but as this is early in the development cycle it would be trivial to change if necessary.
I was considering using __d([phrase],[string]) but can't see how to set this without creating my app as a plugin and then I'm back to the same problem with /Locale/
I have been unable to find any example of this in my searches on SO or the cakePHP community sites so would be grateful for any suggestions.
Is there a standard way to do this within cakePHP? if not, what would be a good "best practice" way to implement this?
Edit - following the answer below here's how it was implemented:
in /app/Locale/[lang]/LC_MESSAGES/ I created a new .po files with the new phrasing in them as phrase1.po, phrase2.po etc.
Where I set the language I also set the phrasing where the phrase file matches the name of the po file:
Configure::write('Config.language', 'deu');
Configure::write('App.langDomain', 'phrase1');
and all strings were wrapped with:
__d(Configure::read('App.langDomain', 'string')
And it just works.
Use __d() like this:
__d(Configure::read('App.langDomain'), 'Some string');
In bootstrap.php check the conditions and set App.langDomain based on whatever you need.
__d() has nothing to do with plugins, you can use it everywhere.
And alternative would be to wrap your translations with a custom method, something like
__dd(Configure::read('App.langDomain'), array('foo' => __('String1', 'bar' => __('String2'));
The array is an array of langDomain => stringForThatDomain mappings. Your __dd() method would take the one that is passed in the first argument.
I am developing an application in cakephp 2.3.4, Which is multi-language.
Admin can add any number of new languages.
My question is, When admin decides to add a new language, how resulting locale name should be defined.
Can a locale name be any arbitrary name, given by admin or it should be a dropdown containg all languages code according to language.
Unfortunately, your question is a bit 'vague', i.e., will administrators be able to add GNU-locale files (*.po), or are you talking about adding translations inside the database.
In any case, CakePHP uses locales according to the ISO 639-3 standard see here and here for more information. A complete list of those locales can be found inside the I10n class.
Since you probably also want to switch the locale of PHP itself when switching locales, so that, for example, date, money and time-formats will follow the right format for the locale, it's best to stick with those locales and not 'invent' your own locales.
See setlocale(). Be aware though, that PHP may use slightly different locale-codes than CakePHP uses. And it will depend on what locales are installed on your server.
To get a list of locales installed on your server, use locale -a on the command line. See this page for more information: https://wiki.archlinux.org/index.php/Locale
Which techniques to use for localization
A quick summary of techniques to use;
Short messages (interface/UI)
In general, locale files are used for short pieces of text. Locale-files are therefore mostly used for fixed strings,
for example, strings that are used in the interface (like 'are you sure you want to delete this file?' => 'weet u zeker dat u dit bestand wilt verwijderen?).
Longer (fixed) text
For longer pieces of text in your application, that are not part of the 'content' (not the blog-post, but for example a fixed page with a disclaimer),
it's best to use separate views for translated content, for example;
app/Views/MyController/disclaimer_eng.ctp
app/Views/MyController/disclaimer_deu.ctp
app/Views/MyController/disclaimer_fre.ctp
Content
For the content of your website (the part of your website that is managed by the 'user' of the website),
put translations inside the database. This data may be updated frequently and all translations should be updated as well.
How to implement this, is really up to you and depends on your situation. CakePHP offers a Translate behavior that you can use (http://book.cakephp.org/2.0/en/core-libraries/behaviors/translate.html), but in most of my situations that behavior didn't really fit our needs (IMO it is not very efficient, because it stores translations per-field, per-model).
I'm having troubles with the CakePHP's (2.3) CacheHelper.
This is realy a powerful tool, but it's not so suitable for what I'm doing.
I have a internationalised website and the language is set either by the user's preferences or by "forcing" it with an URL argument (lang:xx).
So, the cached page "controller/action/yy" can be the same page as "controller/action/yy/lang:xx". And worst, "controller/action/yy" can be cached in english, french or whatever.
Is there a way to change the name (the prefix is clearly not a solution here) of the cached file (so that "controller/action/yy" will always be cached as "controller/action/yy/lang:xx" by adding the user's preferences language) ?
Thanks in advance !
Sébastien
You can in your beforeRender change the prefix of the file:
Configure::write('Cache.viewPrefix', 'YOURPREFIX');
And you can get your prefix from params or session (depends of your app).
I didn't get why prefix is not useful. You will have one file for each language for each page. Something like "eng_my_action" file.
If you want to save only 1 file and translate it with the user language makes non sense. Because view already do that (only a parser of the data).
Fonts:
http://book.cakephp.org/2.0/en/core-libraries/helpers/cache.html#using-the-helper (looking for new in version 2.3)
Well,
I will sample the awnser to you understand:
public function beforeRender(){
$lang = isset($this->params["named"]["lang"]) ? $this->params["named"]["lang"] : "eng"; // verify if is the default language(eng) or is in params
if($this->Auth->user("lang")){
$lang = $this->Auth->user("lang"); // This is a example how to take the default language from a user. You need to change it to your app.
}
Configure::write('Cache.viewPrefix', $lang);
}
I have created a site with multiple languages in sitecore... I the content editor (system > languages) I have specified three languages (Dutch, English and German). No I have 2 problems.
When an item has, for example: an English version but no German and Dutch version and I type the address to the German site: www.testsite.com/de I get the German site, but without content. In this case I want a 404 page to be shown.
Another problem is when I go to language that is not specified in system > language and also on the item is still get an empty site. In this case I also want a 404 page to be shown. Sitecore shows the page as long as it is a valid ISO-code.
I'm using Sitecore 6.4
Does anybody has a solution for these problem(s)?
Thanks in advance!
mrtentje
My LinkManager is specified as follows in the Web.config:
<add name="sitecore" type="Sitecore.Links.LinkProvider, Sitecore.Kernel" addAspxExtension="true" alwaysIncludeServerUrl="false" encodeNames="true" languageEmbedding="asNeeded" languageLocation="filePath" shortenUrls="true" useDisplayName="false"/>
Unfortunately you have to manage both of these scenarios manually in Sitecore, they both have quite simple solutions but will require some development on your part.
For the first (accessing of pages without translations) I think you would need to extend the current ItemResolver within Sitecore and have it explicitly check that a version exists for the language that has been selected. I haven't implemented that myself but that's how I'd look at handling it.
The second (only accepting certain languages) is something I have handled, and it really bothered me that Sitecore couldn't handle it itself (though perhaps it does and I missed it). For this I created a step in the pipeline immediately after the LanguageResolver called PermissableLanguageChecker. This checks to see if the current language of the request is one of certain allowable values, and if it isn't it sets the language back to the default language, or in your case throw a 404.
For the "allowable values", I read them from the site config with a new property there:
<site name="website" ... permissableLanguages="pl-PL,en" language="pl-PL" ... />
That permissableLanguages property is handy as we can also use it later on in the site when presenting a language selection control to the user.
You may want to take a look at the Language Fallback module in the Sitecore Shared Source Library. As it covers some of your scenarios.
http://trac.sitecore.net/LanguageFallback