Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Internationalisation for WordPress Developers

Internationalisation for WordPress Developers

In this presentation I cover the concepts and terminology of internationalisation, the three core steps needed to internationalise your WordPress plugin or theme, some best practices, and advanced considerations to make the lives of your translators easier.

Video: https://wordpress.tv/2016/05/30/john-blackbourn-internationalisation-for-wordpress-developers/

This session has been presented at:

* Global WordPress Translation Day, April 2016
* WordCamp Europe Contributor Day, June 2016
* WordCamp Brighton Contributor Day, July 2016
* WordSesh, August 2016

John Blackbourn

June 26, 2016
Tweet

More Decks by John Blackbourn

Other Decks in Technology

Transcript

  1. Internationalisation for
    WordPress Developers

    View full-size slide

  2. Best Practices for
    Internationalising
    Themes and Plugins

    View full-size slide

  3. Terminology
    Translation
    Localisation
    Internationalisation
    t9n
    l10n
    i18n

    View full-size slide

  4. Terminology
    Translation
    Localisation
    Internationalisation
    t9n
    l10n
    i18n
    18

    View full-size slide

  5. Internationalisation for
    WordPress Developers

    View full-size slide

  6. i18n for
    w7s d8s

    View full-size slide

  7. Say no to
    Concatenation
    echo $post_type . ' updated';
    echo 'You have ' . $number . ' posts';

    View full-size slide

  8. $text = 'Hello, World!';
    $text = __( 'Hello, World!', 'my-plugin' );
    Step 1:
    __() and _e()

    View full-size slide

  9. __() and _e()
    echo 'Hello, World!';
    _e( 'Hello, World!', 'my-plugin' );
    echo __( 'Hello, World!', 'my-plugin' );
    Step 1:

    View full-size slide

  10. echo 'Hello, World!';
    _e( 'Hello, World!', 'my-plugin' );
    echo __( 'Hello, World!', 'my-plugin' );
    Step 1:
    __() and _e()

    View full-size slide

  11. Loading MO Files
    Step 2:
    add_action( 'init', function() {
    load_plugin_textdomain(
    'my-plugin',
    false,
    dirname( __FILE__ ) . '/languages'
    );
    } );

    View full-size slide

  12. Loading MO Files
    Step 2:
    add_action( 'after_setup_theme', function() {
    load_theme_textdomain(
    'my-theme',
    get_template_directory() . '/languages'
    );
    } );

    View full-size slide

  13. wp-content/plugins/my-plugin/languages

    View full-size slide

  14. Localised Headers
    Step 3:
    /*
    Plugin Name: My Plugin
    Author: John Blackbourn
    Description: My excellent plugin
    Version: 1.0
    Text Domain: my-plugin
    Domain Path: /languages
    */

    View full-size slide

  15. Localised Headers
    Step 3:
    /*
    Theme Name: My Theme
    Author: John Blackbourn
    Description: My excellent theme
    Version: 1.0
    Text Domain: my-plugin
    Domain Path: /languages
    */

    View full-size slide

  16. Step 1: __() and _e()
    Step 2: Loading MO Files
    Step 3: Localised Headers

    View full-size slide

  17. Context
    _e( 'Comment', 'my-plugin' ); // A comment
    _e( 'Comment', 'my-plugin' ); // To comment

    View full-size slide

  18. Context
    _ex( 'Comment', 'noun', 'my-plugin' );
    _ex( 'Comment', 'verb', 'my-plugin' );
    via _x() and _ex()
    Kommentar / Kommentieren

    View full-size slide

  19. Context
    /* translators: column name header */
    $col = __( 'Comments', 'my-plugin' );
    via translator comments

    View full-size slide

  20. Context
    _x() and _ex()
    Used to disambiguate
    text for translation
    Translator Comments
    Used to provide further
    context for translators

    View full-size slide

  21. Formatted Strings
    $text = __( 'Hello, World!', 'my-plugin' );
    $text = __( "Hello, {$name}!", 'my-plugin' );
    No!

    View full-size slide

  22. Formatted Strings
    $text = __( 'Hello, ', 'my-plugin' );
    $text .= $name;
    $text .= __( '!', 'my-plugin' );
    No!

    View full-size slide

  23. Formatted Strings
    $text = sprintf(
    /* translators: 1: user name */
    __( 'Hello, %s!', 'my-plugin' ),
    $name
    );
    via sprintf()

    View full-size slide

  24. Numbers
    $text = __( "You have {$count} posts",
    'my-plugin' );
    No!

    View full-size slide

  25. Numbers
    $text = sprintf(
    /* translators: 1: number of posts */
    _n( '%s Post', '%s Posts', $count,
    'my-plugin' ),
    $count
    );
    via sprintf() and _n()

    View full-size slide

  26. Numbers
    if ( 1 === $deleted ) {
    $message = __( 'Theme deleted.' );
    } else {
    $message = _n(
    '%s theme deleted.',
    '%s themes deleted.',
    $deleted
    );
    }
    via sprintf() and _n()

    View full-size slide

  27. Numbers
    $label = _n_noop(
    'Image (%s)',
    'Images(%s)'
    );
    echo sprintf(
    translate_nooped_plural( $label, $count ),
    $count
    );
    via _n_noop()

    View full-size slide

  28. Punctuation
    $text = __( 'Next Post', 'my-plugin' );
    $text .= '»';
    No!

    View full-size slide

  29. Punctuation
    $text = __( 'Next Post »', 'my-plugin' );
    Better

    View full-size slide

  30. Security
    _e( 'Hello, World!', 'my-plugin' );

    View full-size slide

  31. Security
    _e( 'Hello, World!', 'my-plugin' );
    // alert("Hello!")

    View full-size slide

  32. Security
    esc_html_e( 'Hello, World!', 'my-plugin' );
    // <script>alert("Hello!")</script>

    View full-size slide

  33. Security
    esc_attr__()
    esc_html__()
    esc_attr_e()
    esc_html_e()
    esc_attr_x()
    esc_html_x()
    esc_html( __n( ... ) )

    View full-size slide

  34. HTML in Strings
    $text = sprintf(
    /* translators: 1: user name */
    __( 'Hello, %s!', 'my-plugin' ),
    $name
    );

    View full-size slide

  35. HTML in Strings
    $text = sprintf(
    /* translators: 1: user name */
    __( 'Hello, %s!', 'my-plugin' ),
    $name
    );
    Not great

    View full-size slide

  36. HTML in Strings
    $text = sprintf(
    /* translators: 1: user name */
    __( 'Hello, %s!', 'my-plugin' ),
    '' . $name . ''
    );
    Better

    View full-size slide

  37. i18n Tools
    translate.wordpress.org

    View full-size slide

  38. i18n Tools
    develop.svn.wordpress.org
    trunk -> tools -> i18n
    Poedit

    View full-size slide

  39. i18n Tools
    I18n for WordPress Developers
    More Information:
    developer.wordpress.org/plugins
    and

    View full-size slide

  40. Test Your Knowledge!
    WordPress Developers: Test your
    i18n knowledge!

    View full-size slide

  41. Internationalisation for
    WordPress Developers
    Questions!

    View full-size slide