CakePHP form builder drop down not preserving french accents - cakephp

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&eacute;s commerciales g&eacute;n&eacute;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
));

Related

How to give id to an image in CakePHP?

I'm inserting an image in my template file as
<?php echo $this->Html->image('profile_picture.png', array('alt'=>'frame partner avatar'), array('id'=>'framePartnerAvatar')); ?>
Now I'm trying to give style to this image by using the id mentioned, but on checking through Firebug only source and alternate name is visible. Image id is not coming there.
You have to use the correct syntax:
<?php echo $this->Html->image(
'profile_picture.png',
array(
'alt'=>'frame partner avatar',
'id'=>'framePartnerAvatar'
)); ?>
See HtmlHelper::image()
According to the documentation the method used to create images requires two parameters. The first one being the source link and the second one being the options parameter
$this->Html->image('cake_logo.png', ['alt' => 'CakePHP']);
Your code should be something along the lines of this
$this->Html->image('profile_picture.png', array(
'alt'=>'frame partner avatar',
'id'=>'framePartnerAvatar')
);
$thumb_img = $this->Html->image('yourimage.png',array('alt'=>'yoursite.com','id'=>'yourId'));
Please ensure that all HTML attributes such as alt, id, class etc needs to be written within a single array, and not multiple arrays.
<?php echo $this->Html->image('profile_picture.png', array(
'alt'=>'frame partner avatar',
'id'=>'framePartnerAvatar'
)
); ?>
This will certainly generate the following HTML:
<img src="/img/profile_picture.png" alt='frame partner avatar' id='framePartnerAvatar' />
Peace! xD

CakePHP 2.4 and Timehelper's timeAgoInWords locale

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

Unable to change form field name in cakephp

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.

cakephp Paginator -> sort - model option

I am having some issues sorting the table data by a field of a different model.
From here: http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html
It says I can add in the 'model' option but when I try:
echo $this->Paginator->sort('unit', 'Unit', array('model' => 'Unit'));
I get this error:
Warning (2): array_filter() expects parameter 1 to be array, null given [CORE/Cake/View/Helper/PaginatorHelper.php, line 395]
Warning (2): array_merge() [function.array-merge]: Argument #1 is not an array [CORE/Cake/View/Helper/PaginatorHelper.php, line 395]
Any idea what is going on here? The Main / default model is Card and I need to order by the Unit model for one of the column headings.
Thanks
If you are showing records in a list out of some tables, then you can use it via:
<?php echo $this->Paginator->sort('Unit.unit', 'Unit');
It will perfectly work without passing third argument model option.
Just a reminder for newer Versions: Associated models are not automatically loaded in CakePHP3s Paginator. Make sure you include the 'sortWhitelist' Option, see https://book.cakephp.org/3.0/en/controllers/components/pagination.html#control-which-fields-used-for-ordering
Please try below code
echo $this->Paginator->sort('Unit.unit', 'Unit', array('model' => 'Unit'));
Let me know if any.

htmlspecialchars

if i submit data like my string using form on insert/edit view, on a list view i'll get my string as italic (like here).
how can i avoid that, and to have my string (with visible all html tags) on all forms?
i.e. so it appears like this: <i>my string</i>
thanks in advance!
So you're asking how you can escape the HTML code on your views when you render the results as they exist in the database... is that right?
Assuming that is what you're asking, in your view, you could simply wrap the DB field output
<?php
foreach ( $rows as $row ) {
echo $html->tag("p",htmlentities($row['Model']['field']));
}
// or more simply
foreach ( $rows as $row ) {
echo htmlentities($row['Model']['field']).'<br/>';
}
?>
Maybe the option 'escape'=>true will be useful, like in:
$html->tag('p', $text, array('escape'=>true));

Resources