The three files
.pot | the template — every translatable string in the theme, with no translations. Stoat ships languages/stoat.pot |
.po | your translation, as editable text. One per language |
.mo | the same translation compiled for WordPress to read. Generated from the .po |
WordPress reads the .mo. The .po is what you keep and edit.
Naming
stoat- plus the locale, exactly as WordPress spells it:
stoat-fr_FR.po stoat-fr_FR.mo
stoat-de_DE.po stoat-de_DE.mo
stoat-pt_BR.po stoat-pt_BR.mo
stoat-vi.po stoat-vi.mo
The locale is the one shown at Settings → General → Site Language; a wrong locale code is the commonest reason a finished translation does nothing.
Where to put them
wp-content/languages/themes/ — not the theme folder.
wp-content/languages/themes/stoat-fr_FR.mo <- survives updates
wp-content/themes/stoat/languages/ <- replaced on update
Files inside the theme are deleted when the theme updates. The wp-content/languages/themes/ directory is WordPress’s own, is loaded first, and is never touched.
With Poedit
- Open
wp-content/themes/stoat/languages/stoat.potin Poedit. - Create new translation, pick your language.
- Translate.
%sand%dare placeholders — keep them, and keep their order. - Save as
stoat-<locale>.poinwp-content/languages/themes/. Poedit writes the.mobeside it automatically.
With WP-CLI
wp i18n make-mo wp-content/languages/themes/stoat-fr_FR.po
Updating after a theme release
A new version usually adds strings. In Poedit: Translation → Update from POT file, pick the new stoat.pot, and the new strings appear untranslated with everything else intact.
Things that catch people out
%sand%dmust survive. Search results for: %s without the%sprints a heading with no search terms in it.- Context matters. Post the noun and Post the verb are the same English word and may need different translations; the
.potcarries a comment wherever that applies. - Keep the length close. Previous translated into something twice as long can wrap the pagination.
