Skip to content

[FEATURE]: Custom field transformations #467

@sargreal

Description

@sargreal

Is your feature request related to a problem? Please describe.
Some field types, e.g. json or other custom fields may need to be translated as well. The format of these will not be one of plain, markdown, html or blocks

Describe the solution you'd like
The solution would be, to have custom field transformations, that can be defined inside the plugin configuration.

Example of the plugin configuration format with this in mind:

  translate: {
    //...
      translatedFieldTypes: [
        "string",
        { 
          type: "json", 
          format: "plain", // format plain describes the output format of the preTransform function
          preTransform: async ({field_data, field_name, content_type, source_locale, target_locale}) => {
            // Your custom code here, in this example description is a field in the json that should be translated
            return field_data["description"];
          },
          postTransform: async ({translated_data, original_field_data, field_name, content_type, source_locale, target_locale}) => {
            // Your custom code here, in this example description is a field in the json that should be translated
            original_field_data["description"] = translated_data;
            return original_field_data;
          }
        },
        { type: "text", format: "plain" },
        { type: "richtext", format: "markdown" },
        "component",
        "dynamiczone",
      ],
      //...
    },

Specification:

type preTransformArgs<FieldType = unknown> = {
  field_data: FieldType;
  field_name: string;
  content_type: string;
  source_locale: string;
  target_locale: string;
};

type postTransformArgs<FieldType = unknown> = {
  translated_data: string | string[];
  original_field_data: FieldType;
  field_name: string;
  content_type: string;
  source_locale: string;
  target_locale: string;
};

type preTransform = <FieldType = unknown>(args: preTransformArgs<FieldType>) => Promise<string | string[]> | string | string[];
type postTransform = <FieldType = unknown>(args: postTransformArgs<FieldType>) => Promise<FieldType> | FieldType;

Implementation:

The implementation should be done inside the translate service in the function translate:

await Promise.all(
Object.keys(groupedFields).map(async (format) => {
const textsToTranslate = groupedFields[format].map(({ field }) =>
get(data, field, '')
)
const translateResult = await strapi
.plugin('translate')
.provider.translate({
text: textsToTranslate,
targetLocale,
sourceLocale,
priority,
format,
})
groupedFields[format].forEach(({ field }, index) => {
set(translatedData, field, translateResult[index])
})
})
)

Code with annotated todos:

    await Promise.all(
      Object.keys(groupedFields).map(async (format) => {
       // TODO: get the preTransform and postTransform functions from the config 
       const textsToTranslate = groupedFields[format].map(({ field }) =>
          get(data, field, '')
        )
        // TODO: apply preTransform
        const translateResult = await strapi
          .plugin('translate')
          .provider.translate({
            text: textsToTranslate,
            targetLocale,
            sourceLocale,
            priority,
            format,
          })

       // TODO: apply postTransform
        groupedFields[format].forEach(({ field }, index) => {
          set(translatedData, field, translateResult[index])
        })
      })
    )

The config needs to be updated accordingly

Describe alternatives you've considered

  • It is not feasible to include all possible formats, especially since everyone can create custom fields.
  • The transformations should not be done inside the providers, as then everyone of them would need to implement this transformation. Rather providers should have a fixed number of formats they need to support.

Additional context
This feature will fix #403

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Investigate

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions