CakePHP 2: Localization&Internalization for function timeAgoInWords() - cakephp

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.

Related

CakePHP Localization of static data

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.

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.

Translation cakephp not working

I'm trying to implement a translation in Cakephp but isn't working and don't show me any erros.
I have this HTML in a element
<a href="/sites/pages/servicos" target="_blank">
<span class="title">Serviços</span>
<div class="description"><?php __('o que fazemos') ?></div>
</a>
In App Controller inside beforeFilter():
Configure::write('Config.language', 'eng');
In my folder locale/eng/LC_MESSAGES/default.po I have this:
msgid "o que fazemos"
msgstr "What we do"
But isn't working...
Thanks
I think you're just forgot "echo"
<?php echo __('o que fazemos'); ?>
Have you correctly generated the i18n files with the ./cake i18n command?
Use PoEdit to edit your translate files, instead of doing it by hand if you've done so.
http://poedit.net/
First of all, Did you generate the default.pot file by typing
app\console\cake followed by i18n extract after having the full file in _() format?
Second, why did you put the Configure::write('Config.language',
'eng'); in App Controller instead of app\Config\core.php
(recommendation).
And as +JazzCat said as it is a .po file it is highly recommended to use poedit.
PS: you can set the language in AppController using session:
$this->Session->write('Config.language', 'en');

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');

AppError 404 equivalent in cake 2.0

I've recently upgraded my 1.3 cake app to 2.0, and I'm trying to redo my app_error code.
With Cake 1.3, it was simply a case of creating an app_error.php file, putting it in my app root, and overriding the built-in error404() and missingController() actions.
Here is my old 1.3 /app/app_error.php file: http://pastebin.com/beWZD9PJ
It had some code that kicked in when someone arrived at the site with a predefined 'alias' URL, and then it redirected them accordingly.
I just need this to work in Cake2.0, and I see the manual is telling me its all changed, but I can't find a specific case like this. Can anyone help me out, so the error404 code kicks in?
Many thanks
4xx and 5xx errors in CakePHP 2.0 ar now exceptions, thus you need to customize your Exception renderer or handler. Read from this section to the bottom http://book.cakephp.org/2.0/en/development/exceptions.html#exception-renderer
You can throw a 404 exception with the following code in your controller in Cake 2:
throw new NotFoundException(__('Your error text here'));
Then, you just need to have APP/View/Errors/error400.ctp present with something relevant to display. Cake includes this by default:
<h2><?php echo $name; ?></h2>
<p class="error">
<strong><?php echo __d('cake', 'Error'); ?>: </strong>
<?php printf(
__d('cake', 'The requested address %s was not found on this server.'),
"<strong>'{$url}'</strong>"
); ?>
</p>
<?php
if (Configure::read('debug') > 0 ):
echo $this->element('exception_stack_trace');
endif;
?>
It's simple.
With cakephp 2, you have to add this function in your AppController:
public function appError($error) {
$this->redirect('/');
}
Here, for example we redirect all errors to index page.

Resources