Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Internationalization for
Plugin and Theme Developers
Sergey Biryukov
WordCamp Milano 2016
Sergey Biryukov
● WordPress Core Contributor at Yoast
yoast.com
● Co-founder of Russian WP community
ru.wordpress.org
● Po...
Plugins and Themes for the Whole World
● Internationalization (i18n) — providing the ability to translate
● Localization (...
Plugins and Themes for the Whole World
● Over 100 languages
● More robust code
● Feedback
● It’s easy
Localized Theme Directories
Localized Plugin Directories
Introduction to gettext
● Text domain
– 'my-plugin'
● Preparing the strings
– <?php echo 'Title'; ?>→<?php _e( 'Title', 'm...
Text Domain
● Should match the plugin/theme slug (folder name):
– wp-content/plugins/my-plugin→'my-plugin'
– wp-content/th...
Text Domain
● Loading the text domain
– load_plugin_textdomain( 'my-plugin', false,
dirname( plugin_basename( __FILE__ ) )...
Text Domain
● Loading the text domain
– load_plugin_textdomain( 'my-plugin', false,
dirname( plugin_basename( __FILE__ ) )...
Preparing the Strings
● Regular strings:
– __( 'Hello world!', 'my-plugin' );
– _e( 'Hello world!', 'my-plugin' );
● Strin...
Preparing the Strings
● Plural forms:
– _n( '%d item', '%d items', $count, 'my-plugin' );
– _nx( '%d item', '%d items', $c...
Preparing the Strings
● Escaping HTML tags:
– esc_html__( 'Hello <em>world</em>!', 'my-plugin' );
– esc_html_e( 'Hello <em...
Preparing the Strings
● Escaping HTML tags and attributes:
– <option value="<?php esc_attr_e( 'value', 'my-plugin' ); ?>">...
_e() ≠ echo()
● Don’t use PHP variables, only simple strings:
– _e( $string ); — don’t do that.
● Provide the ability to t...
Context and Comments
● Context — same string, different translations:
– _x( 'redirect', 'noun', 'my-plugin' );
– _x( 'redi...
Plural Forms
● ???
– _e( "You have $count items.", 'my-plugin' );
– _e( 'You have ' . $count . ' items.', 'my-plugin' );
–...
Plural Forms
● Incorrect:
– _e( "You have $count items.", 'my-plugin' );
– _e( 'You have ' . $count . ' items.', 'my-plugi...
Plural Forms
● Correct:
– printf( _n( 'You have %d item.', 'You have %d items.', $count ),
number_format_i18n( $count ) );...
Plural Forms
● If the number is not available:
– $items_plural = _n_noop( 'You have %s item.', 'You have %s items',
'my-pl...
Plural Forms
● The first form is not necessarily used for 1 item:
– printf( _n( 'Theme deleted.', '%d themes deleted.', $c...
Language Files
● .pot (Portable Object Template)
– Translation template, contains English strings only.
● .po (Portable Ob...
Language Files
makepot.php→.pot→Poedit→.po/.mo→email
Plugin Changelog
● Version 1.5.6
– Added Russian translation.
– That’s it!
● Version 1.5.6.1
– Fixed a typo in Russian tra...
Language Files
makepot.php→.pot→Poedit→.po/.mo→email
translate.wordpress.org
translate.wordpress.org
translate.wordpress.org
● GTE (General Translation Editor) — locale editors
– Can check and approve all translations.
● PT...
If Someone Has Sent You Their Translation
● Ask them to create a WordPress.org account
– They can be added as a Project Tr...
If Someone Has Sent You Their Translation
● Once the translator has a WordPress.org account:
– Go to the Polyglots team bl...
@SergeyBiryukov
Thanks! Questions?
You’ve finished this document.
Download and read it offline.
Upcoming SlideShare
i18n for Plugin and Theme Developers, WordCamp Moscow 2016
Next
Upcoming SlideShare
i18n for Plugin and Theme Developers, WordCamp Moscow 2016
Next
Download to read offline and view in fullscreen.

Share

i18n for Plugin and Theme Developers, WordCamp Milano 2016

Download to read offline

https://2016.milano.wordcamp.org/

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

i18n for Plugin and Theme Developers, WordCamp Milano 2016

  1. 1. Internationalization for Plugin and Theme Developers Sergey Biryukov WordCamp Milano 2016
  2. 2. Sergey Biryukov ● WordPress Core Contributor at Yoast yoast.com ● Co-founder of Russian WP community ru.wordpress.org ● Polyglots, Support, and Meta teams sergeybiryukov.com @SergeyBiryukov
  3. 3. Plugins and Themes for the Whole World ● Internationalization (i18n) — providing the ability to translate ● Localization (L10n) — translating to a particular language
  4. 4. Plugins and Themes for the Whole World ● Over 100 languages ● More robust code ● Feedback ● It’s easy
  5. 5. Localized Theme Directories
  6. 6. Localized Plugin Directories
  7. 7. Introduction to gettext ● Text domain – 'my-plugin' ● Preparing the strings – <?php echo 'Title'; ?>→<?php _e( 'Title', 'my-plugin' ); ?> ● Language files – .pot, .po, .mo
  8. 8. Text Domain ● Should match the plugin/theme slug (folder name): – wp-content/plugins/my-plugin→'my-plugin' – wp-content/themes/my-theme→'my-theme' ● Should be added to plugin/theme headers: – Plugin Name: My Plugin – Version: 1.0 – Text Domain: my-plugin
  9. 9. Text Domain ● Loading the text domain – load_plugin_textdomain( 'my-plugin', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); – load_theme_textdomain( 'my-theme', get_template_directory() . '/languages' );
  10. 10. Text Domain ● Loading the text domain – load_plugin_textdomain( 'my-plugin', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); – load_theme_textdomain( 'my-theme', get_template_directory() . '/languages' ); ● wp-content/languages (WordPress 4.6+)
  11. 11. Preparing the Strings ● Regular strings: – __( 'Hello world!', 'my-plugin' ); – _e( 'Hello world!', 'my-plugin' ); ● Strings with context: – _x( 'Hello world!', 'post title', 'my-plugin' ); – _ex( 'Hello world!', 'post title', 'my-plugin' );
  12. 12. Preparing the Strings ● Plural forms: – _n( '%d item', '%d items', $count, 'my-plugin' ); – _nx( '%d item', '%d items', $count, 'comments', 'my-plugin' ); ● If the number is not available yet: – _n_noop( '%d item', '%d items', 'my-plugin' ); – _nx_noop('%d item', '%d items', 'comments', 'my-plugin' );
  13. 13. Preparing the Strings ● Escaping HTML tags: – esc_html__( 'Hello <em>world</em>!', 'my-plugin' ); – esc_html_e( 'Hello <em>world</em>!', 'my-plugin' ); – esc_html_x( 'Hello <em>world</em>!', 'post title', 'my-plugin' ); ● Escaping HTML attributes: – esc_attr__( 'Hello "world"!', 'my-plugin' ); – esc_attr_e( 'Hello "world"!', 'my-plugin' ); – esc_attr_x( 'Hello "world"!', 'post title', 'my-plugin' );
  14. 14. Preparing the Strings ● Escaping HTML tags and attributes: – <option value="<?php esc_attr_e( 'value', 'my-plugin' ); ?>"> <?php esc_html_e( 'Option label', 'my-plugin' ); ?> </option> ● Same, in a longer notation: – <option value="<?php echo esc_attr( __( 'value', 'my-plugin' ) ); ?>"> <?php echo esc_html( __( 'Option label', 'my-plugin' ) ); ?> </option>
  15. 15. _e() ≠ echo() ● Don’t use PHP variables, only simple strings: – _e( $string ); — don’t do that. ● Provide the ability to translate whole phrases, not separate words: – echo __( 'Hello' ) . ' ' . __( 'world!' ); — don’t do that either. ● Don’t forget the text domain: – _e( 'Hello world!', 'my-plugin' ); ● Remove unnecessary HTML markup from the strings: – _e( '<p>Hello world!</p>', 'my-plugin' );
  16. 16. Context and Comments ● Context — same string, different translations: – _x( 'redirect', 'noun', 'my-plugin' ); – _x( 'redirect', 'verb', 'my-plugin' ); ● Comments — to explain placeholders in a string: – /* translators: %s: file name */ __( '%s was deleted.', 'my-plugin' );
  17. 17. Plural Forms ● ??? – _e( "You have $count items.", 'my-plugin' ); – _e( 'You have ' . $count . ' items.', 'my-plugin' ); – printf( __( 'You have %d items.', 'my-plugin' ), $count ); – printf( _n( 'You have %d item.', 'You have %d items.', $count ), $count );
  18. 18. Plural Forms ● Incorrect: – _e( "You have $count items.", 'my-plugin' ); – _e( 'You have ' . $count . ' items.', 'my-plugin' ); – printf( __( 'You have %d items.', 'my-plugin' ), $count ); ● Almost correct: – printf( _n( 'You have %d item.', 'You have %d items.', $count ), $count );
  19. 19. Plural Forms ● Correct: – printf( _n( 'You have %d item.', 'You have %d items.', $count ), number_format_i18n( $count ) ); ● number_format_i18n() — for displaying numbers ● date_i18n() — for displaying dates
  20. 20. Plural Forms ● If the number is not available: – $items_plural = _n_noop( 'You have %s item.', 'You have %s items', 'my-plugin' ); ● ... ● After it’s available: – printf( translate_nooped_plural( $items_plural, $count ), number_format_i18n( $count ) ); ● translate_nooped_plural() — for deferred translations of plural strings
  21. 21. Plural Forms ● The first form is not necessarily used for 1 item: – printf( _n( 'Theme deleted.', '%d themes deleted.', $count ), number_format_i18n( $count ) ); ● Better: – if ( 1 === $count ) { _e( 'Theme deleted.' ); – } else { printf( _n( '%d theme deleted.', '%d themes deleted.', $count ), number_format_i18n( $count ) ); – }
  22. 22. Language Files ● .pot (Portable Object Template) – Translation template, contains English strings only. ● .po (Portable Object) – Language file in a human-readable format. ● .mo (Machine Object) – Compiled language file in a machine-readable format.
  23. 23. Language Files makepot.php→.pot→Poedit→.po/.mo→email
  24. 24. Plugin Changelog ● Version 1.5.6 – Added Russian translation. – That’s it! ● Version 1.5.6.1 – Fixed a typo in Russian translation.
  25. 25. Language Files makepot.php→.pot→Poedit→.po/.mo→email translate.wordpress.org
  26. 26. translate.wordpress.org
  27. 27. translate.wordpress.org ● GTE (General Translation Editor) — locale editors – Can check and approve all translations. ● PTE (Project Translation Editor) — project editors – Can approve translations for a particular project. ● Translators – Can suggest translations.
  28. 28. If Someone Has Sent You Their Translation ● Ask them to create a WordPress.org account – They can be added as a Project Translation Editor. – They would be able to import the .po file themselves. – ...and continue translating in the future. ● Ask locale editors to import the files – No guarantee that the plugin will continue to be actively translated.
  29. 29. If Someone Has Sent You Their Translation ● Once the translator has a WordPress.org account: – Go to the Polyglots team blog: https://make.wordpress.org/polyglots/ – Find the Polyglots Handbook link: https://make.wordpress.org/polyglots/handbook/ – On “Theme & Plugin Directories” page, find a post template for requesting new translation editors. – Submit your request to the Polyglots blog and wait for a reply.
  30. 30. @SergeyBiryukov Thanks! Questions?
  • buzztone

    Oct. 1, 2017

https://2016.milano.wordcamp.org/

Views

Total views

1,139

On Slideshare

0

From embeds

0

Number of embeds

239

Actions

Downloads

2

Shares

0

Comments

0

Likes

1

×