Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 216 additions & 0 deletions i18n/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
# Translating Third-Party Breakdance Elements

This guide explains how to add translation support to your custom Breakdance elements.

**Note**: This translation system requires Breakdance X.X+.

## Overview

Breakdance provides a built-in translation system that automatically translates:
- Element names
- Control labels
- Dropdown/button bar item labels
- Preset section labels
- Placeholders

Third-party developers can hook into this system to translate their custom elements.

### Understanding the Workflow

The translation workflow uses a **two-file system** to prevent overwriting manual translations:

1. **`{domain}-builder.pot`** - Generated by WP-CLI from element files (for merging only)
2. **`{domain}.pot`** - Your main POT file (includes merged element strings)
3. **`{domain}-{locale}.po/mo`** - Your actual translation files (created from main POT)

**Key Point:** The `-builder.pot` file is NOT used directly for translations. It must be merged into your main POT file first. This separation allows you to regenerate element strings without overwriting other manual translations in your plugin.

## Setup

### 1. Register Your Translations

Add this code to your plugin's main file:

```php
<?php
/**
* Plugin Name: My Custom Elements
* Text Domain: my-plugin
* Domain Path: /languages
*/

add_action( 'plugins_loaded', function() {
// Register element translations
if ( function_exists( '\\Breakdance\\I18n\\Elements\\registerElementTranslations' ) ) {
\Breakdance\I18n\Elements\registerElementTranslations(
'MyElements', // Must match your element namespace
'my-plugin' // Must match your Text Domain header
);
}

// Load translation files
load_plugin_textdomain(
'my-plugin',
false,
dirname( plugin_basename( __FILE__ ) ) . '/languages'
);
}, 10 );
```

**Important:**
- The namespace must exactly match your element slugs (e.g., `MyElements\\Button`)
- Use your main plugin text domain

### 2. Generate Element Strings

```bash
wp breakdance i18n make_pot my-plugin-slug
```

This creates `my-plugin-elements-builder.pot` with all translatable strings from your elements.

**Options:**
```bash
# Custom domain
wp breakdance i18n make_pot my-plugin --domain=my-custom-domain

# Custom output path
wp breakdance i18n make_pot my-plugin --output=/path/to/custom.pot
```

### 3. Merge with Main POT File

```bash
# Using msgcat (recommended)
msgcat --use-first \
languages/my-plugin.pot \
languages/my-plugin-elements-builder.pot \
-o languages/my-plugin.pot

# Or manually copy entries from the builder file to your main POT
```

### 4. Create Translation Files

1. Open your main `.pot` file in Poedit
2. Create a new translation (e.g., `my-plugin-fr_FR.po`)
3. Translate all strings and save (generates both `.po` and `.mo` files)

**File Structure:**
```
my-plugin/
├── my-plugin.php
├── languages/
│ ├── my-plugin.pot (Main template - merged)
│ ├── my-plugin-elements-builder.pot (Generated - for merging only)
│ ├── my-plugin-fr_FR.po (French translation)
│ └── my-plugin-fr_FR.mo (Compiled French)
└── elements/
├── MyButton/element.php
└── MyHero/element.php
```

## What Gets Translated

The translation system automatically extracts and translates:

### Element Names
```php
static function name() {
return 'My Custom Button'; // ← Will be translated
}
```

### Control Labels
```php
c( 'button_text', 'Button Text' ) // ← Second parameter translated
```

### Dropdown Items
```php
[
'type' => 'dropdown',
'items' => [
['text' => 'Option One'], // ← 'text' values translated
['text' => 'Option Two'],
]
]
```

### Button Bar Labels
```php
[
'type' => 'button_bar',
'items' => [
['label' => 'Left'], // ← 'label' values translated
['label' => 'Center'],
['label' => 'Right'],
]
]
```

### Preset Section Labels
```php
getPresetSection(
"EssentialElements\\spacing_margin_y",
"Vertical Spacing", // ← This parameter translated
"design.spacing.margin_top",
"design.spacing.margin_bottom"
)
```

### Placeholders
```php
[
'type' => 'text',
'placeholder' => 'Enter text' // ← Placeholder translated
]
```

## Translation Context

All translations use context for better translation accuracy:

- **Element names**: Context is `"Element name"`
- **Control labels**: Context is `"Control label"`
- **Item text**: Context is `"Item text"`
- **Item labels**: Context is `"Item label"`
- **Preset sections**: Context is `"Preset section label"`
- **Placeholders**: Context is `"Placeholder"`

In your `.po` file, you'll see entries like:

```
#: elements/MyButton/element.php:45
msgctxt "Control label"
msgid "Button Text"
msgstr ""
```

Use `_x()` function if you need to reference these strings in PHP:

```php
_x( 'Button Text', 'Control label', 'my-plugin-elements' );
```

## Troubleshooting

**Translations not showing:**
- Check namespace matches element slugs exactly
- Verify `.mo` files are in correct `languages/` directory
- Ensure file naming: `{textdomain}-{locale}.mo` (not `{textdomain}-builder-{locale}.mo`)
- Confirm element strings were merged into main POT file
- Clear WordPress cache
- Regenerate and merge when adding new strings

**POT generation issues:**
- Install WP-CLI or use Poedit as alternative
- Ensure element files are named `element.php`
- Check strings aren't in variables

## Resources

- [WordPress i18n Documentation](https://developer.wordpress.org/apis/handbook/internationalization/)
- [Poedit](https://poedit.net/) - Translation file editor
- [WP-CLI i18n](https://developer.wordpress.org/cli/commands/i18n/) - Official WP-CLI i18n commands
- [GlotPress](https://wordpress.org/plugins/glotpress/) - WordPress translation platform for your plugin.