Let's build i18n integration based upon http://drupal.org/node/1356978.

Here is a first plan:

1) Allow parameters to be marked to be translated, .i.e. 'translate' => 1.

2) i18n integration: Pass through all configured argument values (direct input) of translatable parameters to i18n. Apply them using an input evaluator.

3) Make an optional "language" parameter for actions (probably of type == 'language'), which is enabled if the action enables it. Options are:

  • "Default language"
  • "Current display language"
  • every enabled language

Then, this language is applied when getting argument values for all translatable parameters. If the parameter is not enabled, the action goes for "Default language" (as now).

4) Use 3) to

  • make "set a data value" apply to specific languages
  • provide an action "Get a translation" (like add a variable, but multi-lingu

Comments

fago’s picture

Component: Rules Core » Rules Engine
Status: Active » Needs work
StatusFileSize
new4.28 KB

First basic work.

Status:
1) needs docs
2) values can be translated via i18n interface. Updates need work, input evaluator and translate tab is todo.

The rest is todo too.

fago’s picture

StatusFileSize
new14.72 KB

Update:
ad 1) Added docs.
ad 2) Implemented proper update logic and the input evaluator for applying translations. Translate tab is todo.

Details:

  • I'm using i18n-contexts like rules:rules_config:rules_generate_a_profile2_label:5:message, thus I've split the i18n-property name again using a colon. That seems to work fine.
  • The update logic removes deprecated strings from removed actions. For that some trickery was required to bypass i18n caches, see rules_i18n_rules_config_update().
  • For implementing the evaluator some more context than available before was required. Thus I've improved the input evaluator API a bit in a backward-compatible way to make that possible.

Next step: Complete 2) and write tests for it. Then continue with 3).

fago’s picture

StatusFileSize
new26.44 KB

Update:
1) done
2) done. Add tests for translating lists of textual values.
3) Started. (Not included in attached patch).

Updated patch attached.

Some questions i18n folks could me help with:

  • Is it ok to go with i18n contexts that drill down even further using colons, e.g. rules:rules_config:rules_generate_a_profile2_label:5:message
  • Is there a way to make use of i18n_string_translate_list() with that somehow, e.g. translate values for rules:rules_config:rules_generate_a_profile2_label:5:values:*? If so, what has to be passed as context?
klausi’s picture

+++ b/includes/rules.processor.inc
@@ -311,6 +317,9 @@ abstract class RulesDataInputEvaluator extends RulesDataProcessor {
+   * @param $param_info
+   *   (optional) An array of information about the handled parameter value.
+   *   For backward compatibility, this parameter is not required.
    */
   abstract public function prepare($text, $variables);

$param_info should also be in the function signature. EDIT: Ooops, I should have read the comment.

+++ b/rules.api.php
@@ -96,6 +96,10 @@
+ *   - translatable: (optional) Allows translating provided argument values for
+ *     the parameter via i18n String translation. This is applicable only for
+ *     textual parameters, i.e. parameters of type 'text', 'token', 'list<text>'
+ *     and 'list<token>'.

what type is that new parameter? I guess boolean? What is the default value? I guess FALSE?

jose reyero’s picture

About questions in #3

Contexts for i18n strings can be as long as you want, though we are always splitting them in 4 four parts, so if you want to use wildcards, they must be one of the first four parts.

The general idea is the four parts are:
1. Texg group (group of strings, sometimes module name)
2. Object / object type
3. Object id
4. Object property

Like 'taxonomy:vocabulary:1:name'.

So a string context like:

"rules:rules_config:rules_generate_a_profile2_label:5:message"

Will be split into (rules, config_rules, rules_generate_a_profile2_label, 5:message)
Note the last one is "5:message"

Options:

a) Can we make it shorter? do we really need 'rules_config' ? (are there other rules' group of strings?)

b) We can group two parts together using other gluing character ('#' is used in some modules), maybe it makes sense like
"rules:rules_config:rules_generate_a_profile2_label#message:5"
or
"rules:rules_config#rules_generate_a_profile2_label:5:message"

Then we could use wildcards for

"rules:rules_config:rules_generate_a_profile2_label#message:*"

or

"rules:rules_config#rules_generate_a_profile2_label:*:message"

fago’s picture

hm, I'm already following
1. Texg group (group of strings, sometimes module name)
2. Object / object type
3. Object id
4. Object property.

However, then I cannot have multiple values for a property? Do I need to move away from that pattern to get multiple value support?

fago’s picture

Update:
1) done
2) done. Add tests for translating lists of textual values.
3) done.
4) todo.

Thus, now the send-mail action is properly translatable too, the data-selector applies translations and user-help got improved. I've implemented 3) such that translatable properties default to the current UI language if no custom translation language is made configurable, what can be done by defining a 'language' parameter. E.g. the mail-action does so.

@klausi: Thanks, I improved the docs.

TODO:

  • Improved tests:
    • Test for applying translation to data-selection
    • Tests for translating lists of text
    • Test translation using a custom translation language (mail action)
    • Test token replacements to be translated (via field translation).
  • Docs
fago’s picture

StatusFileSize
new39.14 KB

and the updated patch...

Also, I forgot to mention that the data-selection translation requires the fix from #1376126: Fix language handling for translatable fields

klausi’s picture

+++ b/rules_i18n/rules_i18n.i18n.inc
@@ -0,0 +1,94 @@
+  /**
+   * Adds in translatable properties of the given element.
+   */
+  protected function buildElementProperties($element, &$properties) {
+
+    foreach ($element->pluginParameterInfo() as $name => $info) {

This is a performance problem when clearing the cache with many default rules exported in code. The configurations are imported and saved, which triggers a rules_clear_cache(). But the next imported rule might need the plugin parameter info and rebuilds the rules cache. Then the cache is cleared upon saving of another rule and cache rebuilding starts again if the parameter info is requested.

klausi’s picture

Here is a very bad hack to avoid the cache rebuilding issue, I added this snippet to buildElementProperties():

// Hack to avoid long cache clears.
$rules_cache = drupal_static('rules_get_cache');
if (empty($rules_cache)) {
  return;
}
fago’s picture

ah, thanks klausi. We just have to exclude saves with $entity->is_rebuild == TRUE, as RulesPlugin::save() already does.

fago’s picture

StatusFileSize
new41.85 KB

ok, improved the patch to deal with the performance issue when rebuilding defaults. Needs the entity api improvement from #1458568: efficiently rebuild caches when rebuilding defaults. That way we keep rules_i18n working when deploying defaults.

fago’s picture

StatusFileSize
new48.54 KB

ok, completed the patch

make "set a data value" apply to specific languages
provide an action "Get a translation" (like add a variable, but multi-lingu

It turned out that we'd basically enhance every condition + action that has a data selector to make it language aware. That sucks and is kind of an API break though. Instead, we should enhance the data-selection widget to have its own language setting included optionally. As this is no minor task (has import/export implications, ..) this should be a separate follow-up issue.

For the meanwhile and for selecting with a dynamic-value (e.g. user preferred value) I've done a "Select a translated value" action in addition to a "Translate a text" action provided by the rules_i18n module.

Todo before we can commit this:
* Add tests for the new actions
* Fix @todo to reset wrapper language

When committed:
* add a change-notice explaining all API enhancements.
* update API docs in the handbooks
* add follow-up for language-aware data selection

fago’s picture

Status: Needs work » Needs review
fago’s picture

StatusFileSize
new50.54 KB

fixed the wrapper language @todo and added tests

fago’s picture

Status: Needs review » Fixed

added another test-case to ensure PHP code in translations is not evaluated by the PHP input evaluator + committed it! :-)

fago’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

Anonymous’s picture

Issue summary: View changes

Updated issue summary.

geek-merlin’s picture

Component: Rules Engine » Rules Core
Issue summary: View changes
Related issues: +#2209607: "Provided" text variables are always sanitized
cyper983’s picture

Status: Closed (fixed) » Needs review

15: rules_i18n.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, 15: rules_i18n.patch, failed testing.

tr’s picture

Status: Needs work » Fixed

The patch in #15 was already committed, on 12 March 2012. This issue was then marked as "Fixed" by the project maintainer.

More than two years after that, @cyper983 re-opened this issue without a comment saying why, and re-tested the patch from #15 which of course failed to apply because those changes had already been made years prior.

I don't know why this was re-opened, but it should have been left closed. I'm restoring that status now.

tr’s picture

Status: Fixed » Closed (fixed)