I’d like to use DeepL to translate my Laravel Post model. The problem is, their API requires that we submit a flat array of translations. E.g. our payload would be –
{
"target_lang": "ES",
"text": [
"The post title",
"A quote goes here (translatable)",
"<p>A content block goes here (translatable)</p>",
"A quote goes here",
"<p>A content block goes here (translatable)</p>"
]
}
However, my actual post uses a ‘content’ array to define blocks of content, like below:
[
{
"type": "quote",
"data": {
"name": "A quote name",
"quote": "A quote goes here (translatable)"
}
},
{
"type": "content",
"data": {
"content": "<p>A content block goes here (translatable)</p>"
}
},
{
"type": "quote",
"data": {
"name": "A quote name (not translatable)",
"quote": "A quote goes here"
}
},
{
"type": "content",
"data": {
"content": "<p>A content block goes here (translatable)</p>"
}
}
]
The data above is very flexible and changeable but always hinges on the block type. I can easily flatten the data down using something like below:
public function translatableAttributes(): array
{
return [
$this->title,
...collect($this->content)
->mapWithKeys(fn (array &$content) => match ($content['type']) {
'quote' => $content['data']['quote'],
'content' => $content['data']['content'],
})->flatten()->toArray(),
];
}
But the big issue I’m having is pushing that back into the array. I just can’t think of a way to do this while maintaining its flexibility.
I’ve thought of perhaps implementing promises and then resolving them for each key but again can’t think how to implement this.
I could make separate API calls but again this is very inefficient when I can translate 50 strings at a time in one API call.
2
Answers
I would suggest getting by with a simple array_map()
And more complex, but more flexible (if, for example, there are several fields for translation in one content; then we will need to use
foreach
in getTranslatableKeys())A body-less foreach loop with array destructuring syntax can push the desired values by dynamic keypath into the result array.
Code: (Demo) (or with a loop body)
Output: