CakePHP 3.6 multi language form - forms

As mentioned in CakePHP 3.6.10 Translate behaviour not showing 'defaultLocale' values the default language values should be saved in the source table so they can be used as a fallback for empty fields in other languages.
However I have a problem building the forms for this. I have 5 languages (locales): en_US, nl_BE, fr_BE, de_BE and ru_RU. The defaultLocale is en_US. So to ADD a new record I did:
// for the defaultLocale
echo $this->Form->control('title');
// for all other languages I iterate over every language except of the defaultLocale
foreach ($supported_locales as $key => $val):
if ($key !== $default_locale):
echo $this->Form->control('_translations.' . $key . '.title');
endif;
endforeach;
This works fine. Allthough I'm not sure if this is the proper Cake-way to do it?
But in the VIEW (using a disabled form) and EDIT the defaultLocale field
echo $this->Form->control('title');
shows the translated value of the selected locale at that moment instead of the defaultLocale which is saved in the source table. F.e. when you switched the language to Russian at that moment you'll get to see:
English: Русский титул
Dutch: Nederlandse titel
French: Titre français
Deutsch: Deutscher Titel
Russian: Русский титул
So you're missing the value for the default locale (English) because it's replaced by the value for the currently selected language (here Russian). And you're not able to edit the value for the default locale when you're using the page in another language.
Am I overlooking something and is there a easier way to make this work 'out of the box'?

You must make sure that you fetch the records in the default locale, irrespectively of the current environments locale. You can do so using the translate behaviors setLocale() method (locale() before CakePHP 3.6), to explicitly set the locale to use for a specific repository, for example:
$locale = \Cake\Core\Configure::read('App.defaultLocale');
$this->Articles->setLocale($locale);
$query = $this->Articles->find('translations');
This will retrieve the articles in the configured default locale, irrespectively of what might have been set via I18n::setLocale(). If you are including associations where you need the locale applied too, then you have to explicitly set the locale for them too, ie:
$this->Articles->setLocale($locale);
$this->Articles->Comments->setLocale($locale);
$query = $this->Articles->find('translations')->contain('Comments');
See also
Cookbook > ORM > Behaviors > Translate > Retrieving one language without using I18n::locale

Related

CakePHP 4 Date format for FormHelper->date() how to change to UK format

I have the following code in a template:
<?= $this->Form->date('selected_date', ['required' => true]) ?>
This displays a lovely new dynamic date picker, but with the US format "mm/dd/yyyy". What I want is "dd/mm/YYYY"
In app.php I've set the APP_DEFAULT_LOCALE to en-GB.
In AppController.php I've set the following:
I18n::setLocale('en-GB');
Time::setDefaultLocale('en-GB'); // For any mutable DateTime
FrozenTime::setDefaultLocale('en-GB'); // For any immutable DateTime
Date::setDefaultLocale('en-GB'); // For any mutable Date
FrozenDate::setDefaultLocale('en-GB'); // For any immutable Date
How do I change the format? I can't find anything in the docs or online.
You can't change it, at least there's no reliable, cross browser/device compatible way, the control is rendered by the browser, and the current state of things is that browsers use the locale the browser currently runs in to format the control.
If you want something solid, then you'll have to use a custom JavaScript datepicker. If you want to walk on the edge, look into web components.
See also Is there any way to change input type="date" format?.

How to copy data of any object from one language to other language in pimcore 5?

I have to copy data of any object which is localized. I want to copy English data in the new locale whenever i add a new language. e.g. If i am adding a new language Germany then the English data of this particular object should be copied in German too.
Are you sure you won't like to use fallback Pimcore functionality? https://pimcore.com/docs/5.x/Development_Documentation/Multi_Language_i18n/index.html#page_Language-Configuration
If you'll use it you won't need to copy data but when Pimcore will see that German language is empty then the fallback logic will use English data

TCA configuration: Value of field should be copied to translated record

I am adding a field to the pages table (is a relation to a file) and would like the value of the field in the pages record to be copied to the translated record by default.
Currently, the copied field is empty (default value), which is probably a good idea in most cases.
I am thinking of something that behaves like l10n_mode = prefixLangTitle without the prefix.
Depending on the TYPO3 version this should be possible with one of the following behaviours for the inline field:
https://docs.typo3.org/typo3cms/TCAReference/7.6/Reference/Columns/Inline/Index.html#behaviour
https://docs.typo3.org/typo3cms/TCAReference/8.7/ColumnsConfig/Type/Inline.html#localizechildrenatparentlocalization
https://docs.typo3.org/typo3cms/TCAReference/latest/ColumnsConfig/Type/Inline.html#allowlanguagesynchronization
Sine the localizeChildrenWithParentLocalization feature is broken with pages and pages_language_overlay though, I guess the only working versions would be CMS 8 or 9 with properly configured language synchronization.
https://forge.typo3.org/issues/78743
Use
['behaviour']['allowLanguageSynchronization'] => true
if the translated record will use the value from the default field by
default (will effectively be copied), but it should be possible to change
this later.
See pages.author as example.
When "Custom value" is selected, the value can be overridden.
Alternativively, use
l10n_mode = exclude
if the field should always have the value of the default language and you
should not be able to change it in the translated record.

TYPO3 Not able anymore to translate CE's to other languages

Is there a way to 'reset' or db entries to delete or something else without deleting all content already translated... (and would that solve the issue?)
In the first go all translation went well, I chose a 'one tree' setup pressing translate rather then copy, but adding and modifying the content over time certain elements where not available for translation anymore ...
at one point the second step in translation asked for the origin language (if I recall well) and trying to resolve I chose another language than the default, now I do not have the choice anymore and the record summary proposes elements from german rather than from my default language (italian) which might be the problem since I can only introduce new content in the default language.
if I try to localize from the list view clicking the language flag, in the language selection field I get [INVALID VALUE("1")] and as only option (Default) [0] to select ...
I use TYPO3 V7.6.13, EXT:gridelements and EXT:t3sbootstrap (the nested CE's where the first to show trouble)
content of my database table sys_language: (my default lang is italian)
uid | pid | tstamp | hidden | title | flag |
1 0 ... 0 English gb
2 0 ... 0 German de
does anyone know good reference or a solution to this problem ?
That sounds like your sys_language records (in yoour root-page, id = 0) are disabled or missing.
Those records make languages available for translation.
The other factor for translation selection is the translation of the current page. You need to have the page translated to a language (given above) to be able to translate any record in that page. That also is neccessary for pages which contain only data.
first check (as suggested by bernd) if your language setup is valid:
do you have a sys_language record for every added language in your
root-page ? (you can control the sys_language table with phpMyAdmin)
is the page translated ?
in my case that was all fine but I needed a thorough cleanup:
I deleted all hidden records in the backend
I activated the system extension 'recycler' and deleted all in the
list (from root-page recursive)
I then checked with phpMyAdmin which records in tt_content where
hidden (and did not show in the backend) and deleted those manually
once I did that the translate request answered perfectly and I could restore the missing CE's translations
note: I still had gridelements showing up in wrong sequence for the translation in the backend but correctly in the frontend, the nested CE's seem though, and of course 'CLEAR CASH FREQUENTLY' to avoid surprises ...

Use localized date format with date picker in cakephp 3

I'm building a cakephp 3 app (cakephp v3.3.2 that is) and I have a problem getting dates displayed in the chosen locale (de_DE).
The database field in my example is invoice_date, which is of type DATE (stored in a mysql DB).
I want to use a date picker in the web page ("zebra_datepicker"), so in the view I use a single text entry field for the date instead of the three drop-downs that are displayed by default:
echo $this->Form->input('invoice_date', [ 'type' => 'text' ]);
To get the date displayed in the German format dd.mm.YY I changed the global locale setting to
ini_set('intl.default_locale', 'de_DE');
in config/bootstrap.php.
For testing, I created a new record in the database and set the invoice_date to 2016-09-02 (Y-M-D).
If I call the edit action of my controller now, I get a default value of 02.09.16 in the form, which is correct. But if I submit the form back, the database value of the field is changed into 2002-09-16!
Do I need some extra code in the controller to change the date format back into its original form? Is this a bug in the localization code of cakephp or did I miss something? Note, that my controller just uses patchEntity to process the posted data.
I already tried adding date('invoice_date', 'dmy') in the validationDefault method of the table object, but this didn't change anything:
$validator
->date('invoice_date', 'dmy')
->requirePresence('invoice_date', 'create')
->notEmpty('invoice_date');
Thanks for your help!
I just found the solution to my problem: in bootstrap.php, I had to add:
Type::build('date')->useLocaleParser();
Type::build('datetime')->useLocaleParser();
With that, I can enter dates like 31.12.16 (d.m.y) and the date gets correctly saved in the database. This works with the simple validator:
$validator
->date('invoice_date')
->notEmpty('invoice_date');
To also support dates like 31.12.2016 (d.m.Y), I had to add an extra parameter to the date validator, like this:
$validator
->date('invoice_date', 'dmy')
->notEmpty('invoice_date');