Metatag field type is not translated — missing FieldTextExtractor plugin
### Problem/Motivation
The `ai_translate` module relies on a `FieldTextExtractor` plugin system to know how to extract translatable text from each field type. When no plugin exists for a given field type, the field is silently skipped during translation.
The `metatag` field type (provided by the [Metatag](https://www.drupal.org/project/metatag) module) has no corresponding `FieldTextExtractor` plugin, so any field of type `metatag` — typically used to store SEO metadata such as page title and description — is never included in the translation process.
The root cause is in `TextExtractor::extractTextMetadata()`:
```php
// TextExtractor.php, lines 43–49
if (!isset($this->plugins[$fieldType])) {
$this->plugins[$fieldType] = $this->extractorManager
->getExtractor($fieldType) ?? FALSE;
}
if (empty($this->plugins[$fieldType])) {
continue; // metatag fields are silently skipped here
}
```
Since no plugin handles `'metatag'` as a field type, `getExtractor('metatag')` returns `NULL`, which is stored as `FALSE`, and the field is skipped on every pass.
---
### Additional context
The `metatag` field type stores its content as a JSON-serialized blob in a single `value` column. Example:
```json
{
"title": "My page title [site:name]",
"description": "Page description for SEO.",
"og_title": "Open Graph title",
"og_description": "Open Graph description."
}
```
Not all keys inside the JSON are translatable text — for example `robots`, `canonical_url`, or structured data fields should **not** be translated. A plugin would need to deserialize the JSON, translate only the appropriate keys, and re-serialize the result.
---
### Proposed resolution
Add a new `FieldTextExtractor` plugin (e.g. `MetatagFieldExtractor`) that handles the `metatag` field type. The plugin should:
1. Deserialize the JSON value from the `value` column.
2. Extract only the text-based metatag values that are meaningful to translate (e.g. `title`, `description`, `abstract`, `og_title`, `og_description`, `og_site_name`, `twitter_cards_title`, `twitter_cards_description`).
3. Return those values in the standard `FieldTextExtractorInterface` format so the AI provider can translate them.
4. On `setValue()`, re-serialize the translated values back into JSON and write them to the field.
The plugin would be placed at:
src/Plugin/FieldTextExtractor/MetatagFieldExtractor.php
and declared with an attribute referencing the `metatag` field type:
```php
#[FieldTextExtractor(
id: "metatag",
label: new TranslatableMarkup('Metatag'),
field_types: ['metatag'],
)]
```
Note: this plugin should only be registered when the metatag module is present. This can be achieved via a service tag condition or by placing the plugin in a sub-module (e.g. ai_translate_metatag).
---
Remaining tasks
- Decide the list of metatag keys that should be considered translatable.
- Implement MetatagFieldExtractor with extract(), setValue(), and getColumns().
- Add test coverage.
- Consider whether the plugin belongs in ai_translate core (behind a module dependency check) or in a new optional sub-module.
```
```
issue