Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

APIv4 - Add generic setLanguage, to all APIs #24116

Closed

Conversation

eileenmcnaughton
Copy link
Contributor

@eileenmcnaughton eileenmcnaughton commented Aug 1, 2022

Overview

This updates the api contract to support setLanguage eg.

    $messageTemplate = MessageTemplate::get()
      ->addWhere('is_default', '=', 1)
      ->addWhere('workflow_name', 'IN', ['contribution_online_receipt', 'contribution_offline_receipt'])
      ->addSelect('id', 'msg_subject', 'msg_html', 'workflow_name')
      ->setLanguage('ca_FR')
      ->execute()->indexBy('workflow_name');

At a generic level this provides a way for an api consumer to specify where there is a language preference. A language preference does not mean that something usable by that language will be available - but it allows listeners, including the core Translation BAO to provide them.

If the language preference alters the api behaviour then the record should have actual_language set on it.

The language preferrence can be implemented by any hook - however, core core will implement the translation model for any entity/field combos which have been marked as translatedFields. For these fields (only MessageTemplate fields in core) the Translation BAO will add in the message template fields for msg_subject, msg_html and msg_text if translations exist.

This results in a return like the image below, where the first template has no translation and the second has one

image

Split off from #23844

Before

No way to invoke the Translation retrieval from core

After

setPreferredLanguage can be set on any api action This indicates that where possible that language should be used, allowing for both custom hooks and for core code to retrieve any existing translations.

In the core BAO_Translation code any translated fields will be swapped out with one in the preferred language, or a variant (eg. French will returned if French Canadian is preferred but only a French translation is available). If a substitution is retrieved then the actual_language property will be added to the return result

Technical Details

Note that the BAO_Translation code only kicks in when a field is defined as translatable using the translateFields hook - per
#24063 - this hook will be defined in core for ONLY the message template fields (as core will render these for sending languages) - any other fields would need to be defined in an extension, or a new discussion started

Comments

Coleman's input was
image

However - I used actual_language rather than just language which is already used in at least one table (erm the translation table)

@civibot
Copy link

civibot bot commented Aug 1, 2022

(Standard links)

* If set then listeners such as the Translation subsystem may alter
* the output.
*
* @var string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you grep for @option, then there are a couple examples like:

Civi/Api4/Generic/AbstractSaveAction.php:   * @optionsCallback getMatchFields
Civi/Api4/Generic/ExportAction.php:   * @options never,always,unmodified
Civi/Api4/Generic/ExportAction.php:   * @options never,always,unused
Civi/Api4/Action/WorkflowMessage/GetTemplateFields.php:   * @options metadata,example
Civi/Api4/Action/WorkflowMessage/Render.php:   * @options error,warning,info

So this could probably use an @optionsCallback?

@eileenmcnaughton eileenmcnaughton force-pushed the preferred_language branch 2 times, most recently from a92d8a5 to d14d0ae Compare August 2, 2022 02:35
@totten
Copy link
Member

totten commented Aug 2, 2022

For reference, I had some notes from before about different notations that could be used for requesting translation on API calls (eg setLanguage() vs chaining vs output-filters). I've copied those to a gist (https://gist.github.com/totten/ae7db562432e5feeb94d0fe3651d4c5a). This PR implements 1-SetLang with method setPreferredLanguage() and result-field actual_language.

Every item in the gist has trade-offs. The trade-offs here are:

  • Good support for IDE autocompletion
  • Short / doesn't require much boilerplate
  • setPreferredLanguage() coexists with setLanguage(). They have similar names but control different behaviors; new behavior is opt-in.
  • Result field is easy to read and has proper multiplicity. Result field is not known to APIv4-tooling and could someday/theoretically conflict.

@eileenmcnaughton eileenmcnaughton force-pushed the preferred_language branch 2 times, most recently from 47a65a5 to d618640 Compare August 3, 2022 04:06
@eileenmcnaughton eileenmcnaughton changed the title APIv4 - Add generic setPreferredLanguage, to all APIs APIv4 - Add generic setLanguage, to all APIs Aug 3, 2022
@eileenmcnaughton
Copy link
Contributor Author

Closing in the expectation we proceed with #24174

@eileenmcnaughton eileenmcnaughton deleted the preferred_language branch February 16, 2023 05:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
3 participants