Несколько мультиязычных сайтов в одной админке

Как реализовать переключение контекстов на нескольких доменах, но когда языки находятся в папках, а не в поддоменах.

Вот пример:
  • site1.ru/ru
  • site1.ru/en
  • site2.ru/ru
  • site2.ru/en

По ссылке bezumkin.ru/sections/tips_and_tricks/2439/ Василий даёт 2 плагина, один только для вложенных в папки языков, другой только для поддоменов.

Как можно совместить эти 2 плагина, чтобы все эти 2 сайта с 2-мя языками каждый переключались правильно?

То есть есть 2 домена, но в одной админке 4 контекста.

Это упрощённый пример. На самом деле нужно в одну админку впихнуть управление минимум 5-ю сайтами, у каждого из которых по 3 языка.

UPD
Решение изложил в отдельной статье: modx.pro/solutions/5602-several-multilingual-sites-in-one-admin-panel/
Василий Столейков
17 мая 2015, 14:47
modx.pro
1
2 895
0

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

Василий Столейков
17 мая 2015, 17:49
0
Мне нужно хотя-бы логику действий подсказать, дальше уже буду пробовать сам…
    Dmitry Rodionov
    17 мая 2015, 19:33
    +1
    а в чем проблема совместить? сначала получаем несколько контекстов с нужным http_host, а внутри них уже делаем проверку на base_url
    хотя по сути это можно было бы сделать и за один запрос, если оптимизировать код
      Dmitry Rodionov
      17 мая 2015, 19:59
      0
      по сути можно получать хост и двухбуквенный язык из url если они жестко заданы и находить по этим параметрам контекст
        Василий Столейков
        17 мая 2015, 20:00
        0
        Пример вашей логики сможете набросать, чтобы можно было проверить?
          Василий Столейков
          17 мая 2015, 20:00
          0
          Как я понял, вы хотите одним запросом это сделать?
            Dmitry Rodionov
            17 мая 2015, 20:10
            +1
            Если интересует один запрос на чистом SQL это будет как-то так:
            SELECT s1.`context_key`
            FROM `modx_context_setting` as s1
            LEFT JOIN `modx_context_setting` as s2
            ON s1.`context_key` = s2.`context_key`
            WHERE s1.`key`='cultureKey' AND s1.`value`='ru' AND s2.`key`='base_url' AND s2.`value`='/ru/'

            Но тут вопрос что удобнее, Сергей предложил более оптимальный выход — поиск по одному параметру
      Сергей Шлоков
      17 мая 2015, 19:34
      +2
      Ну логика может быть такая: у каждого контекста указываешь ключ в стиле host_language, т.е. site1_ru,site1_en.
      А в плагине разбираешь запрос и формируешь ключ контекста.
      <?php
      // Работаем только на фронтенде
      if ($modx->event->name != 'OnHandleRequest' || $modx->context->key == 'mgr') {return;}
      // Определяем запрашиваемый хост (отрезаем <b>.ru</b>)
      preg_match('/(\S+)\.ru/',$_SERVER['HTTP_HOST'],$matches);
      $host = $matches[1];
      
      //Определяем папку  /ru/ или /en/ из запроса (через preg_match или типа того)
      $lang = ...;
      //Получаем ключ контекста
      $context = $host.'_'.$lang;
      //Переключаемся.
      $modx->switchContext($context);
      А как с этим будет справляться админка и админ, это вопрос.
        Василий Столейков
        17 мая 2015, 19:38
        0
        Спасибо большое! Интересное решение!
        А как с этим будет справляться админка и админ, это вопрос.
        А в чём проблема, если назвать контексты ЧПУ-именами? Также можно для разных групп менеджеров давать доступ только к контекстам определённого сайта…
          Сергей Шлоков
          17 мая 2015, 19:44
          +1
          Проблема во внимательности. Главное не перепутать сайты, когда работаешь. :)
          Иногда от усталости при копировании с локалки на рабочий сайт ошибаешься и копируешь наоборот, а потом мучаешься, почему не работает.
          Василий Столейков
          18 мая 2015, 08:29
          0
          Что я делаю неправильно? Никак не могу добиться нормального переключения языков, то 404, то 503…
          Проверяю на такой схеме:
          - site.com/
          - - host_language = site.com_ru
          - site.com/en
          - - host_language = site.com_en
          Вот что у меня получилось в плагине:
          <?php
          // Работаем только на фронтенде
          if ($modx->event->name != 'OnHandleRequest' || $modx->context->key == 'mgr') {return;}
          
          // Определяем язык папки из URL
          preg_match('|/(.*)/|', $_SERVER['REQUEST_URI'], $m);
          $lang = $m[1];
          
          // Если папка пуста, указываем русский язык
          if(empty($lang)) $lang = 'ru';
          
          
          
          // Выбираем все существующие на сайте языки
          $q = $modx->newQuery('modContextSetting');
          $q->select('value');
          $q->where(array('key' => 'cultureKey'));
          $q->prepare();
          $q->stmt->execute();
          $langs = $q->stmt->fetchAll(PDO::FETCH_ASSOC);
          
          foreach ($langs as $l) {
              // Если папка соответствует языку, определяем нужный нам язык
              if($lang == $l['value']) {
                  $lang == $l['value'];
              }
          }
          
          
          $host_language = $_SERVER['HTTP_HOST'].'_'.$lang;   
          
          
          // Выбираем контекст с настройкой base_url
          $q = $modx->newQuery('modContextSetting', array('key' => 'host_language', 'value' => $host_language));
          $q->select('context_key');
          
          $tstart = microtime(true);
          if ($q->prepare() && $q->stmt->execute()) {
          	// Учитываем наш запрос в БД
          	$modx->queryTime += microtime(true) - $tstart;
          	$modx->executedQueries++;
          	// Получаем ключ контекста
          	if ($context = $q->stmt->fetch(PDO::FETCH_COLUMN)) {
          		// Web инициализируется в index.php - на него переключаться не нужно
          		if ($context != 'web') {
          			$modx->switchContext($context);
          		}
          	}
          }
            Сергей Шлоков
            18 мая 2015, 09:00
            0
            Чего-то ты усложнил, я проще предлагал.
            Если доступ есть, вышли на почту, попробуем вместе.
            Dmitry Rodionov
            18 мая 2015, 13:01
            0
            foreach ($langs as $l) {
                // Если папка соответствует языку, определяем нужный нам язык
                if($lang == $l['value']) {
                    $lang == $l['value'];
                }
            }
            вот эта конструкция вообще что делает?
            $lang == $l['value']; вернет true и все, да и если тут присвоение — толку тоже чуть, для чего эта конструкция и выше
            // Выбираем все существующие на сайте языки
            в данном случае достаточно одной проверки на host_language, если не найден — возвращаем первый контекст, если уж правильнее надо вернуть первый по домену, а не вернуть для несуществующего языка по домену test2.ru домен test1.ru
          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
          15