Автоматическое переключение контекстов Babel по языку браузера

День добрый!
Есть сайт на два языка: ru (основной)/ en (дополнительный)
Ключи контекстов именно такие: ru, en
Задача такова:
Если человек заходит с браузером с английским языком на любую страницу, то автоматически переводить его на её копию в английском контексте.
Если он переключает язык — не мешать, переходить на основную, русскую версию.
Если с русского языка заходит — ничего автоматически не перенаправлять.

Есть вот такой код:
Но работает как-то криво, если в русском браузере тыкаться внутри английской версии, то часто выдает 404 — uri подставляет из английской, а в контекст отправляет русский.
<?php
/* Запускаем плагин только на фронтенде и с включенными sef-url */
if ($modx->context->key == 'mgr' || !$modx->getOption('friendly_urls') || $modx->event->name != 'OnHandleRequest') {
    return;
}

/* Проверяем GET-параметр cultureKey */
if (!empty($_GET['cultureKey'])) {
    switch ($_GET['cultureKey']) {
        case 'en':
            $modx->switchContext('en');
            break;
        default:
            $modx->switchContext('web');
            break;
    }

    /* Очищаем GET-параметр, чтобы не появлялся в URL */
    unset($_GET['cultureKey']);
} else {
    /* Если cultureKey не указан, проверяем язык браузера */
    $browserLang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);

    if ($browserLang === 'en') {
        $modx->switchContext('en');
    }
    /* В остальных случаях оставляем текущий контекст (обычно web) */
}
Реально ли как-то довести до ума, чтоб всё работало по-человечески?
Заранее сердешная благодарность и чем могу, тем смогу
Серый
10 сентября 2025, 19:55
modx.pro
37
0

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

Николай Савин
6 часов назад
0
Твой код верный. Должен работать. Я бы его немного вот так переделал, чтобы фильтровать GET и проверить существование заголовка HTTP_ACCEPT_LANGUAGE
<?php
  /* Запускаем плагин только на фронтенде и с включенными sef-url */
  if ($modx->context->key == 'mgr' || !$modx->getOption('friendly_urls') || $modx->event->name != 'OnHandleRequest') {
      return;
  }

HTTP_ACCEPT_LANGUAGE есть в 95% случаев, но обычно не гарантия что он обязательно будет
  /* Разрешенные контексты */
  $allowedContexts = ['en' => 'en', 'ru' => 'web'];

  /* Проверяем GET-параметр cultureKey */
  $cultureKey = filter_input(INPUT_GET, 'cultureKey', FILTER_SANITIZE_STRING);
  if (!empty($cultureKey)) {
      $targetContext = isset($allowedContexts[$cultureKey]) ? $allowedContexts[$cultureKey] : 'web';
      $modx->switchContext($targetContext);
  } else {
      /* Если cultureKey не указан, проверяем язык браузера */
      $acceptLanguage = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '';
      if (!empty($acceptLanguage)) {
          $browserLang = strtolower(substr($acceptLanguage, 0, 2));
          if ($browserLang === 'en') {
              $modx->switchContext('en');
          }
      }
      /* В остальных случаях оставляем текущий контекст */
  }
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    1