Implementations
Three official implementations of TranslationStrategy are available, each targeting a different platform.
WordPress
Package: phpnomad/wordpress-integration
Delegates to WordPress's native gettext functions. This is the implementation used when PHPNomad runs as a WordPress plugin.
| Method | WordPress function |
|---|---|
translate($text) |
__($text, $domain) |
translate($text, $context) |
_x($text, $context, $domain) |
translatePlural($s, $p, $n) |
_n($s, $p, $n, $domain) |
translatePlural($s, $p, $n, $ctx) |
_nx($s, $p, $n, $ctx, $domain) |
Dependencies:
HasTextDomain— provides the plugin's text domain (e.g.,'my-plugin')
Locale is managed by WordPress's own switch_to_locale() / restore_previous_locale() globals. The strategy does not accept a locale parameter.
Translation files: WordPress uses .pot / .po / .mo files. Generate them with wp i18n make-pot and place them in your plugin's languages/ directory. For plugins on wordpress.org, community translations are loaded automatically via GlotPress.
Symfony
Package: phpnomad/symfony-translation-integration
Delegates to Symfony's TranslatorInterface. Use this for standalone PHP applications, SaaS platforms, or any context where Symfony's translation component is available.
Dependencies:
Symfony\Contracts\Translation\TranslatorInterface— the Symfony translator instanceHasTextDomain— used as the Symfony translation domainHasLanguage— provides the target locale
Context encoding: Context is encoded using gettext's \x04 (EOT) separator convention. When using Symfony's gettext catalogue loader, this is handled transparently. With other catalogue formats (XLIFF, YAML), message IDs will include the context prefix.
Pluralization: Uses Symfony's %count% parameter convention. The translator's catalogue must include plural forms using Symfony's pipe-separated syntax or ICU MessageFormat.
Native gettext
Package: phpnomad/gettext-integration
Uses PHP's built-in gettext extension (dgettext, dngettext). This is the lightest implementation — no framework dependencies, just the PHP ext-gettext extension.
Dependencies:
HasTextDomain— provides the gettext domainHasLanguage— sets locale viasetlocale(LC_MESSAGES, $locale)ext-gettext— the PHP gettext extension must be loaded
Context encoding: Uses the standard gettext \x04 (EOT) separator for msgctxt. This is compatible with .po / .mo files generated by standard gettext tools.
Translation files: Place .mo files in the standard gettext directory structure: locale/{lang}/LC_MESSAGES/{domain}.mo. Bind the domain to its directory using bindtextdomain() before using the strategy.
Choosing an Implementation
| Context | Implementation | Why |
|---|---|---|
| WordPress plugin | WordPress | Native integration with WP's translation ecosystem and GlotPress |
| Symfony/Laravel app | Symfony | Leverages existing translator configuration and catalogue management |
| Standalone PHP app | gettext | Minimal dependencies, standard Unix i18n |
| CLI tool | gettext or Symfony | Depends on whether you want catalogue management (Symfony) or simplicity (gettext) |
| Tests | Create a passthrough mock | Return the input string unchanged for predictable assertions |