Poedit

Пример кода, для переключения языка /home/mac/PhpProject2/index.php:

<?php

$lang = 'ru';
$locale = 'ru_RU';
$domain = 'messages'; // так должны называться файлы *.po и *.mo
$locale_path = dirname(__FILE__) . '/locale'; // папка с каталогами переводов
// Set enviroment
putenv('LC_ALL=' . $locale);
putenv('LANG=' . $locale);
putenv('LANGUAGE=' . $locale);
// Set locale
if (!setlocale(LC_ALL, $locale . '.utf8', $locale . '.utf-8', $locale . '.UTF8', $locale . '.UTF-8', $lang . '.utf-8', $lang . '.UTF-8', $lang)) {
    // Set current locale
    setlocale(LC_ALL, '');
}
// Bind domain
bindtextdomain($domain, $locale_path);
bind_textdomain_codeset($domain, 'UTF-8');
// Set default domain
textdomain($domain);

echo _("Hello world");

Теперь идем в poedit и выбираем в меню Файл \ Создать новый каталог...

screenshot

screenshot

Давим ОК, poedit спросит нас куда сохранить результат своей работы, указываем путь ./locale/ru/LC_MESSAGES/messages.po

screenshot

Если все ок, poedit пройдется по файлам исходников в поисках строк для перевода и вывалит сообщение, мол все получилось, нашел несколько строк и т.п.

Выглядит примерно вот так:

screenshot

После всего этого index.php уже должен выводить строку "Привет мир"

Как проверить текущий язык:

setlocale(LC_ALL, '0')

Простенький хелпер для этого дела:

<?php
/**
    * Helper to change current locale in all possible ways on any system
    *
    * @author mac
    */
class LocaleHelper {

    /**
        * Get Locale Name by Language Name
        *
        * @param string $lang
        * @return string
        */
    public static function getLocaleNameByLangName($lang) {
        switch ($lang) {
            case 'ru': return 'ru_RU';
            default: return 'en_US';
        }
    }

    /**
        * Set Locale to $lang
        *
        * @param string $lang
        */
    public static function setLocale($lang) {
        $locale = LocaleHelper::getLocaleNameByLangName($lang);
        if($locale == 'en_US') $lang = 'en';

        $domain = 'messages'; // так должны называться файлы *.po и *.mo
        $locale_path = dirname(__FILE__) . '/locale'; // папка с каталогами переводов
        // Set enviroment
        putenv('LC_ALL=' . $locale);
        putenv('LANG=' . $locale);
        putenv('LANGUAGE=' . $locale);
        // Set locale
        if (!setlocale(LC_ALL, $locale . '.utf8', $locale . '.utf-8', $locale . '.UTF8', $locale . '.UTF-8', $lang . '.utf-8', $lang . '.UTF-8', $lang)) {
            // Set current locale
            setlocale(LC_ALL, '');
        }
        // Bind domain
        bindtextdomain($domain, $locale_path);
        bind_textdomain_codeset($domain, 'UTF-8');
        // Set default domain
        textdomain($domain);
    }

}

Его тесты:

<?php

require_once 'PHPUnit/Framework.php';

require_once dirname(__FILE__) . '/../LocaleHelper.php';

/**
    * Test class for LocaleHelper.
    * Generated by PHPUnit on 2011-03-05 at 05:28:04.
    */
class LocaleHelperTest extends PHPUnit_Framework_TestCase {

    /**
        * @var LocaleHelper
        */
    protected $object;

    /**
        * Sets up the fixture, for example, opens a network connection.
        * This method is called before a test is executed.
        */
    protected function setUp() {
        $this->object = new LocaleHelper;
    }

    /**
        * Tears down the fixture, for example, closes a network connection.
        * This method is called after a test is executed.
        */
    protected function tearDown() {

    }

    public function testGetLocaleNameByLangNameForDefault() {
        $this->assertEquals(
                'en_US',
                LocaleHelper::getLocaleNameByLangName('not_exists')
        );
    }

    public function testGetLocaleNameByLangNameForRussian() {
        $this->assertEquals(
                'ru_RU',
                LocaleHelper::getLocaleNameByLangName('ru')
        );
    }

    public function testSetLocaleForRussian() {
        LocaleHelper::setLocale('ru');
        $this->assertEquals(
                'ru_RU.utf8',
                setlocale(LC_ALL, '0')
        );
    }

}

И пример:

<?php
require_once 'LocaleHelper.php';

LocaleHelper::setLocale($_REQUEST['lang']);
echo _("Hello world");

Касательно Wordpress'а

Для перевода плагинов, настройки poedit выглядят следующим образом:

screenshot

screenshot

screenshot

Важно, в путях должна быть точка, нужно убедиться что она сохранена. В ключевых словах надо подставить те что пользуются в Wordpress.

В самом плагиное все вызовы __ и _e должны содержать домен, например так: _e('Save', 'my_plugin');

Имя файла должно быть: my_plugin-ru_RU.mo

То есть: [имя_домена_не_плагина]-[локаль].mo

Файл должен лежать в папке плагина.

Подключается в плагине вот так:

function custom_table_example_languages() {
    load_plugin_textdomain('custom_table_example', false, dirname(plugin_basename(__FILE__)));
} add_action('init', 'custom_table_example_languages');

Ссылки по теме:

http://codex.wordpress.org/I18n_for_WordPress_Developers