Изменение локали вручную во время выполнения?

18 апр. 2012 г., 19:56:29
Просмотры: 31.1K
Голосов: 8

Интересно, есть ли способ изменить локаль во время выполнения в WordPress?

Я имею в виду, что создал пользовательский URL для создания XML-файла с данными для интеграции с другим веб-приложением. URL также содержит языковую часть. Допустим, мой URL выглядит так:

http://example.com/custom/url/en

где последняя часть URL - английский язык. В этом случае я хочу, чтобы WordPress генерировал XML на английском языке. Но как я могу указать WordPress изменить локаль в этой точке выполнения?

Обратите внимание, что мне нужно изменить локаль, потому что я также использую системные переменные, которые переводятся, такие как __(), _e() и так далее.

1
Комментарии

возможный дубликат Изменение языка по клику на кнопку

kaiser kaiser
19 апр. 2012 г. 02:29:02
Все ответы на вопрос 3
1
16

Я пытаюсь сделать нечто подобное, и эксперты из рассылки wp-hackers (Otto, Nacin) сказали мне следующее:

Не пытайтесь изменять WPLANG, вы не можете изменить константу, определенную через define(). Вместо этого измените глобальную переменную $locale или добавьте фильтр для 'locale'.

Таким образом, лучшее решение — применить фильтр к глобальной переменной 'locale'. Единственный способ сделать это — создать собственный плагин. Если вы поместите следующий код в файл functions.php, он не будет работать корректно, так как выполнится слишком поздно в последовательности загрузки WordPress.

Ваш плагин может выглядеть так (я просто повторно использую часть с проверкой URI от OneTrickPony, вы можете заменить её на другой условный метод проверки):

<?php
/*
Plugin Name: Изменение локали во время выполнения
Plugin URI: http://wordpress.stackexchange.com/questions/49451/change-locale-at-runtime
*/

function wpsx_redefine_locale($locale) {
    // проверяем URI
        $lang = explode('/', $_SERVER['REQUEST_URI']);
        // переключаем на английский, если запрошен
        if(array_pop($lang) === 'en'){
          $locale = 'en_US';
        // в противном случае используем язык по умолчанию
        }else{
          $locale = 'gr_GR';
        }
    return $locale;
}
add_filter('locale','wpsx_redefine_locale',10);  
?>

Надеюсь, это поможет кому-нибудь!

Ещё несколько предостережений (цитата Andrew Nacin) относительно производительности при смене локали:

Возможно "переключить" локаль после загрузки локали по умолчанию, но я бы не советовал этого делать, так как это неэффективно, за исключением случая, когда ваш язык по умолчанию — английский, тогда это не так страшно.

Файлы текстового домена по умолчанию загружаются после хуков plugins_loaded и setup_theme, но до загрузки темы и до срабатывания after_setup_theme. Загрузка английского, а затем перезагрузка текстового домена в немецком на хуке init будет нормальной с точки зрения производительности, так как для английского нет mo-файлов. Но загрузка испанского по умолчанию с последующим переключением на немецкий — нет.

См. http://codex.wordpress.org/Plugin_API/Action_Reference для полезной информации о последовательности загрузки.

8 мар. 2013 г. 13:39:14
Комментарии

Убедитесь, что этот фильтр не добавлен внутри другого действия, например, в init - это слишком поздно для загрузки правильного текстового домена.

fischi fischi
9 мар. 2017 г. 15:03:56
10

Не знаю, возможно ли это реализовать в рамках плагина, из-за того что WP требует определения констант до определенного момента, но можно проверить запрашиваемый язык в wp-config.php и определить необходимую константу:

// разделяем URI
$lang = explode('/', $_SERVER['REQUEST_URI']);

// здесь меняем на английский, если запрошен
if(array_pop($lang) === 'en'){
  define('WPLANG', 'en_US');

// иначе используем язык по умолчанию
}else{
  define('WPLANG', 'gr_GR');
}
18 апр. 2012 г. 20:27:44
Комментарии

+1 И да, действительно можно переопределить константу WPLANG из плагина.

Johannes Pille Johannes Pille
18 апр. 2012 г. 20:33:21

Я расширяю свою тему через functions.php. Попробовал приведённый выше код в своём файле, но он не работает :( В любом случае спасибо, но решение пока ищу

KodeFor.Me KodeFor.Me
18 апр. 2012 г. 20:35:22

Вы пробовали добавить в wp-config? В любом случае, проверьте, определена ли там WPLANG

onetrickpony onetrickpony
18 апр. 2012 г. 20:40:31

@MerianosNikos: WPLANG должен быть в формате languagecode_КОДСТРАНЫ, например "en_US", "de_DE", "pt_BR" или подобное. В остальном вышеуказанное должно работать.

Johannes Pille Johannes Pille
18 апр. 2012 г. 20:46:41

One Trick Pony: WPLANG определен в wp-config.php, потому что основной язык моего сайта - греческий. Jahanned Pille, я пробовал и en_US, и просто en, но ничего не изменилось

KodeFor.Me KodeFor.Me
18 апр. 2012 г. 20:58:46

Вы проверяете URI только для английского языка?

onetrickpony onetrickpony
18 апр. 2012 г. 21:00:01

Английский или греческий. Установлено два языка

KodeFor.Me KodeFor.Me
18 апр. 2012 г. 21:12:05

@Merianos: Посмотрите этот pastebin для простого плагина, который должен решить проблему.

Johannes Pille Johannes Pille
18 апр. 2012 г. 21:12:51

Я тоже обновил свой код, но вам нужно заменить константу, которую вы определяете в wp-config, чтобы это работало. @Johannes: проблема с изменением языка через плагин в том, что некоторые функции локализации могут быть вызваны до того, как ваш плагин запустится. Также нет гарантии, что этот плагин будет загружен первым

onetrickpony onetrickpony
18 апр. 2012 г. 21:52:15

Не рекомендую использовать array_pop из request_uri — это очень грубая и ненадёжная практика..

T.Todua T.Todua
5 нояб. 2018 г. 11:46:15
Показать остальные 5 комментариев
0

Сначала убедитесь, что ваш желаемый языковой пакет есть в списке (под заголовком "has a language pack"). Если это так, используйте следующий код:

//установка желаемой локали
add_filter( 'locale', function($locale) {
    if ( !is_admin() ) 
        $locale = "zh_TW";
    return $locale;
});

Если вы не выбрали этот язык в панели управления WordPress, вам может потребоваться программно использовать хуки установки:

//проверяем, не установлен ли язык, затем устанавливаем
add_action('wp', 'my_locale_implemention');
function my_locale_implemention()
{
    $my_locale = get_locale();  //get_user_locale
    if ( !empty($my_locale) && !in_array( $my_locale, get_available_languages() ) ) {
        require_once( ABSPATH . 'wp-admin/includes/file.php' );
        require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
        $language = wp_download_language_pack( $my_locale );
        if ( $language ) {
            if(empty($_POST)) header("location: ".$_SERVER['REQUEST_URI']); exit; //перезагрузка страницы
        }
    }
}
4 нояб. 2018 г. 18:46:34