Translation issueshttps://lab.civicrm.org/dev/translation/-/issues2018-10-24T20:56:28Zhttps://lab.civicrm.org/dev/translation/-/issues/15Backend credit card contribution are left as Pending if contribution statuses...2018-10-24T20:56:28ZbgmBackend credit card contribution are left as Pending if contribution statuses are localizedHow to reproduce:
* Modify the Contribution Statuses, so that the label for Complete is 'Terminé' (https://dmaster.demo.civicrm.org/civicrm/admin/options?gid=11&reset=1) - this changes the label, not the `name`, so that we can localize ...How to reproduce:
* Modify the Contribution Statuses, so that the label for Complete is 'Terminé' (https://dmaster.demo.civicrm.org/civicrm/admin/options?gid=11&reset=1) - this changes the label, not the `name`, so that we can localize the contribution statuses.
* Go to a contact record and record a new credit card contribution (you can use the dummy processor)
![contribution-pending-status-complete](/uploads/0eb1ea21b9b42a7494182e5423b9aa10/contribution-pending-status-complete.gif)
If I change the contribution status back to 'Complete', it works as expected.
I suspect the culprit is here:
https://github.com/civicrm/civicrm-core/blob/master/CRM/Contribute/Form/Contribution.php#L1181
The `$statuses` are fetched using:
```
$statuses = CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id');
```
PS: the front-end form uses a hardcoded value:
* https://github.com/civicrm/civicrm-core/blob/master/CRM/Contribute/Form/Contribution/Confirm.php#L1649
* https://github.com/civicrm/civicrm-core/blob/master/CRM/Contribute/Form/Contribution/Confirm.php#L2465
```
protected function completeTransaction($result, $contributionID) {
if (CRM_Utils_Array::value('payment_status_id', $result) == 1) {
try {
civicrm_api3('contribution', 'completetransaction', array(
'id' => $contributionID,
'trxn_id' => CRM_Utils_Array::value('trxn_id', $result),
'payment_processor_id' => $this->_paymentProcessor['id'],
'is_transactional' => FALSE,
'fee_amount' => CRM_Utils_Array::value('fee_amount', $result),
'receive_date' => CRM_Utils_Array::value('receive_date', $result),
'card_type_id' => CRM_Utils_Array::value('card_type_id', $result),
'pan_truncation' => CRM_Utils_Array::value('pan_truncation', $result),
));
}
catch (CiviCRM_API3_Exception $e) {
if ($e->getErrorCode() != 'contribution_completed') {
throw new CRM_Core_Exception('Failed to update contribution in database');
}
}
}
}
```5.8https://lab.civicrm.org/dev/translation/-/issues/85Some strings in core afforms do not translate2024-03-25T18:55:32ZbgmSome strings in core afforms do not translateFor example:
- Enable CiviCampaign
- Go to the CiviCampaign dashboard
![image](/uploads/49a1d30b027b36f57971cbc4fb9d48ff/image.png)
For the tabs, the strings are correctly wrapped with `ts`, and I double-checked that the strings are t...For example:
- Enable CiviCampaign
- Go to the CiviCampaign dashboard
![image](/uploads/49a1d30b027b36f57971cbc4fb9d48ff/image.png)
For the tabs, the strings are correctly wrapped with `ts`, and I double-checked that the strings are translated in my translation file.
For the placeholders on the filter fields, the strings are not correctly wrapped in `ts`, but even if I do wrap them, and I make sure to add the strings to my translation files, they do not translate.
cc @colemanwhttps://lab.civicrm.org/dev/translation/-/issues/84`testLocalizedData()` failing after recent strings update2024-03-29T02:04:10Ztotten`testLocalizedData()` failing after recent strings updateIn CI, the test `testLocalizedData()` has started failing consistently. I've done some hunting and may have an explanation (*but don't know the next step*).
__The Test__: `testLocalizedData()` generates the SQL data-set in two locales. ...In CI, the test `testLocalizedData()` has started failing consistently. I've done some hunting and may have an explanation (*but don't know the next step*).
__The Test__: `testLocalizedData()` generates the SQL data-set in two locales. It spot-checks the data for a common string that should usually be translated. Specifically, `New Organization` is a link in the default menu. It's translated as `Neue Organisation` (`de_DE`) or `Nouvelle organisation` (`fr_FR`).
__Compare__: The test passes on my laptop but not in CI. My laptop has older translation data than the server.
You can manually inspect by running a small script and grepping the output (`cv scr printsql.php | grep Neue`):
```php
function _getSqlLive($locale) {
$schema = new \CRM_Core_CodeGen_Schema(\Civi\Test::codeGen());
$files = $schema->generateLocaleDataSql($locale);
foreach ($files as $file => $content) {
if (preg_match(';^civicrm_data\.;', $file)) {
return $content;
}
}
throw new \Exception("Failed to generate $locale");
}
echo _getSqlLive('de_DE');
```
Both outputs include some translated strings, but the newer doesn't have as many:
```diff
---Local machine, old data
+++Server machine, new data
("Individual,Contact",NULL,"4","0","1","new_individual","Neue Person"),
-("Organization,Contact",NULL,"5","0","1","new_organization","Neue Organisation"),
-("Household,Contact",NULL,"6","0","1","new_household","Neuer Haushalt"),
+("Organization,Contact",NULL,"5","0","1","new_organization","New Organization"),
+("Household,Contact",NULL,"6","0","1","new_household","New Household"),
```
If I inspect the data (`msgunfmt civicrm.mo -o civicrm.po`), I find these in the old data-set:
```
msgid "New Individual"
msgstr "Neue Person"
msgid "New Organization"
msgstr "Neue Organisation"
msgctxt "menu"
msgid "New Individual"
msgstr "Neue Person"
msgctxt "menu"
msgid "New Organization"
msgstr "Neue Organisation"
```
And these in the new data-set:
```
msgid "New Individual"
msgstr "Neue Person"
msgctxt "menu"
msgid "New Individual"
msgstr "Neue Person"
msgctxt "menu"
msgid "New Organization"
msgstr "Neue Organisation"
```
So it's missing `New Organization` in the default context. Additionally, the phrases `Phone Call` and `Meeting` appear in the old data-set but not the new data-set. I see similar omissions in `fr_FR`.
I assume that the SQL translation is evaluating everything in the default context. (It doesn't seem to use the `menu` translations). I don't know if that's good or bad. But regardless, it's probably bad that `Phone Call` and `Meeting` are missing.
In the CI logs for `testTranslatedData()`, the failure starts on roughly Feb 4. (Some places seem to start Feb 5 -- l10n data is cached for a bit.) I'm guessing this is related the new strings released around Feb 4 (https://chat.civicrm.org/civicrm/pl/jyqia56a47dp5dnrouiabnmnuw).
(ping @bgm)https://lab.civicrm.org/dev/translation/-/issues/83No translation for "sections" in "New <contact>"2023-08-30T12:57:17Zthoni56No translation for "sections" in "New <contact>"When creating a new person/household/organisation there are foldable sections for details, address, communication preferences etc.
When the site has a non-English localization (at least a Swedish one) they are not translated.
![Skärmav...When creating a new person/household/organisation there are foldable sections for details, address, communication preferences etc.
When the site has a non-English localization (at least a Swedish one) they are not translated.
![Skärmavbild_2023-08-11_kl._13.38.33](/uploads/effa60ca9aa352a2d735ddfe89bb8d79/Skärmavbild_2023-08-11_kl._13.38.33.png)
I'm contributing to the Swedish translation so I know that the strings are translated in Transifex ;-). I have `uplang` installed and it seems to update other translations (although I would love a way to explicitly trigger the download, see https://lab.civicrm.org/extensions/uplang/-/issues/2).https://lab.civicrm.org/dev/translation/-/issues/82Spelling error in Dutch deprecation notice2023-05-04T13:50:48ZJanecSpelling error in Dutch deprecation noticeCurrent: APIv3 is de legacy versie van CiviCRM's API. Hoewel nog ondersteunt, raden wij het gebruik in nieuwe projecten af.
Should be: APIv3 is de legacy versie van CiviCRM's API. Hoewel nog ondersteund, raden wij het gebruik in nieuwe ...Current: APIv3 is de legacy versie van CiviCRM's API. Hoewel nog ondersteunt, raden wij het gebruik in nieuwe projecten af.
Should be: APIv3 is de legacy versie van CiviCRM's API. Hoewel nog ondersteund, raden wij het gebruik in nieuwe projecten af.https://lab.civicrm.org/dev/translation/-/issues/81eWAYRecurring/ewayrecurring - Tricky to checkout git repo2022-11-30T08:36:05ZtotteneWAYRecurring/ewayrecurring - Tricky to checkout git repoThere appear to be two l10n data folders for "ewayrecurring", but they have different capitalization:
https://github.com/civicrm/civicrm-l10n-extensions/tree/master/po/eWAYRecurring
https://github.com/civicrm/civicrm-l10n-extensions/tre...There appear to be two l10n data folders for "ewayrecurring", but they have different capitalization:
https://github.com/civicrm/civicrm-l10n-extensions/tree/master/po/eWAYRecurring
https://github.com/civicrm/civicrm-l10n-extensions/tree/master/po/ewayrecurring
If you checkout on a case-insensitive filesystem, then you get weird messages.
Here's what I see with initial checkout:
```
[bknix-min:~/bknix/build/universe/ext/civicrm-l10n-extensions] git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: po/eWAYRecurring/bg_BG/eWAYRecurring.po
modified: po/eWAYRecurring/ca_ES/eWAYRecurring.po
modified: po/eWAYRecurring/cs_CZ/eWAYRecurring.po
modified: po/eWAYRecurring/cy_GB/eWAYRecurring.po
modified: po/eWAYRecurring/de_DE/eWAYRecurring.po
modified: po/eWAYRecurring/en_GB/eWAYRecurring.po
modified: po/eWAYRecurring/es_ES/eWAYRecurring.po
modified: po/eWAYRecurring/fr_CA/eWAYRecurring.po
```
The two names `po/eWAYRecurring/bg_BG/eWAYRecurring.po` and `po/ewayrecurring/bg_BG/ewayrecurring.po` point to the same object in the filesystem, but they have different content, so one or the other gets locally modified.
Because the repo is in this funny state, it's hard to stay up-to-date (`git pull` doesn't run cleanly).https://lab.civicrm.org/dev/translation/-/issues/80Recurring contributions: ThankYou page does not translate the membership cont...2023-05-18T23:59:42ZshaneonabikeRecurring contributions: ThankYou page does not translate the membership contribution unitRelated to #32
To reproduce:
* Configure CiviCRM to non-English (ex: French)
* Setup a recurring membership contribution page
* Choose a membership and choose recurring option
Result:
> Cette adhésion sera renouvelée automatiquement ...Related to #32
To reproduce:
* Configure CiviCRM to non-English (ex: French)
* Setup a recurring membership contribution page
* Choose a membership and choose recurring option
Result:
> Cette adhésion sera renouvelée automatiquement tous les year.
(i.e. the frequency unit is not translated)
From the string:
> This membership will be renewed automatically every %1.
Like @mathieu I will ignore for now this string:
> This recurring contribution will be automatically processed every %1 %2s.
(which assumes that all plurals end with an 's', in every language of the world.)https://lab.civicrm.org/dev/translation/-/issues/79Error in link on upgrade page after update database ready2022-11-30T18:23:15ZHanVError in link on upgrade page after update database readyI have today upgraded to version 5.55.2, on the screen after the database upgrade is an error in the link in the message:
Your Date Format settings have been automatically updated. (CRM/Upgrade/Incremental/php/FiveFiftyThree.php)
In the...I have today upgraded to version 5.55.2, on the screen after the database upgrade is an error in the link in the message:
Your Date Format settings have been automatically updated. (CRM/Upgrade/Incremental/php/FiveFiftyThree.php)
In the open tag it must be: href='%1'
I found the place with transifex.https://lab.civicrm.org/dev/translation/-/issues/78Define `setLocale()` for languages which aren't "all there"2023-01-13T01:04:07ZtottenDefine `setLocale()` for languages which aren't "all there"## The Basic Question
__Q: What to do if someone activates a locale that isn't "all there"?__
To clarify the question:
* "Activate a locale" means "Call `setLocale('xx_XX')`". This could be:
* Click a button in the web UI to set t...## The Basic Question
__Q: What to do if someone activates a locale that isn't "all there"?__
To clarify the question:
* "Activate a locale" means "Call `setLocale('xx_XX')`". This could be:
* Click a button in the web UI to set the language of the screen. (This requires a call to `setLocale(...)`.)
* Send an email or SMS message in another language. The message includes tokens, and tokens can be localized. (This requires a call to `setLocale(...)`.)
* Process an API call in an alternate language (such as "Preview mailing in locale X" / "Render message in locale X"). It may respond with localized data. (This requires a call to `setLocale(...)`.)
* "All there" means that a locale is enabled/defined in all localization layers
* Is marked as active in `civicrm_option_value` (`languages`; ie *communication-preference languages*)
* Is marked as active in `civicrm_setting` (`uiLanguages`; ie *web UI languages*)
* Has `ts()` data (file `l10n/xx_XX/civicrm.mo`)
* (*In multilingual deployments*) Has SQL columns (aka setting `languageLimit`)
* Has currency formatting rules
* ~~Has date formatting rules~~ (*afaik, we don't actually track this on a per-locale basis right now*)
* Is supported by Drupal/Joomla/WordPress
Example: A staff member writes emails (`Mailing` or `MessageTemplate`) in few locales (eg `es_US` and `en_US`). They send email to a user who prefers `es_US`. The email has tokens, which can rely on services like `ts()` and `Civi::format()`. But the system doesn't fully support `es_US` (eg there is no `l10n/es_US/civicrm.mo`). How will the email render? How will the tokens be processed?
## The Basic Answer
__A: Either switch the locale completely -- or mix-in substitutes from other locales.__
Example (*continued*): If you are rendering an email for `es_US` but lack some resources for `es_US`, then you might switch the request to `en_US`, or you might mix-in elements from `es_MX`.
| | Ideal | Complete Switch | Mixed Locales |
|--|--|--|--|
| tsLocale | es_US | en_US | es_MX |
| dbLocale | es_US | en_US | es_MX |
| Currency | es_US | en_US | en_US |
| Dates | es_US | en_US | es_MX |
## When the question matters (broadly)
I imagine that many deployers don't care -- they pick 1 or 2 well-defined locales and do everything in that locale. But it can matter ifeither...
* ...if you define communication-materials (`Mailing`, `MessageTemplate`) in alternate languages
* ...if your primary audience uses a locale that isn't fully supported (`es_US`, `en_NZ`)
## Mixed signals
At a lower level, the existing code has some inconsistent answers:
* When booting Civi, the `applyLocale()` checks several settings (from Civi+CMS) and decides which locale to activate.
* In the Civi API, there's an option (`setLanguage()` / `option.language`) to set the active locale. It only lets you choose locales that are configured for multilingual.
* In localization unit-tests, some tests call `setLocale()` for locales that aren't enabled.
* In the `CRM_Core_I18n::setLocale()`, it allows you pass *anything* (without validation).
At a higher level, I imagine two different attitudes:
* __You should only process requests in locales that are fully supported.__ If a user performs an action in some other locale, then they will inevitably get quirks (eg mail-tokens that render with alien content). Better to make a clean switch to a supported locale rather than to peck at quirks.
* __You should allow any locale with a best-effort/closest-match.__ Even if we don't have all localization resources for all locales, we have lots of pieces that get pretty close, and admins should be allowed to send messages with any locale they choose. Granted, they _could_ send messages with tokens that don't localize properly; it's up to them to write the message and choose suitable tokens.
## Exploratory branch
There is an [exploratory branch (PR 24174)](https://github.com/civicrm/civicrm-core/pull/24174) which currently answers this way:
* The class `Locale` represents the major decisions/data-points for the locale (eg tsLocale, dbLocale, moneyFormatter).
* The function `Locale::negotiate('xx_XX')` is a focal-point -- it takes a preferred a locale (`xx_XX`), examines the settings+resources, and creates a concrete `Locale` descriptor.
* `Locale::negotiate()` is influenced by a new setting, `partial_locales` (on/off). If enabled, then it will mix locales. If disabled, it will only use complete locales.
A couple things in flux:
* The `negotiate()` looks at a bunch of settings and resources. Which ones matter? How should each be used?
* Some tests were written on the assumption that `setLocale()` has no validation. Some of these can be easily [tweaked so as the make the test-scenario more valid](https://github.com/totten/civicrm-core/commit/bc77245f54923453e59d484a60a944eadfc9c3fc). But there are some (like `testUiLanguages()` and `testI18nEventCopy()`) which have relevant edge-cases. Need to change the test or change `negotiate()`.
* Are there callers in contrib (`setLocale('xx_XX')`) which will barf if the values are negotiated?
(*I may have done a similar sort of braindump on MM a couple weeks ago... but I want something to link back to and add comments on...*)5.54.0https://lab.civicrm.org/dev/translation/-/issues/77Translation of message for multiple registrations missing2022-08-19T15:24:12Zthoni56Translation of message for multiple registrations missingIf you allow multiple registrations to an event, and select a number greater than 1 when you register (from the web view) the following string is displayed:
Fill in your registration information on this page. You will be able to ent...If you allow multiple registrations to an event, and select a number greater than 1 when you register (from the web view) the following string is displayed:
Fill in your registration information on this page. You will be able to enter the registration information for additional people after you complete this page and click "Continue".
This string can not be translated in Transifex (since it does not exist). The string there is (probably):
Fill in your registration information on this page. If you are registering additional people, you will be able to enter their registration information after you complete this page and click "Review your registration".
We are running 5.50.4 on Joomla.https://lab.civicrm.org/dev/translation/-/issues/76Add support for extension .mo in [civicrm.l10n]2023-01-28T19:10:09ZbgmAdd support for extension .mo in [civicrm.l10n]#30 added support for translation "mo" files in a custom resource directory (such as `files/civicrm/l10n`). This makes it easier to update files regularly, such as with the l10nupdate extension, which must be able to write to disk.
Howe...#30 added support for translation "mo" files in a custom resource directory (such as `files/civicrm/l10n`). This makes it easier to update files regularly, such as with the l10nupdate extension, which must be able to write to disk.
However currently extensions must still have their "mo" files in their own directory. This causes challenges with the distribution of mo files for core extensions, but it is also annoying for non-core extensions that are available for automatic distribution (i.e. on Transifex).
Proposal: support both, as a transitional measure.
Eventually, I think we should deprecate the old behaviour, and always have a process such as l10nupdate which will fetch translations. That way we can also deprecate `civicrm-l10n-xx.tar.gz`.5.59.0https://lab.civicrm.org/dev/translation/-/issues/75Translatable fields within Extension table2022-04-21T20:39:46ZseamusleeTranslatable fields within Extension tableAt present the CiviCRM i18n widget code and also the i10n schema code depend on the functions in the schema structure file returning an array of fields or html widgets. The Schema Structure file does not contain any information about tab...At present the CiviCRM i18n widget code and also the i10n schema code depend on the functions in the schema structure file returning an array of fields or html widgets. The Schema Structure file does not contain any information about tables other than core tables so for example in the JMA Grant Applications extension if we wanted to make the title or the introductory text field translatable we would have to hack the schema structure file.
I would like to propose that we create 3 new Events or similar to handle altering the fields, indices and widgets functions in the schema structure file.https://lab.civicrm.org/dev/translation/-/issues/74ts() - Allow symbolic placeholders2022-01-27T13:24:34Ztottents() - Allow symbolic placeholdersOverview
---------
When writing translatable strings, placeholders must be numeric.
This leads to some quirky strings - eg if you're outputting a title and subtitle ("Some Chapter: Some Section"), the only way to encode that is `ts('%1...Overview
---------
When writing translatable strings, placeholders must be numeric.
This leads to some quirky strings - eg if you're outputting a title and subtitle ("Some Chapter: Some Section"), the only way to encode that is `ts('%1: %2')`. This string should be translatable because the layout is language dependent (eg LTR/RTL; eg punctuation-preferences), but the exported string will become meaningless when presented in Transifex (or similar). And it may be confused with other/similar strings.
Current behavior
-----------------
The function `ts(string $str, array $params)` accepts the following `$params`:
* Functional params (`count`, `plural`, `context`, `domain`, `escape`, `skip_translation`)
* Substitution params (numeric keys; `0`, `1`, `2`, ...)
As in:
```php
echo ts('Hello, %1!', [
1 => $name,
]);
echo '<li>' . ts('%1: %2', [
1 => $title,
2 => $subtitle,
]) . '</li>';
echo ts('The directory %1 is not writable. Please check your file permissions.', [
'plural' => 'The following directories are not writable: %1. Please check your file permissions.',
'count' => count($notWritableDirs),
1 => implode(', ', $notWritableDirs),
]),
```
```smarty
{ts 1=Bob}Hello %1!{/ts}
<li>{ts 1="Title" 2="Subtitle"}%1: %2{/ts}</li>
```
~~Proposed behavior (draft 1; symbol-prefix)~~
-----------------
Any `$params` which begin with a symbol (`%`, `_`, `{`, `@`, etc) will be used for variable substitution.
The earlier examples remain valid. Additionally, these examples are also valid:
```php
echo ts('Hello, %name!', [
'%name' => $name,
]);
echo '<li>' . ts('%title: %subtitle', [
'%title' => $title,
'%subtitle' => $subtitle],
) . '</li>';
echo ts('The directory %dir is not writable. Please check your file permissions.', [
'plural' => 'The following directories are not writable: %dir. Please check your file permissions.',
'count' => count($notWritableDirs),
'%dir' => implode(', ', $notWritableDirs),
]),
```
```smarty
{ts _NAME_=Bob}Hello _NAME_!{/ts}
<li>{ts _title_="Foo" _subtitle_="Bar"}_title_: _subtitle_{/ts}</li>
```
Proposed behavior (draft 2; capitalization-based)
-----------------
Any `$params` which begin with a capital letter (`[A-Z]`) will be used for variable substitution.
```php
echo ts('Hello, %NAME!', [
'NAME' => $name,
]);
echo '<li>' . ts('%TITLE: %SUBTITLE', [
'TITLE' => $title,
'SUBTITLE' => $subtitle],
) . '</li>';
echo ts('The directory %DIR is not writable. Please check your file permissions.', [
'plural' => 'The following directories are not writable: %DIR. Please check your file permissions.',
'count' => count($notWritableDirs),
'DIR' => implode(', ', $notWritableDirs),
]),
```
```smarty
{ts NAME=Bob}Hello %NAME!{/ts}
<li>{ts TITLE="Foo" SUBTITLE="Bar"}%TITLE: %SUBTITLE{/ts}</li>
```
Comments
---------
Either draft (using symbol-prefix or using uppercase) should avoid conflicts with existing strings+params. (Existing params do not begin with symbols and they are not uppercase.)
A couple factors in choosing a symbol:
* Using `%` is most consistent with current `ts()` style.
* `ts()` is used in multiple programming languages. Each has different compatibility/constraints.
* Pure PHP and pure JS are fairly flexible (`%FOO`, `{{FOO}}`, `_FOO_`, etc)
* Smarty-HTML (`{ts KEY=VALUE}...{/ts}`) is pretty limited. The bottleneck is how it parses the `KEY`.
* Angular-HTML (`{{ts('...')}}`) is in the middle. It's OK for `{{ts('%FOO')}}`, `{{ts('_FOO_')}}`, but I wouldn't count on `{{ts('{{FOO}}')}}`.
* If you want one symbol that works everywhere, `_` is probably it.
* Being flexible about symbol may be good for compatibility in the most contexts.
I suppose that the uppercase approach constrains style a bit, but maybe that's a good thing - ie you get more consistency in how `ts()` looks across environments.
Questions
---------
Are there any constraints in other layers -- eg Transifex, civistrings -- which would prevent this?
As far as I know, the only constraints which require using numeric-keys are baked into `ts()` itself.https://lab.civicrm.org/dev/translation/-/issues/73Missing translation of recur_frequency_units2022-02-17T03:46:27ZmasettoMissing translation of recur_frequency_unitssee row 789 of `CRM/Contribute/Form/Contribution/Main.php`:
```
$unit .= "(s)";
$form->assign('frequency_unit', $unit);
```
It uses `value` of `recur_frequency_units` and not its label.
I think you could translate it at row 150 of t...see row 789 of `CRM/Contribute/Form/Contribution/Main.php`:
```
$unit .= "(s)";
$form->assign('frequency_unit', $unit);
```
It uses `value` of `recur_frequency_units` and not its label.
I think you could translate it at row 150 of templates/CRM/Contribute/Form/Contribution/Main.tpl
```
{if $one_frequency_unit}
{ts}{$form.frequency_interval.label}{/ts}
{else}
{ts}{$form.frequency_unit.html}{/ts}
{/if}
```
What do you think?https://lab.civicrm.org/dev/translation/-/issues/72"Cancel" in registration update should have different translation than "cance...2023-03-14T01:46:02Zthoni56"Cancel" in registration update should have different translation than "cancel" as in "abort operation"When you change status of a registration, especially through the self-service registration update, you can choose between "Transfer" or "Cancel" in English. The Swedish translation of that precis "Cancel" should not be "Avbryt" (meaning ...When you change status of a registration, especially through the self-service registration update, you can choose between "Transfer" or "Cancel" in English. The Swedish translation of that precis "Cancel" should not be "Avbryt" (meaning something like "Abort"), as is the case with most of the other instances. In Swedish, at least, it should be translated to something different, like "Avbokad" (which means "Deregister") as that is used in the rest of the Swedish translation.
This seems to be impossible since the same translation for "Cancel" is used everywhere (correct me if I'm wrong and how to distinguish the two). I don't know if this is a problem with the tools for managing translations as this type of problem has popped up a few times.
I'm one of the main contributors to the Swedish translation.
(Sorry if I posted this issue in the wrong place. Please direct me to the right place and update the instructions on https://civicrm.org/bug-reporting as they say "Click Create New Issue in at the top of the left panel". I don't have that... This makes new Issue Tracker very confusing, disclosing the internal structure of the project.)https://lab.civicrm.org/dev/translation/-/issues/71Full Month Names: avoid relying on the operating system's locale for translation2021-09-07T14:23:31ZbgmFull Month Names: avoid relying on the operating system's locale for translationThis kind of question comes up from time to time:
https://civicrm.stackexchange.com/questions/35468/date-in-english-even-when-page-is-set-to-french/40170
> "The date is always uses English month and day names regardless of the interfa...This kind of question comes up from time to time:
https://civicrm.stackexchange.com/questions/35468/date-in-english-even-when-page-is-set-to-french/40170
> "The date is always uses English month and day names regardless of the interface language. How do I fix this?"
The main issue is because currently translating the month name relies on the operating system. The non-English locale must be enabled so that `strftime` outputs the correct month name (ex: "janvier" not "January").
Most people somewhat control their hosting environment, and can enable it once they know how, but since the default CiviCRM date format uses `%B` (full month name), it gives a bad first impression. Considering we already have those strings in Transifex, it would be easy to just hardcode the list of months and translate using 'ts'.5.43.0bgmbgmhttps://lab.civicrm.org/dev/translation/-/issues/70Multi-lingual: Contact Type label is cached regarless of language2021-08-28T04:51:08ZbgmMulti-lingual: Contact Type label is cached regarless of languageTo reproduce:
* Enable multi-lingual
* Add a second language
* View a contact record, switch to the other language, then view the contact record again.
Note that the "Contact Type" will always be the same in both languages.
![contactt...To reproduce:
* Enable multi-lingual
* Add a second language
* View a contact record, switch to the other language, then view the contact record again.
Note that the "Contact Type" will always be the same in both languages.
![contacttype-2021-08-12_15-29](/uploads/d72800debe08abdc071edfd036113a88/contacttype-2021-08-12_15-29.png)
The root of the bug is in `CRM/Contact/Page/View/Summary.php` `getAllContactTypes`, the cache does not take language into account:
```
protected static function getAllContactTypes() {
if (!Civi::cache('contactTypes')->has('all')) {
$contactTypes = (array) ContactType::get(FALSE)
->setSelect(['id', 'name', 'label', 'description', 'is_active', 'is_reserved', 'image_URL', 'parent_id', 'parent_id:name', 'parent_id:label'])
->execute()->indexBy('name');
```
@eileen Would it make sense to add the language to `has('all')`? I'm not too familiar with the cache service, and suspect there will be similar issues in other places.5.42.0https://lab.civicrm.org/dev/translation/-/issues/69"On behalf of" and "in honor of" labels disappear when multilingual is enabled2021-07-27T13:36:29ZJonGold"On behalf of" and "in honor of" labels disappear when multilingual is enabledThis is related to #27 but is a separate issue. To replicate:
* Create a contribution page that allows giving on behalf of an organization.
* Load the contribution page, note the label on the new checkbox.
* Enable multilingual support....This is related to #27 but is a separate issue. To replicate:
* Create a contribution page that allows giving on behalf of an organization.
* Load the contribution page, note the label on the new checkbox.
* Enable multilingual support.
* Reload the contribution page. Note that the label is missing.
This is inconsistent with other l10n behavior, where the default language is the fallback. I propose that the behavior match on these fields.5.41.0JonGoldJonGoldhttps://lab.civicrm.org/dev/translation/-/issues/68crmScope is not working for extensions2021-04-08T23:19:52ZbgmcrmScope is not working for extensionsNormally extensions can translate using this syntax:
```
{crmScope key="myext"}
{ts}Hi there{/ts}
{/crmScope}
```
because it sort of expands to `{ts domain="myext"}Hi there{/ts}`.
However, for some time (at least since 5.29), this h...Normally extensions can translate using this syntax:
```
{crmScope key="myext"}
{ts}Hi there{/ts}
{/crmScope}
```
because it sort of expands to `{ts domain="myext"}Hi there{/ts}`.
However, for some time (at least since 5.29), this has not been working.
It should be possible to reproduce this with [i18nexample](https://github.com/mlutfy/ca.bidon.i18nexample/) but I have to admit I have not tested that extension, but have seen it on a few other extensions.https://lab.civicrm.org/dev/translation/-/issues/67Canonize API for storing translated data2021-08-12T19:25:30ZtottenCanonize API for storing translated data# Goal
Enable richer user experiences which incorporate data-translation. Specifically, provide a CRUD API for administrative applications that need to read/write alternate versions of a string in the database.
# Background
* This is ...# Goal
Enable richer user experiences which incorporate data-translation. Specifically, provide a CRUD API for administrative applications that need to read/write alternate versions of a string in the database.
# Background
* This is most immediately motivated by https://lab.civicrm.org/dev/mail/-/issues/83, which aims to improve the process+experience of drafting+testing workflow templates. For this case, the string that is being edited (ie `civicrm_msg_template.msg_html`) is a relatively rich piece of content (with HTML tags, tokens, Smarty expressions - which in turn may vary based on the context for which the template will be used). The richness of the text implies that one should have more features available (token-pickers, syntax-highlighting, ad nauseum). Editing a translation of this content in a generic textbox (as with multilingual UI, Transifex UI, or POEdit) would be difficult and error-prone.
* This is intended as a step in support of https://lab.civicrm.org/community/feature-request/-/issues/26, which is a broad effort (initiated by @ayduns @BjoernE) to re-conceive how the multilingual subsystem works. TLDR: Current multilingual requires significant MySQL schema manipulation. This works for 1-3 languages but does not scale to 10 languages. Resolving it requires changes in the storage/lifecycle of translated data.
* Inspired by this discussion, Eileen wrote a proof-of-concept extension https://github.com/eileenmcnaughton/civi-data-translate. The scope of `civi-data-translate` mostly matches the scope of this filing, but not quite perfectly. It matches insofar as it introduces an APIv4 interface and a MySQL table for strings. It diverges insofar as it specifically touches on `MessageTemplate`. (The work for `MessageTemplate` is left as a separate matter.) Its biggest obstacle is dependency-hell: it requires a skilled administrator to maintain a deployment, which disincentivizes development and usage.
# Approaches
Working within the limits of available code and capacity, it appears feasible to adapt `civi-data-translate` to this purpose. Either:
1. Move its APIv4 interface and data-storage to core-proper, or...
2. Move its APIv4 interface and data-storage to core-extension.
# Comments
* Having an API to edit the strings would be meaningless if we did not have a data-store.
* There is a performance question about using MySQL for a string table. (Most FOSS applications use `gettext` MO files which are optimized for fast lookup of static strings. This is how Civi handles translation of its numerous app-strings.) In prior discussions with @BjoernE @ayduns etal, we identified this balance:
* There is a difference between *administration* (browsing/editing strings) and *runtime lookup* (substituting 1000 strings during a page-load).
* For administration, there is no question about whether the performance of a MySQL string-table would be acceptable. It would be. In fact, many different tools/workflows/stores can be acceptable.
* The performance question is relevant to *runtime lookup of heavily used strings*. The performance question is not necessarily closed, and it depends on other variables (*the #data-strings, the use-case, the hardware, etc*).
* If one does need to optimize lookup, the best known approach is to compile to gettext. To wit: Read strings from whatever source is handy, aggregate them, and [write them](https://github.com/pear/File_Gettext/blob/master/File/Gettext/MO.php) to a cache folder in `*.mo` format. (You can see [de.systopia.l10nmo](https://github.com/systopia/de.systopia.l10nmo) as a foray into this approach of blending/merging string sources.)
* I was worried about proposing this - specifically, worried that it might conflict with a more optimized dataflow. However, on reflection, I think it is complementary progress. Suppose you wanted to patch `l10nmo` to include a feed of strings provided by web-based administrators. If each web UI stored strings differently, then you'd probably give up. But if they use the same (shared/documented) string API, then it's easier to pull from there.
* (*I mention this as a hypothetical. In practice, some things like dev/mail#83 can be achieved without this level of optimization. The upshot is that we can bite off a chunk of work here on the API/storage side and make some incremental progress.*)