Declare translatable shortcode attributes

Declare shortcode text with pom_shortcode_translation_schema. POM Translate and POM AI consume this shared filter, and POM Theme derives its builder translation flags from it. Register the filter from your theme or plugin's normal bootstrap, outside editor-only hooks, so background requests see the same declaration.

add_filter(
    'pom_shortcode_translation_schema',
    static function ( array $schema ): array {
        $schema['acme_banner'] = array(
            'attributes' => array( 'heading', 'button_label' ),
            'content' => true,
            'groups' => array(
                'items' => array( 'title', 'description' ),
            ),
        );
        return $schema;
    }
);

Use lowercase tags and attribute names. Each entry supports:

Key Type Meaning
attributes String array Named attributes containing human-readable text. Defaults to an empty list.
content Boolean Whether enclosed content may contain prose or nested shortcodes. Defaults to true; set false for code, scripts, and other technical bodies.
groups Attribute-to-string-array map Text members of a URL-encoded JSON array of objects, such as a WPBakery param_group. Defaults to an empty map.

Groups are translated field by field. Both %20 and + space encoding are accepted, matching WPBakery parameter groups. Unlisted members, numeric values, booleans, object order, and nested configuration retain their values. Invalid JSON is left unchanged. Group fields appear as Shortcode group field in Translate contents. A group attribute is never translated as a complete text string.

An explicit shared declaration takes precedence over WPBakery flags. Without one, POM Translate uses available translatable flags, including flags on parameter-group children. Attributes without a declaration are preserved. Inner prose is handled separately, and vc_raw_html keeps its decoding and encoding behavior.

Existing POM Translate integrations

The following filter remains available for integrations that only need attribute declarations in POM Translate:

add_filter(
    'pom_translate_parser_translatable_shortcode_attributes',
    static function ( array $map ): array {
        $map['acme_banner'] = array( 'heading', 'button_label' );
        return $map;
    }
);

An entry in this legacy filter overrides the shared attribute list for the same tag in POM Translate only. It does not replace the shared content or groups declaration. Prefer the shared filter when both translation products should use the same rules.

For conditional attribute decisions, filter pom_translate_parser_should_extract_shortcode_attribute, which receives the default decision, tag, attribute name, and value. This applies to both the Visual Composer and ordinary-content paths. Declared groups are processed separately.

Register only attributes containing visitor-facing prose. Exclude IDs, URLs, CSS classes, colors, enum keys, query parameters, and numeric settings. Shortcode inner content is handled separately by the parser.

POM Theme supplies declarations for its modules independently of WPBakery's editor runtime. These include titles, buttons, accessible labels, form messages, listing text, and Timeline group fields. Keep other entries when adding an integration; use an empty attribute list to declare that an element contains no translatable attributes.

Save representative content after adding the registration, or use Generate pending translations → Process all. Verify nested and repeated shortcodes, single- and double-quoted rich HTML, multiline values, group text containing quotes, literal placeholder-like text, and source fallback when a translation is missing. Confirm that URLs, IDs, and configuration never appear as prose and remain valid after rendering. Moving a component or reordering group rows can change string identity; review translations after those edits.