I have this form in CakePHP:
echo $form->input('name', array('label' => $j['contact_name']));
echo $form->input('email', array('class' => 'disabled', 'label' => $j['contact_mail']));
echo $form->end(__('Submit', true));
I have two different languages, so I want to change name into name, but when I do that it doesn't work. Anybody help me how will this work in CakePHP.
Thanks!
You'll have to use the 'Localization' features of CakePHP
http://book.cakephp.org/2.0/en/core-libraries/internationalization-and-localization.html
Basically, any string that should be translated in the current language, should be echoed via the __() method, for example echo __('hello')
The string 'hello' in this example is the string to be localised (translated). CakePHP uses GNU locale files to define your translations. In these files are 'pairs' of strings, called msgid (the string/message to be translated) and msgstr (the translated string). Each language ('locale') has its own translation file, located in:
app/Locale/[locale]/LC_MESSAGES/default.po
For example, to have a 'Dutch' translation (locale 'nld'), this file:
app/Locale/nld/LC_MESSAGES/default.po
Should be created, containing:
msgid "hello"
msgstr "hallo"
Now, by switching the locale to 'nld' (for example in the beforeFilter() of your AppController;
Configure::write('Config.language', 'nld');
The 'nld' locale will be used and this line;
echo _('hello');
Will output:
hallo
In your case, setting the label would be something like this;
echo $this->Form->input('name', array('label' => __('hello')));
important
older versions (before CakePHP 2.x) 'echoed' the translated string in stead of returning the translated string. To return the translated string in CakePHP 1.x, you need to pass 'true' as second parameter; echo __('hello', true);
Strings in .po files are case sensitive, e.g. Hello !== hello
Locale files are meant for 'short', fixed text in your application, not to translate big pieces of text or 'dynamic' text, entered by the user. although it is possible to use it for these situations, it is not designed for this.
There are several other changes between CakePHP 2.x and 1.x, so in all cases, make yourself familiar with the whole concept by reading the manual.
Related
Some of the popular software libraries can help to generate forms (for data input) to some degree.
The form fields (or form types) can be constructed based on information which is provided also by an object-relational mapping.
I am looking for ways to achieve translated data displays for field labels and descriptions according to such a software combination.
I would appreciate your advices.
I don't know if you took a look into FormType Field Reference.
You can use that cofiguration:
// instead of 'label'
$profileFormBuilder->add('address', AddressType::class, [
'label_format' => 'form.address.%name%',
]);
$invoiceFormBuilder->add('invoice', AddressType::class, [
'label_format' => 'form.address.%name%',
]);
And Then, add the following code to your translations file:
form:
address:
address: Your Address # 'address' replaced %name%
invoice: Your Invoice Address # 'invoice' replaced %name%
Recently I updated CakePHP from 2.3.9 to 2.4.4. As far as I remember (I can't test now) Timehelper::timeAgoInWords was working well in old CakePHP. But after this update I get locale problem. I change language to English, but time ago still comes in Turkish.
In core.php i already set default language to Turkish:
Configure::write('Config.language', 'tur');
Inside my view file I use this:
$d = "2012-05-02 20:17:30"
$myString = $this->Time->timeAgoInWords($d, array('end' => '+10 year'));
I get result in Turkish like this:
1 yıl, 8 ay, 4 hafta önce
I want result like this:
1 year, 8 months, 4 weeks ago
My session variables like this:
[Config] => Array
(
[userAgent] => 35db889a82essb4e57b540d52e8a766d
[time] => 1391121684
[countdown] => 10
[language] => eng
)
Although I set my language as English, result cames in Turkish. How can I debug/fix this ?
Edit:
I checked for Configure-language values. Results like this:
echo Configure::read( 'Config.language' );
result: tur
But
echo $this->Session->read('Config.language');
result: eng
As I noted in the top of my question, I already setted Configure::language inside my core.php file. Does core.php overrides my session value ?
Edit2:
And strange thing is, although Config.language looks like both "tur" and "eng", other parts inside my view file works well. For example this works well:
__("string")
Edit3:
Regarding to this page: http://book.cakephp.org/2.0/en/core-libraries/internationalization-and-localization.html
I added this:
class AppController extends Controller {
public function beforeFilter() {
if ($this->Session->check('Config.language')) {
Configure::write('Config.language', $this->Session->read('Config.language'));
}
}
}
After this change config language results like this:
echo Configure::read( 'Config.language' );
result: eng
echo $this->Session->read('Config.language');
result: eng
But I still see timeAgo result in Turkish..
Last week I migrated to new server, maybe some setting is missing for English or etc ? I can't understand why timeAgo doesn't work while __("string") works.
Edit4:
I even changed core.php like this:
Configure::write('Config.language', 'eng');
setlocale( LC_TIME, 'en_US.utf8', 'eng', 'en', 'en_US', 'en_UK' );
It seems like, in my configuration nothing changes timeAgoInWords's language. I override in every beforeFilter to change Config.language is to english, but still words are Turkish. Note that in my php.ini timezone is like this:
date.timezone = Europe/Istanbul
Edit5:
It seems like there is a problem in the translations. I checked for source code of timeago, here is a copy: https://github.com/cakephp/cakephp/blob/2.4.4/lib/Cake/Utility/CakeTime.php#L738
It seems like this method uses __d and __dn so I checked the results in my code. "az önce" means "just now" in Turkish.
I'm sure that Config.language is "eng". So:
echo __d('cake', 'just now', 'just now'); // results: "az önce"
echo __('just now'); // results: "just now"
echo __('az önce'); // results: "az önce"
$days=12;
echo __dn('cake', '%d day', '%d days', $days, $days); // results: "12 gün"
echo __('gün'); // results: "days"
To debug echo Configure::read( 'Config.language' ); right before your timeAgo call. If you find it's not "eng" then you are setting the language to English after timeAgo was already called.
IF that does not work then you may have to call setlocale as well
I use this for english dates:
setlocale( LC_TIME, 'en_US.utf8', 'eng', 'en', 'en_US', 'en_UK' );
And I guess this would the call for Turkish
setlocale(LC_TIME, 'tr_TR.UTF-8', 'tr_TR', 'tr', 'turkish');
PS: Looking at the history of the TimeHelper nothing was changed to affect the locale, but may a dependency was changed.
Normally I change current language like this:
$this->Session->write('Config.language', $lang);
I set default language like this in every request in core.php:
Configure::write('Config.language', 'tur');
Regarding to CakePHP documents I must add this code to my AppController:
class AppController extends Controller {
public function beforeFilter() {
if ($this->Session->check('Config.language')) {
Configure::write('Config.language', $this->Session->read('Config.language'));
}
}
}
After adding the code above to beforeFilter() of AppController, I refreshed /tmp/cache/persistent/ folder and everything works fine.
Edit:
This solution worked well for english but it didn't work for other languages.
Why ? As noted in this question cake looks for cake.po files inside your Locale folder.
For example if you want to see cake's messages in french, so you need to create this file:
/app/Locale/fra/LC_MESSAGES/cake.po
Where do CakePHP use cake.po records ?
For example: this method
You can create default po files like this: i18n shell tutorial
After shell's file creation, you can edit cake.po file for your language.
For some languages cake.po files are ready. For example: french file
You can find rest from there: https://github.com/cakephp/localized
For Russian language it`s necessary to set cake.po file encoding to utf-8, or you will see blank options instead of translated month names.
My solution is:
1. Place file cake.po in \app\Locale\rus\LC_MESSAGES directory and set
2. in AppController file
public function beforeFilter()
{
Configure::write('Config.language', 'rus');
}
Translation file for your language you can find in files of CakePHP Localized plugin https://github.com/cakephp/localized
My Goal:
Reuse of a contact form to be related to several different entities I call "Parents" ie Group has contact information, Member has contact info etc....
The way I tried doing it was:
1. Creating a view file for contact, named "form.ctp" which doesn`t create a new form, nor submits, just echo's the contact's fields.
2. Calling this file using requestAction
My Problem:
The form's _Token get crumbled.
Parent add.ctp example
<?php echo $this->Form->create('Group');?>
<fieldset>
echo $this->Form->input($field_prefix.'contact_id',array('type'=>'hidden'));
<?php echo $this->requestAction(array('controller' => 'contacts', 'action' => 'form'), array('named' => array('index'=>'0','parent'=>'Group',
'fields'=>array(
'email'=>array('value'=>'xx#yy.com','hidden'=>1)
))));
inside the form.ctp I have:
//Associated Model
echo $this->Form->input('Contact.0.city',array('type'=>'hidden'));
echo $this->Form->input('Contact.0.postcode');
echo $this->Form->input('Contact.0.phone');
echo $this->Form->input('Contact.0.cellphone');
echo $this->Form->input('Contact.0.email',array('value'=>""));
echo $this->Form->input('Contact.0.id',array('type'=>'hidden'));
?>
Looking at the HTML source code that is generated, I see that whether I use the request action or just copy the contect of the form.ctp into the "Parent's" add file, I get the same HTML result.
HOWEVER!!! when I use the form.ctp Action Request, I get the blackhole, the tokens are being messed up!!!
Any Ideas?
Thanks in advance
Orly
If your problem is solely reusing a form, you can use the form as a Element, and then you could call it multiple times, substituting in the exact values you need.
As for SecurityComponent, I would recommend (at least as a temporary fix) disabling SecurityComponent for that specific action by using $this->Security->unlockedActions(); in your controller's beforeFilter()
The label shows up correctly, but for some reason the options in the drop down menu do not.
echo $form->input('job_category', array('label'=>'Emploi Catégorie',
'options'=>array('Activités commerciales générales')
));
it produces the following HTML:
<option value="0">Activités commerciales générales</option>
should be:
Activités commerciales générales
If you really have to use character entity references, I believe adding 'escape' => false to the input array should do it.
But the real answer is: don't use character entity references at all. Make sure the HTML page uses UTF-8 and the code is saved as UTF-8, and you can write accented characters normally in the code.
why don't you do this?
echo $form->input('job_category', array('label'=>'Emploi Catégorie',
'options'=>array('Activités commerciales générales')
));
It happened to me using spanish accents You need to put the escape option to false like this so cake doesn't escape the special characters
echo $form->input('job_category', array('label'=>'Emploi Catégorie',
'options'=>array('Activités commerciales générales'),
'escape' => false
));
How can I change the extension for CakePHP Views from .ctp to .php
I have seen there is this line in /cake/libs/view.php var $ext = '.ctp'; that sets the extension but how can I do it from my /app/ folder so it doesn't effect Cake core files.
Thanks
You can set the extension in your AppController with
public $ext = '.yourext';
This is is reply to Cameron's comment regarding the issue of using multiple extensions in light of the fact cakephp does not allow you to specify multiple extensions.
I am using Mustache for a single site that uses merb, rails2, rails3 and cakephp for different sections of the site. The cake site "receives" mustache files for common layout elements but these templates have a '.mustache' file extension which my cake site will not recognize. My workaround is basically what dhofstet suggests just framed in the context of your specific usecase. In short, create a wrapper that might look something like this:
<?
$tmp = $this->ext;
$this->ext = '.mustache';
?>
<?= $m->render($this->renderElement('moznav/advanced_header'), array('foo' => $bar)) ?><br />
<? $this->ext = $tmp; ?>
When flow returns to the caller, you keep on using your native file extension.
How can I change the extension for CakePHP Views from .ctp to .php
I have seen there is this line in /cake/libs/view.php var $ext =
'.ctp'; that sets the extension but how can I do it from my /app/
folder so it doesn't effect Cake core files.
example:
you have view posts/add.ctp
now you rename add.ctp into add.php
and then you run .../posts/add the message error show:
Error: The view for PostsController::add() was not found.
to your app can understand extention .php, you add line public $ext = '.php' in PostsController.php
now, you run again ..posts/add => okie, cakephp understand extention .php
Notice: if you use atrribute $ext = '.php' but file view named .ctp, cakephp extention .ctp will use by default
I found this post because I had the same problem. This is not mentioned in the Predominant TwigView plugin documentation on Github. I'm tired of those documentations that explains only half of things and with which we have to guess the second half. This is a big waste of time that slows down projects pointlessly.