This guide provides full details about WordPress internationalize (i18n) and WordPress Localization (l10n) WordPress plugins. It presents essential internationalization and localization principles with benefits and shows real-world examples, including detailed code analysis. No matter your WordPress experience level, you can use this guide to learn how to create multi-language plugins that anyone worldwide can understand.
Decoding i18n and l10n: Laying the Foundation
Before we dive into the technical details, let’s clarify the distinction between internationalization and localization:
- Internationalization (i18n): This method allows you to create language adaptation options that let your plugin work in various regions without additional developer input. It involves building a framework that supports multiple languages. Think of it as preparing your plugin for translation. The “18n” is a numeronym—a word formed by numbers and letters—representing the 18 letters between the “i” and the “n.”
- Localization (l10n): This is the process of adapting your plugin to a specific language, culture, and region. This includes translating text, adapting date and number formats, currency symbols, and other cultural conventions. Localization happens after internationalization. The “10n” represents the 10 letters between the “l” and the “n.”
In essence, you internationalize your plugin once and localize it multiple times—once for each language you want to support.
The Power of Multilingual Plugins: Why i18n/l10n Matters
Investing time in internationalizing your plugin offers numerous significant advantages:
- Expanded Global Reach: By supporting multiple languages, you can reach a significantly larger audience of potential users worldwide.5 This translates to more downloads, installations, and potentially higher revenue if you’re selling a premium plugin.
- Enhanced User Experience and Satisfaction: Customers prefer and better relate to plugins when they see their language presented. The translation work builds a better user experience that keeps people happy and helps them stay with the system.
- Improved Accessibility and Inclusivity: Multilingual plugins promote inclusivity by making them accessible to users who may not be proficient in English. It will broaden your user base and demonstrate a commitment to global accessibility.
- Competitive Edge in the Plugin Marketplace: Offering multilingual support can differentiate your plugin from competitors who only cater to English-speaking users. This process can be a significant advantage in a crowded marketplace.
- Increased Community Engagement and Contributions: A multilingual plugin can attract contributions from translators and community members from different language backgrounds, leading to a more vibrant and diverse community around your plugin.
The Core of i18n: Essential Functions and Practices
The core of internationalizing your WordPress plugin revolves around these key elements:
- Wrapping Text in Translation Functions: This is the cornerstone of i18n. You must wrap all user-facing text strings in special WordPress functions that mark them for translation. The most important functions are:
- __() (double underscore): This function retrieves the translated string. Use it when you need to store the translated string in a variable or use it in other functions.
- _e() (underscore e): This function echoes (displays) the translated string directly. Use it when you want to display the translated text immediately.
- _n() (underscore n): This function handles singular and plural forms of a string, which is crucial for grammatically correct translations.
- __() (double underscore): This function retrieves the translated string. Use it when you need to store the translated string in a variable or use it in other functions.
- Here are examples illustrating their usage:
/ Instead of:
echo 'Hello, world!';
// Use:
echo __( 'Hello, world!', 'my-plugin-slug' ); // Retrieves the translated string
_e( 'Welcome to my plugin!', 'my-plugin-slug' ); // Displays the translated string
$item_count = 3;
printf( _n( '%d item', '%d items', $item_count, 'my-plugin-slug' ), $item_count ); // Handles singular/plural forms
- Crucial Explanation: Text Domain: The second argument in these functions (‘my-plugin-slug’) is the text domain, a unique identifier for your plugin translations. It must match your plugin’s slug (the plugin’s folder name) to prevent conflicts with other plugins’ translations.
- Loading the Text Domain: You must tell WordPress to load your plugin’s translation files. This is done using the load_plugin_textdomain() function within the plugins_loaded action hook:
add_action( 'plugins_loaded', 'my_plugin_load_textdomain' );
function my_plugin_load_textdomain() {
load_plugin_textdomain(
'my-plugin-slug', // Your plugin's text domain
false,
dirname( plugin_basename( __FILE__ ) ) . '/languages/' // Path to the languages directory
);
}
- This code tells WordPress to look for translation files in a languages folder within your plugin’s directory.
- Generating a .pot File (Translation Template): A .pot file (Portable Object Template) serves as a template for translators. It contains all the translatable strings from your plugin. You can generate a .pot file using the wp i18n make-pot WP-CLI command or a tool like Poedit.
Using WP-CLI:
wp i18n make-pot . languages/my-plugin-slug.pot
- This command creates my-plugin-slug.pot in your languages directory.
- Creating .po and .mo Files (Translation Files): Translators use the .pot file to create .po (Portable Object) files for each target language. They then compile these .po files into .mo (Machine Object) files, which WordPress uses to display the translated text. Poedit is a popular tool for this process.6
- Organizing Your Plugin’s Files: A standard practice is to create a languages directory within your plugin’s folder to store the .pot, .po, and .mo files.
my-plugin/
├── my-plugin.php
├── includes/
│ └── functions.php
└── languages/
├── my-plugin-slug.pot
├── my-plugin-slug-es_ES.po // Spanish translation
└── my-plugin-slug-es_ES.mo
Handling Complex Scenarios: Plurals, Context, and More
- Plurals: Use the _n() function to handle singular and plural forms correctly.
- Context: Use _x() to provide context for ambiguous words that might have different translations depending on the context.
- Escaping Translated Output: Use escaping functions like esc_html__(), esc_attr__(), and esc_url__() to prevent security vulnerabilities when displaying translated text in HTML attributes, URLs, or other contexts.
Localization: Adapting to Specific Cultures
Localization goes beyond simple text translation. It involves adapting your plugin to specific cultural conventions:
- Date and Time Formats: To show dates and times in the user’s local format, use date_i18n().
- Number Formats: Use number_format_i18n() to format numbers according to the user’s locale.
- Currency Symbols: Use appropriate currency symbols and formatting based on the user’s region.
Tools and Resources for i18n/l10n
- Poedit: A popular cross-platform tool for creating and managing .po and .mo files.
- WP-CLI: The WordPress command-line interface, which includes commands for generating .pot files.
- GlotPress: A web-based translation tool used by WordPress.org and many other open-source projects.7
Example with Context:
// Without context (ambiguous):
_e( 'Post', 'my-plugin-slug' ); // Could mean a blog post or a job post
// With context (clearer):
_x( 'Post', 'noun, a blog post', 'my-plugin-slug' );
_x( 'Post', 'verb, to submit a job application', 'my-plugin-slug' );
This translator makes it clear that the meaning of “Post” is intended.
Questions and Answers:
Conclusion
Making your WordPress plugin work in multiple languages brings you an important return that boosts your market presence. By applying recommended techniques and utilizing this guide, you can build a plugin that serves users worldwide. Our efforts to improve user experience will help us attract more customers and create fresh possibilities for plugin success.
About the writer
Hassan Tahir wrote this article, drawing on his experience to clarify WordPress concepts and enhance developer understanding. Through his work, he aims to help both beginners and professionals refine their skills and tackle WordPress projects with greater confidence.