@shawnvogt/strapi-plugin-google-translate
Version:
Strapi plugin for automated translation of content using Google Cloud Translation
148 lines (135 loc) • 4.72 kB
JavaScript
const _ = require('lodash')
const { flatten_and_compact } = require('./lodash-helpers')
/**
* Get the field or fields to translate of a content type
*
* @param {object} data The data of the object to translate (required for arrays to skip empty props)
* @param {object} schema The schema of the content type
* @returns all attributes that can be translated
*/
async function getAllTranslatableFields(data, schema) {
const attributesSchema = _.get(schema, 'attributes', [])
const { translatedFieldTypes } = strapi.config.get('plugin.gct')
return flatten_and_compact(
await Promise.all(
Object.keys(attributesSchema).map(async (attr) => {
const fieldSchema = attributesSchema[attr]
if (fieldSchema.pluginOptions?.i18n.localized) {
return getTranslateFields(
data,
fieldSchema,
attr,
translatedFieldTypes
)
}
return null
})
)
)
}
/**
* runs the translateExclusions function if included in plugin config
*
* @param {object} data The data at the current level
* @param {object} schema The schema of the attribute or content type
* @returns orignal data object or new modified data object. function should not modify the original data object
*/
const removeTranslateExclusions = async (data, schema) => {
const { translateExclusions } = strapi.config.get('plugin.gct')
if (!translateExclusions) return data
return await translateExclusions(data, schema)
}
/**
* Get the field or fields to translate of a single attribute
*
* @param {object} data The data at the current level
* @param {object} schema The schema of the attribute
* @param {string} attr The name of the attribute
* @param {array} translatedFieldTypes The types of fields that are translated
* @returns The attribute or a list of child attributes if this attribute is a component or a dynamic zone
*/
async function getTranslateFields(data, schema, attr, translatedFieldTypes) {
const { filterFieldNames } = strapi.config.get('plugin.gct')
if (
translatedFieldTypes.includes(schema.type) &&
_.get(data, attr, undefined)
) {
const working_data = await removeTranslateExclusions(data, schema)
if (schema.type == 'component') {
return (
await recursiveComponentFieldsToTranslate(
schema,
_.get(working_data, attr, undefined),
translatedFieldTypes,
attr
)
).map((path) => `${attr}.${path}`)
} else if (schema.type == 'dynamiczone') {
return flatten_and_compact(
await Promise.all(
working_data[attr].map(async (object, index) => {
return (
await recursiveComponentFieldsToTranslate(
schema,
object,
translatedFieldTypes,
attr
)
).map((path) => `${attr}.${index}.${path}`)
})
)
)
} else {
for (let name of filterFieldNames) {
if (attr.endsWith(name)) return null
}
return attr
}
}
return null
}
/**
*
* @param {object} componentReference The schema of the component in the content-type or component (to know if it is repeated or not)
* @param {object} data The data of the component
* @param {array} translatedFieldTypes The types of fields that are translated
* @returns A list of attributes to translate for this component
*/
async function recursiveComponentFieldsToTranslate(
componentReference,
data,
translatedFieldTypes
) {
const componentSchema =
componentReference.type == 'dynamiczone'
? strapi.components[data.__component]
: strapi.components[componentReference.component]
const attributesSchema = _.get(componentSchema, 'attributes', [])
let translateFields = await Promise.all(
Object.keys(attributesSchema).map(async (attr) => {
const schema = attributesSchema[attr]
if (componentReference.repeatable) {
return flatten_and_compact(
await Promise.all(
data.map(async (_value, index) =>
getTranslateFields(
data,
schema,
`${index}.${attr}`,
translatedFieldTypes
)
)
)
)
}
return await getTranslateFields(data, schema, attr, translatedFieldTypes)
})
)
return flatten_and_compact(translateFields)
}
module.exports = {
getAllTranslatableFields,
getTranslateFields,
recursiveComponentFieldsToTranslate,
}