Follow along at

Viewing Notes

How to see this presentation

Some hotkeys:

  • Arrow keys to navigate (slide on touch devices)
  • H = highlight any code snippets
  • P = toggle speaker notes (if any)
  • F = fullscreen viewing
  • W = toggle widescreen
  • O = see an overview
  • ESC = toggles off these goodies


__()   _e()

Not so basics

_x() _ex() _n()

esc_html__() esc_html_e() esc_html_x()

esc_attr__() esc_attr_e() esc_attr_x()

The first mistake

_e IS NOT echo


  • Don’t use I18N functions on variables
  • Don’t use them as simple shortcuts
  • Do provide text domains _e(‘string’,’textdomain’)
  • Always only use static strings

About Text Domains

PROTIP: Include “Text Domain” headers

Plugin Name: Hello World
Author: Otto
Text Domain: hello-world

It works in theme’s style.css files or in plugin headers


Text Domain must match the “slug” of the plugin/theme

The second mistake

Not all languages have the same words.


What’s “SPAM” in your language?


Rule of thumb: Assume strings can double in length.

On Escaping

Shortcut functions

esc_html_e( 'stuff' );

This is identical to:

echo esc_html( __( 'stuff' ) );

All the esc_ functions that end with __, _e, or _x are shortcuts.

<a href="" title="<?php esc_attr_e('Link Title'); ?>">...

On Context

Sometimes, the same word can have different meanings.

Use the _x functions to provide context to translators.

Post, Comment, Buffalo

Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo.

_x('buffalo', 'an animal');
_x('Buffalo', 'a city in New York');
_x('buffalo', 'to bully or intimidate');

Use _ex() as a shortcut for echo _x().

Translators Comments

Use “translators” comments to explain things.

/* translators: description for a picture of a cat */
_e( 'Cat', 'plugin-slug' );

Translators comments are pulled out and put into the translation template as comments for translators to read.

Translators comments must immediately precede the code that they are talking about.

Note: “Comments” are not “context”!

WordPress I18N Tools


  • Finds all current/future I18N functions
  • Handles plugin/theme headers (and Text Domain header)
  • Finds translator comments

Plugin authors have access to the same tool on the plugin admin page.

Add Textdomain

Quick tip for people who forget to add text-domains:

php add-textdomain.php plugin-slug pluginfile.php > newpluginfile.php
  • Adds the textdomain to all your I18N calls for you.
  • Part of the official tools
  • Also accessible from plugin admin screens on

Your text domain should always be identical to your plugin or theme’s slug.


You have 5 tacos.


_e("You have $tacocount tacos.");
_e("You have " . $tacocount . " tacos.");
printf( __("You have %d tacos."), $tacocount );

Pluralization done right?

printf ( 
_n('You have %d taco.', 'You have %d tacos.', $tacocount ), 
$tacocount );

Pluralization is complicated

$number = number_format_i18n( $tacocount );
printf ( 
_n('You have %s taco.', 'You have %s tacos.', $tacocount), 




Pluralization done later



$taco_plural = _n_noop(
'You have %s taco.', 
'You have %s tacos.'

… later …

$number = number_format_i18n( $tacocount );
$string = sprintf( 
translate_nooped_plural( $taco_plural, $tacocount ), 
$number );

So much pluralization!



Enough Code Already!


Why to I18N themes and plugins?


What translators do

Translation consists, mostly, of creating POMO files.

POT file – Portable Object Template

PO file – Portable Object

MO file – Machine Object

Dealing with Translations

Managing PO/MO files is difficult.

Email is awful.

We need better ways.

An Example


Minecraft – Localized


Crowdsourced Translations


Mojang handles their translations through, a crowdsourced translation service. Other similar services exist, like

Voting system




Language Packs (in 3.7)

For themes and plugins in, appropriate language packs will automatically be installed for localized versions of WordPress.


Plugin and theme authors will be able to add PO files too (somehow).


This is kind of a big deal.

Thinking about the future

Things should be easier all around.

  • Plugin/theme authors should have tools to help them do-it-right.
  • Theme-check exists, maybe time to make plugin-check for this sort of thing.
  • Add to the official I18N tools, now that they’re in develop.svn.

Work in Progress

27,278 plugins

2,043 themes

Can we scale


Warning: If you don’t ask me things, I’ll start talking about beer.