Repository navigation
FormBuilder Internationalization (i18n) - #32859
Conversation
|
🤖 Thank you for contributing to CiviCRM! ❤️ We will need to test and review this PR. 👷 Introduction for new contributors...
Quick links for reviewers...
|
d319b3c to
cd2af2c
Compare
|
@samuelsov @shaneonabike after some expermentation I found that a specialized api4 entity/view was not necessary. I fixed a couple bugs in SK editable and was able to get the job done by autogenerating 1 search/displayafform per language. You'll find them in the Localization menu :) |
|
@samuelsov I just tried running the upgrader and got a few odd results
civicrm-core/ang/afform/afformSiteToken.aff.html Lines 6 to 7 in 5d7ffd1 Gets stored as
|
|
Yeah I noticed those as well @colemanw. I fixed a bunch of that on the plane home but I just have to merge it with your new things! I also caught te missing placeholders too. Thanks for your help! |
|
@shaneonabike sounds good. Since I already rebased this branch, the thing to do would be to checkout a new branch locally, delete your local |
|
@samuelsov @shaneonabike the test fail is: |
|
My bad I changed something in the definition to catch the title of the Form which is not being translated. I still need to determine how to translate the titles but they are being recorded properly. We have the following issues still to deal with
|
|
@samuelsov @shaneonabike style errors are here: https://test.civicrm.org/job/CiviCRM-Style/6325/console |
|
@samuelsov @shaneonabike @colemanw - I wanted to give a whirl and felt it would be easier on my brain with a unit-test. So I've pushed up a unit-test. It could probably use more cases (to check on attributes and defns). In the process, I noticed a bug where (eg) However, there is still one test-case that's failing on my local ( |
|
@totten ok, great! Shane and I fixed a few issues yesterday. I'm working on merging them with the change you made. |
|
I need to do a few more tests but it's seems pretty good to me. The only missing translation on a afform is the title of the form. It's populated in the |
|
Suggestion: It seems to me that these two chunks are largely the same:
In both cases, they are addressing the same complex task: take different kinds of selectors (tag-selectors, attribute-selectors, and defn-selectors) and visit every match. They differ in what they do with the match. One can see how they might've started in different places... but I think there's a way to improve. They could share the same code for walking/visiting each of the strings. For example, suppose you had /** Update $doc with translations */
function translateDoc(phpQueryObject $doc): void {
$v = new StringVisitor();
$v->visit($doc, fn($string) => _ts($string));
}
/** Search $doc and return list of strings */
function extractStrings(phpQueryObject $doc): array {
$allStrings = [];
$v = new StringVisitor();
$v->visit($doc, function(string $string) use (&$allStrings) {
$allStrings[] = $string;
return $string;
});
return $allStrings;
}
class StringVisitor {
/**
* Explore an Afform-HTML document. Run a callback on every translateable string.
*
* @param
public function visit(phpQueryObject $doc, $callback): void {
// Go through all the selectors.
// Fire $callback on each.
// Check if $callback has provided a new value.
}
}The upshot of this would be keeping the two operations closely aligned. For example...
If translation and scanning both used the same utility for visiting strings, then these kinds of discrepancies would become impossible. |
|
@totten I was thinking the same. Originally, I had setup a callback when the result was discovered, but it got complicated so we abandoned it and didn't mention that it needed work. If you suggest where I could create a new class to do this exploring I'm all ears? We would need this to be available for Searchkit in the future also b/c that would be the next iteration? |
|
After testing a bit more, there is 2 problems that I'm working on:
|
I'm not sure I see the difficulty, so I took a whirl and produced samuelsov@29be919 (Before trying that, I wanted some more test-coverage. So full proposal is https://github.com/samuelsov/civicrm-core/compare/afformi18n...totten:civicrm-core:afformi18n-consolidate?expand=1. The other big thing in that branch is splitting the TranslatorTest into separate files. This makes it easier to copy-in more complex examples.) (EDIT) Searchkit will probably need a similar scanner/filter/visitor pattern, but I think it will not be literally the same. For afform, you're using CSS-like selectors on HTML data. For SK, you're using different selector applied to JSON data. Similar... but different enough that they don't need to go through the exact same files.
Ah, yeah. I noticed something similar while taking a stab at consolidating the classes. My feeling is that To see what I mean...
|
|
@samuelsov I suspect there was a contemporaneous PR that touched the upgrader-class. Test failures are indicating a rebase would be appropriate. |
Presents messages like: foreach() argument must be of type array|object, null given via /home/totten/bknix/build/dmaster/web/sites/all/modules/civicrm/ext/afform/core/Civi/Afform/StringScanner.php:77 /home/totten/bknix/build/dmaster/web/sites/all/modules/civicrm/ext/afform/core/Civi/Afform/StringScanner.php:53 /home/totten/bknix/build/dmaster/web/sites/all/modules/civicrm/vendor/rubobaquero/phpquery/phpQuery/phpQuery.php:1089 /home/totten/bknix/build/dmaster/web/sites/all/modules/civicrm/vendor/rubobaquero/phpquery/phpQuery/phpQuery/phpQueryObject.php:2928 /home/totten/bknix/build/dmaster/web/sites/all/modules/civicrm/ext/afform/core/Civi/Afform/StringScanner.php:55 /home/totten/bknix/build/dmaster/web/sites/all/modules/civicrm/ext/afform/mock/tests/phpunit/Civi/AfformMock/MockTranslateTest.php:101
NOTE: There were a couple discrepancies between `Translator` and `StringScanner`, which
are resolved as follows:
- HTML Entities: `Translator` was performing a round of decode/encode for HTML entities,
which StringScanner did not. `Translator` cared because it was using a feed of
translations from SQL... which were _stored_ with extraneous HTML entities.
I suspect that getTranslationSources() was actually broken for handling for
any strings containing markup (*not just afform strings*). This update
should be a more general fix.
- Angular Directive Bypass: `StringScanner` would bypass anything that looked like
it included an Angular directive (`{{`). I'm not certain if it's good or bad,
but it seems reasonable enough. If we're doing it, we should consistently.
The update should apply the same bypass during both scan+translate.
I had an old copy of the `l10n` folder. This is more current - and matches what CI has.
Co-authored-by: Shane <shane@symbiotic.coop>
|
OK, the newer failure appears in the same test-class... but is actually a different thing. (It's an interaction with 4f1c71f.) For this, the test needs an update. But it's gonna be a lot easier to do that with a rebase.... |
|
Congratulations @samuelsov @shaneonabike! Great accomplishment getting this finished 🎉🍾 |
|
Thanks but you gotta open some champagne for yourself too! I appreciate that help at the sprint from both @colemanw @totten and others who helped us brainstorm, and add certain elements. @samuelsov and I are already generating a larger list of work that will need to be tackled to fully integrate this 🧨 |
Followup from civicrm#32859 this removes inline `ts()` from translatable strings as it's no longer required in the form markup.
Fixes dev/core#6207 Regression caused by translating afform strings and decoding/re-encoding `defn` objects. Instead of trying to decode everything, leave properties alone that don't need translation. See civicrm#32859 for the original change that caused this issue.
Overview
Internationalization support for FormBuilder.
Before
Translation is working if the translation is provided in core using .mo files but not for custom text.
After
Translation is possible using the
civicrm_translationtable and a newcivicrm_translation_sourcetable to store what could be translated.To test:
civicrm_translation_sourceis populated with the new stringsTechnical Details
Instead of adding
tsto.aff.htmlfile, which causes issues in the GUI, we now extract any strings from the.aff.htmlfiles that should be localizable (title, button, text...) and put them in a new tablecivicrm_translation_source.When saving an afform in the GUI, the extractor is called to save the new strings as data in
civicrm_translation_source.Using a specialized SearchKit based on a SQL view, we are able to do inline edit translations of string data in the
civicrm_translationtable. It works even if there are no translations yet in thecivicrm_translationtable.The
tsfunction will now look in thecivicrm_translationfirst and then fallback to the regular transifex mo files. This allows one to provide a default for packaged afform and yet still be able to change them.Comments
Discussed but excluded from scope (and will lead to future PRs):
civicrm_translationimpact current Message translation intended to support translations of strings from other entitiestsfrom existing afform - some needs extra change in the tags or angular