CakePHP Localization of static data - cakephp

CakePHP Version: 3.6.6
I apologise in advance for such a long post but I believe this is all the information needed for someone to be able to help.
===========================================================================
SECTION 1
// WHAT I'D LIKE' TO ACHIEVE
Ultimately I'd like my application to automatically detect the language of the user and change the following accordingly:
Text.
Date format.
Number format.
Currency.
In an effort to realise this I started by simplifying it by not attempting to automatically detect the language of the user but manually changing the locale in config/app.php.
===========================================================================
SECTION 2
// THE INFORMATION I'VE REFERENCED
Internationalization & Localization - Here
I18N Shell - Here
===========================================================================
SECTION 3
// WHAT I HAVE BEFORE I START
config/app.php
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_GB'),
config/bootstrap.php
ini_set('intl.default_locale', Configure::read('App.defaultLocale'));
// Welcome controller
?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;
// For translation
use Cake\I18n\I18n;
use Cake\I18n\Time;
use Cake\I18n\Number;
class WelcomeController extends AppController
{
public function index()
{
// Get the default locale
$defaultLocale = I18n::getDefaultLocale();
echo $defaultLocale . '<br />';
// Date
$date = new Time('2017-12-05 23:00:00');
echo $date . '<br />';
// Number
echo Number::format(123.50) . '<br />';
// Currency
echo Number::currency(1250.00) . '<br /><br />';
}
}
// index.ctp
<?= __('Welcome') ?>
<br />
<?= __('What would you like to do today!') ?>
// This is what the browser displays
en_GB
05/12/2017, 23:00
123.5
£1,250.00
Welcome
What would you like to do today!
===========================================================================
SECTION 4
// WHAT I'VE DONE
1. Created a folder in src named Locale
2. Created a folder in Locale named de_DE
3. Navigated to the bin with the cli.
4. Typed cake i18n extract and clicked enter.
5. After clicking enter the following is displayed by the cli:
Current paths: None
What is the path you would like to extract?
[Q]uit [D]one
[C:xampp\htdocs\app_name\src] >
I then add the following after > and click enter
C:xampp\htdocs\app_name\src\Template\Welcome
6. After clicking enter the following is displayed by the cli:
Current paths: C:xampp\htdocs\app_name\src\Template\Welcome
What is the path you would like to extract?
[Q]uit [D]one
[D] >
7. I then click enter and the following is displayed by the cli:
Would you like to extract the messages from the CakePHP core? (y/n)
[n] >
8. I then click enter and the following is displayed by the cli:
What is the path you would like to output?
[Q]uit
[C:xampp\htdocs\app_name\src\Template\Welcome\Locale] >
I then add the following after > and click enter
C:xampp\htdocs\app_name\src\Locale
9. I then click enter and the following is displayed by the cli:
Would you like to merge all domain strings into the default.pot file? (y/n)
[n] >
10. I then click enter and the following is displayed by the cli:
Extracting...
Paths: C:xampp\htdocs\app_name\src\Template\Welcome
Output Directory: C:xampp\htdocs\app_name\src\Locale\
====================================================================> 100%
Done.
11. After this I have a default.pot file in the src/Locale folder. I copy and paste this file into the de_DE folder.
The contents of this folder are as below:
# LANGUAGE translation of CakePHP Application
# Copyright YEAR NAME <EMAIL#ADDRESS>
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"POT-Creation-Date: 2018-09-05 09:20+0000\n"
"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
"Last-Translator: NAME <EMAIL#ADDRESS>\n"
"Language-Team: LANGUAGE <EMAIL#ADDRESS>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
#: Template/Welcome/index.ctp:52
msgid "Welcome"
msgstr ""
#: Template/Welcome/index.ctp:58
msgid "What would you like to do today!"
msgstr ""
I then add the following into the 2 msgstr so they look like the below:
#: Template/Welcome/index.ctp:52
msgid "Welcome"
msgstr "abc"
#: Template/Welcome/index.ctp:58
msgid "What would you like to do today!"
msgstr "xyz"
I then change the default locale in config/app.php to:
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'de_DE'),
I then refresh the browser and the below is displayed:
de_DE
05.12.15, 23:00
123,5
1.250,00 €
Welcome
What would you like to do today!
===========================================================================
SECTION 5
// RESULT
The locale, date, number and currency have changed but NOT the text. It still displays:
Welcome
What would you like to do today!
And I was expecting it to display:
abc
xyz
===========================================================================
SECTION 6
// WHAT I'VE TRIED TO FIX IT
I added the below to the middleware - Application.php:
// Add middleware and set the valid locales
$middlewareQueue->add(new LocaleSelectorMiddleware(['en_GB', 'de_DE']));
And this is what the browser displayed:
de_DE
05/12/2015, 23:00
123.5
£1,250.00
Welcome
What would you like to do today!
The locale is still de_DE but the date, number and currency have reverted back to English?
===========================================================================
SECTION 7
// SUMMARY
I'd really appreciate any help on this because it would be brilliant if I could get my application localized and have the functionality of allowing a user to use my application in their native language. I'm really restricting my market if I can't get this working.
If there's anything else that I haven't written but you need please don't hesitate to let me know.
Many thanks in advance for any help. Z.
===========================================================================
#ndm - Thanks for the response, learnt a lot already but still no cigar.
I downloaded Poedit and opened it. I then clicked on "Edit a translation" and opened default.pot file from the Locale folder.
Everything looks good and the below is displayed:
Welcome
What would you like to do today!
I then click on 'Create new translation' and select German from the dropdown, the window is divided into 2 halves:
On the left - Source text - English.
On the right - Translation - German.
I highlight 'Welcome' and select the German equivalent 'Willkommen' which is then populated in the right window. I do the same for 'What would you like to do today'.
At this point the right window is populated with the German equivalents so I go to Save as and save the file in my de_DE folder in the src/Locale folder.
My de_DE folder is now populated with 2 files as detailed below:
de.mo
de.po
I open the de.po file and the contents are detailed below:
# LANGUAGE translation of CakePHP Application
# Copyright YEAR NAME <EMAIL#ADDRESS>
#
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"POT-Creation-Date: 2018-09-05 09:41+0000\n"
"PO-Revision-Date: 2018-09-05 14:26+0100\n"
"Language-Team: LANGUAGE <EMAIL#ADDRESS>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.1.1\n"
"Last-Translator: \n"
"Language: de\n"
#: Template/Welcome/index.ctp:52
msgid "Welcome"
msgstr "Willkommen"
#: Template/Welcome/index.ctp:58
msgid "What would you like to do today!"
msgstr "Was würden Sie heute gerne machen!"
I then clear the cache (tmp/cache/persistent) and refresh the browser.
To confirm I have the below in config/app.php
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'de_DE'),
And I have commented out the middleware reference.
Unfortunately the text has still not been translated?
It seemed like a relatively straight forward process so I'm surprised it hasn't worked. I'm hoping you can see something that I've done incorrectly in the process I've used as documented above.
Thanks again, Z.
// WHAT I'VE TRIED AS A FIX
1. I've tried changing the language definition in config/app.php from:
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'de_DE'),
to
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'de'),
then cleared the cache and refreshed but no luck.
2. I reversed the above then tried changing the language definition in the de.po file from:
"Language: de\n" to de_DE\n
then cleared the cache and refreshed but still no luck.

.pot files are templates (in PO format), you use them to create the final translation files in .po (plain) or .mo (binary) format from them (these are the files that CakePHP is looking for), or to update the latter with changed messages.
You can rename and edit the files manually, or use tools like Poedit that provide a GUI for the gettext tools which can help you with creating/updating .po/.mo files.
Whenever making changes to translation files, remember to clear the cache (tmp/cache/persistent) afterwards!

I know this is a bit late, but for anyone who stumbles across this tread.
Check the permissions of the src/Locale, src/Locale/de_DE and .po &.mo files.
I had a similar issue that the .po and .mo files I had generated were not readable by the web server user, and the translations of text failed silently, as appears to be the case in the OPs question.

Related

Cakephp 3 - Plugin - translation file - not working

Using Cake version 3.4.5 :
1) I've wrote a plugin :
/plugins/Accounting/
2) then, to create the pot file from the view files I run :
bin/cake i18n extract --plugin Accounting
3) this generates /plugins/Accounting/src/Locale/default.pot
But the translated text does not appear.
My locale is es_AR, and I've tried to copy the file as :
/plugins/Accounting/src/Locale/accounting.pot
or
/plugins/Accounting/src/Locale/es_AR/default.pot
or
/plugins/Accounting/src/Locale/es_AR/accounting.pot
Also tried to save the files as accounting.po, but nothing happens
But still not text is translated from the plugin views (it does work for the app's views).
I've found it !!!
The problem was the file / directory permissions.
By default, cake i18n extract --plugin MyPlugin makes this :
creates the src/Locale/ directory inside the plugin structure
creates the template translation file default.pot instead of
my_plugin.pot
all these creations are made with mode 750 being
the owner the linux user currently logged in ( not www-data )
So in order to make it work :
change the permissions of the Locale structure to 755
rename default.pot to my_plugin.po
use __d( 'my_plugin', 'Text to be translated' )

Cakephp 3 Localization issue

I'm using the localization feature to translate my app in French, but I'm running into some constraints I was not expecting.
In the default.po file, when I set:
msgid "MainLoginAccountLocked"
msgstr "Votre compte a été verrouillé."
It works fine. I can see the message translated.
But when I set:
msgid "Main Login Account Locked"
msgstr "Votre compte a été verrouillé."
It's not working. I get the "Main Login Account Locked" key instead of the translation.
Is there limitations in the msgid values? Or restricted values?
I've found nothing in the doc that could help me.
There are no limitations of having spaces in the msgid, I use it all the time.
#Nds's advice is pertinent: clear your cache.
In the past I also ran with problem on the compiles version of the .po file that needed to be regenerated.
Carefully verify the spaces at the end and beginning of the string.
Maybe also you should verify the encodings involved. If you are using UTF-8 everywhere (as I hope), it shouldn't be the issue.

Cakephp 2.4 isn't reading .po files

I created the following file :
/Locale/fra/LC_MESSAGES/default.po
Content:
msgid "delete"
msgstr "effacer"
I set the the default language to fra in core.php
Configure::write('Config.language', 'fra');
when i use
<h3><?php echo __("delete"); ?></h3>
the output should be "effacer" which isn't the case
I tried importing i18n class and setting i10n manually but the issue persist
App::import('I18n', 'i18n');
$I18n =& I18n::getInstance();
$I18n->l10n->get($this->params['lang']);
When i check the persistent cache "myapp_cake_core_default_fra" i find an empty array
Set this language code with language parameter
Configure::write('Config.language','en_Us');

CakePHP 2: Localization&Internalization for function timeAgoInWords()

My problem is that I can not translate a date from English to Russian.
I followed this guides:
Internationalization & Localization CakePHP
I18N shell
I wrote in AppController.php this code:
function beforeFilter() {
parent::beforeFilter();
setlocale(LC_ALL, "ru_RU.utf8");
Configure::write('Config.language', 'rus');
CakeSession::write('Config.language', 'rus');
}
I added a folder "Locale\rus\LC_MESSAGES" and place inside the file default.po.
BTW i extracted all messages to the single file.
But in fact:
<?php echo $this->Time->timeAgoInWords($feedback['Feedback']['created']); ?>
Did nothing.
<?php echo __d('default', $this->Time->timeAgoInWords($feedback['Feedback']['created']), true); ?>
Translates only string 'just now' to russian language, but other time formats still in English.
Examples of translates from default.po you can see below:
success
#: Lib\Cake\Utility\CakeTime.php:842
#: Utility\CakeTime.php:842
msgid "just now"
msgstr "translate"
fail
#: Lib\Cake\Utility\CakeTime.php:829
#: Utility\CakeTime.php:829
msgid "%d week"
msgid_plural "%d weeks"
msgstr[0] "%d translate"
msgstr[1] "%d translate"
I can't understand what i'm doing wrong.
For translating CakePHP core strings like those in Lib\Cake\Utility folder you need to use a different translation domain. The default domain for your views would be 'default' but for CakePHP core strings it is 'cake'.
Instead of 'default.po' you need to provide 'cake.po'. Otherwise your translations will have no effect.

relative URLs in cakePHP

I am using cakePHP 1.26 and TinyMCE v3.38.
The .js file of the TinyMSC is stored under this directory:
http://www.mysite/js/tiny_mce/tiny_mce.js
In the page where the users can post new topic,
the URL of this page is like this:
http://www.mysite/user/newpost
Now I need to add the javascript to this page, and I have tried these:
echo $javascript->link('/js/tiny_mce/tiny_mce.js');
echo $javascript->link('js/tiny_mce/tiny_mce.js');
echo $javascript->link('../js/tiny_mce/tiny_mce.js');
But the tiny_mce.js can not be reached.
I believe that Cake already knows that your javascript is in /js/ through using the $javascript->link() structure in the first place - so try
echo $javascript->link('tiny_mce/tiny_mce.js');
and see if you get anywhere.

Resources