KirbyTags
Kirby Content Translator supports translation of KirbyTags while preserving their structure and functionality. You can configure which types of KirbyTags and which specific attributes within those tags should be translated, giving you fine-grained control over the translation process.
Usage
When the plugin encounters KirbyTags in textarea or markdown fields, it can either:
- Exclude all KirbyTags from translation (default behavior)
- Selectively translate specific attributes of configured KirbyTag types while preserving URLs, filenames, and other technical attributes
Protection is structural, not prompt-based. In textarea and markdown fields the pipeline splits tags out of the prose and replaces each with an opaque <c0/>, <c1/>, … placeholder. The strategy receives the placeholder-decorated prose plus any translatable attributes as separate units – never the raw tag. Afterwards the placeholders are rewritten into fully-formed KirbyTags from the original parse, so URLs, filenames, UUIDs, and untranslatable attributes pass through verbatim. The Panel and the PHP API share this path.
Basic Configuration
Add the kirbyTags option to your plugin configuration to enable selective translation. You can specify which KirbyTag types to translate and which attributes within those tags should be processed. Here's an example configuration:
return [
'johannschopplich.content-translator' => [
'kirbyTags' => [
'link' => ['text', 'title'], // Translate link text and title
'image' => ['alt', 'title', 'caption'], // Translate image descriptions
'file' => ['text', 'title'], // Translate download link text
'email' => ['text', 'title'], // Translate email link text
'video' => ['caption'], // Translate video captions
// Add more tag types as needed
]
]
];
Blueprint Configuration
When using the Content Translator view button or section, you can also configure KirbyTags directly in your blueprint. This allows you to define which tags and attributes should be translated per section:
type: content-translator
kirbyTags:
# Translate link text and title in `(link: ...)` KirbyTags
link:
- text
- title
# Translate image alt text and title in `(image: ...)` KirbyTags
image:
- alt
- title
- caption
# Translate file text and title in `(file: ...)` KirbyTags
file:
- text
- title
# Translate email text and title in `(email: ...)` KirbyTags
email:
- text
- title
# Translate video caption in `(video: ...)` KirbyTags
video:
- caption
Translation Example
For example, this configuration translates the text and title attributes of link tags. Other attributes, such as the URL, will remain unchanged to ensure that links continue to function correctly after translation.
The content might look like this before and after translation (from English to German):
-(link: https://example.com text: Visit our website title: To homepage)
+(link: https://example.com text: Besuchen Sie unsere Website title: Zur Startseite)
kirbyTags option is not configured, the plugin excludes all KirbyTags from translation by default. This prevents breaking existing content and ensures URLs, filenames, and other technical attributes remain intact.Keys are KirbyTag types, values are the attribute names to translate. Any attribute of any tag type works, including tags from your own plugins – text, title, alt, and caption are simply the ones that usually hold prose.
Translating the Field Value
In advanced scenarios, you may want to translate the entire value of a KirbyTag, such as a quote with both the quote text and author. To include the main value of a KirbyTag in the translation, add value to the attributes array:
return [
'johannschopplich.content-translator' => [
'kirbyTags' => [
'quote' => ['value', 'author'] // Translate both the main quote and author
]
]
];
When a Model Breaks a Placeholder
Placeholders are counted in the source and in the translation once the strategy returns. Any unit that lost or invented a <cN/> token is dropped back to its source text, and the content-translator.translate:warning hook fires with the reason placeholder count mismatch. Untranslated prose is the failure mode – never a mangled tag.
The check sits above the strategy, so it protects DeepL, AI, and any custom Strategy equally – a strategy cannot opt out of it.