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