Translation of config actions

Created on 6 October 2022, almost 3 years ago
Updated 21 May 2024, about 1 year ago

Problem/Motivation

What is the current story with translations around config actions? I know that, given a correct schema, default configuration will be extracted by potx and become translatable. However, the config in config actions won't correspond to the existing config schema definitions so it won't be translatable?

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

✨ Feature request
Status

Active

Version

11.0

Component

Code

Created by

πŸ‡³πŸ‡±Netherlands kingdutch

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States thejimbirch Cape Cod, Massachusetts
  • πŸ‡ΊπŸ‡ΈUnited States bsnodgrass

    moved to Drupal Core

  • πŸ‡ͺπŸ‡ΈSpain jose reyero

    While considering configuration schema for this task, I'm thinking that will introduce a great deal of complexity and dependencies so I'm looking into some simpler options.

    This is a rough first patch presenting some alternate approach, using Symfony YAML tags to mark translatable strings in YAML files. The idea has been presented and discussed in this related thread https://www.drupal.org/project/drupal/issues/3488972#comment-15867505 ✨ Make recipes translatable Active

    This is how translatable strings would look like in yaml. Note the newly introduced '!translate' tags.

      actions:
        contact.form.feedback:
          createIfNotExists:
            label: !translate 'Website feedback'
            message: !translate 'Your message has been sent.'
            redirect: ''
    

    So far I've only added these tags for the 'feedback_contact_form' recipe, which is an interesting example because it has both 'input' and 'config/actions' translatable strings. Not sure about using them for 'input' strings but since it was easy enough...

    To manually test it, try applying the recipe with a different default language. You'll get translatable/translated strings for prompts and the newly created feedback form :
    - Apply patch
    - Enable language, locale modules
    - Set a new default language
    - Try: drush recipe core/recipes/feedback_contact_form
    - The first time you'll get English strings but they will be available for translation. Once translated they will be used when re-applying the recipe.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Have not tested but patches should be in MRs please. Also can issue summary sections be filled in

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    @jose reyero awesome to see you in this issue! And great idea.

    Given we're only using Symfony's YAML parser now the idea of using tags is viable. The thing that jumps out is what about translation context? I don't think there is a way to provide an argument to a tag unless we agree some funky character with which to split the string... wouldn't be the first time we've used such an approach in translation. Also I really wish that translation did a fallback approach to context. If it did we could add the action ID as a context to all strings and be done.

  • πŸ‡ͺπŸ‡ΈSpain jose reyero

    Hi @alexpott,

    It's actually Gabor's idea :)

    About translation context, yes, that is a hard one... Looking at how it's done in existing yaml files (module links.yml, routing.yml ...) I don't think that will work here (adding 'title_context' keys ) ... for more info see 'Translation string sharing and context' here https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Language%...

    So I'm thinking some other options - that I've tested, and are ok with the parser - let me know which one looks better, or any better idea...:

    input:
      recipient:
        data_type: email
        # Plain list, faster to write, but not that clear
        description: !translate ['The email address that should receive submissions from the feedback', 'First context']
    
        prompt:
          method: ask
          arguments:
            # Yup, tags work for nested elements ! :)
            question: !translate 
              string: 'What email address should receive website feedback?'
              context: 'Second context'
    
        # Same as previous one, just formatting it differently
        form:
          '#type': email    
          '#title': !translate { string: 'Feedback form email address', context: 'Third context' }
    

    And still we can have the original '!translate' tag with a simple string, same tag can handle all cases.,

  • πŸ‡­πŸ‡ΊHungary GΓ‘bor Hojtsy Hungary

    I like this version best :) Will post in Slack to get more feedback :)

    input:
      recipient:
        data_type: email
        # Plain list, faster to write, but not that clear
        description: !translate ['The email address that should receive submissions from the feedback', 'First context']
  • πŸ‡ͺπŸ‡ΈSpain penyaskito Seville πŸ’ƒ, Spain πŸ‡ͺπŸ‡Έ, UTC+2 πŸ‡ͺπŸ‡Ί

    So I'm thinking some other options - that I've tested, and are ok with the parser

    I was inclined for the third one because might be easier to handle from potx extraction. But if the three are feasible, I don't have an strong opinion.

    input:
      recipient:
        data_type: email
        # Plain list, faster to write, but not that clear
        description: !translate ['The email address that should receive submissions from the feedback', 'First context']
    

    What if the author wants no context?

        description: !translate ['The email address that should receive submissions from the feedback']
    

    Could that be shortcut to

        description: !translate 'The email address that should receive submissions from the feedback'
    

    ?
    Then recipe writers I assume would prefer that one.

  • πŸ‡§πŸ‡ͺBelgium svendecabooter Gent

    That looks like a great approach to add translation options to recipes.

    I don't have strong feelings regarding the exact syntax, but personally prefer the options where the parameters are named explicitly (so 2nd or 3rd).

    I'm assuming the 3rd could also be written as

       form:
          '#type': email    
          '#title': !translate { 
            string: 'Feedback form email address', 
            context: 'Third context' 
          }
    

    As it would avoid having everything on 1 line, especially with larger strings you would need to do some horizontal scrolling in your IDE.
    Come to think of it, then I probably prefer the 2nd version, as it avoids the extra brackets as well..

  • πŸ‡ͺπŸ‡ΈSpain jose reyero

    Done some patch update, the important changes:

    - Moved all tag parsing to Yaml class. This will allow reusability for things other than recipes. Still looking into simplifying this part.
    - Implemented string translation context, with the option 2/3 - named parameters -. This doesn't need to be a definitive one but I was needing some working implementation to move on...
    - Updated two other recipes for translation: core_recommended_admin_theme, core_recommended_front_end_theme
    - Handled yaml validation properly with Type(['string', Stringable::class])
    - Fixed arguments types in ConsoleInputCollector.

    About the context thing / notation:

    - Yes, when no context it can be written as a simple string: !translate 'My simple string'
    - About the option implemented I think it has some advantages: it is self documenting, looks better for potx parsing - as pointed out by @penyaskito - and allows extendability with more parameters... (plurals maybe for other usages). Anyway this context thing doesn't happen that often and it is usually needed only for very short strings.

    So just to clarify, it currently looks like:

    message: !translate {string: 'Your message has been sent.', context: 'Contact form'}
    
    description: !translate 'Just a plain string when no context is needed'
    
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    I think explicit options that match the arguments of the object is definitely the way to go. Really like the way this is going. Lovely work.

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    @jose reyero #13 didn't have the updated patch. Can we use the MR workflow? See the issue fork stuff at the bottom of the issue summary. Thanks!

  • πŸ‡ͺπŸ‡ΈSpain jose reyero

    @alexpott,
    Yes, sorry, I forgot to mention I'm using the MR workflow instead of patch files for further development.

  • @alexpott opened merge request.
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    @jose reyero I created the merge request for you - https://git.drupalcode.org/project/drupal/-/merge_requests/12121

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ
  • The Needs Review Queue Bot β†’ tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

    This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

    Consult the Drupal Contributor Guide β†’ to find step-by-step guides for working with issues.

  • Status changed to Needs work about 1 month ago
  • πŸ‡ͺπŸ‡ΈSpain jose reyero

    Fixed coding standards issues and the 'No core in component' one by moving the callback function to
    Drupal\Core\StringTranslation\YamlTagTranslator.php

    Still cannot get over this one:

    53 | WARNING | Only string literals should be passed to t() where possible
        |         | (Drupal.Semantics.FunctionT.NotLiteralString
    

    which is caused by this line we need:

    return new TranslatableMarkup($string, [], $options);

    Any idea about how to get rid of this warning?

  • πŸ‡ͺπŸ‡ΈSpain jose reyero

    Ok, fixed that issue, thx @goba @penyaskito @anjali15

    Still, working on the patch a bit more. As we talked on the chat, I'm going to trim down this feature, just translating the 'config/actions' part and leaving the 'input' outside of this scope, creating a new task for that one. On one side it's looking to me more like a different case, and we may want to use the '!translate' tag for it or not, and also there are a lot of 'input' strings in the yaml files.

    So let's focus on:
    * config/actions
    * new yaml !translate tag

    Then once we have the feature in place, we can easily use it for more strings - or not.

  • πŸ‡ͺπŸ‡ΈSpain jose reyero

    Looks like tests are passing, finally, just re-running them. This is ready for review now.

Production build 0.71.5 2024