[localizator] Мультиязычность, СЕО, автоперевод...



Языковые версии \ сателиты без контекстов, с автоматическим переводом всех полей ресурса + сео, да еще и автоперевод лексиконов — это я уместил в названии localizator.

Зачем я это сделал: бабeл мне ниразу не подошел, долго я держал один проект на migx «локализации», но слишком он не удобен, собрал все минусы которые успел выявить и решил их в своем компоненте.

Возможности
1. Создание псевдоконтекстов «локализации» (можно вместе работать через site.ru/en/ и ch.site.ru)


2. У ресурса есть таб, где заполняются все стандартные поля ресурса + сео, далее по нажатию кнопки это все можно перевести на другие языки, поле контента пока что поддерживает только tiny mce rte.


3. Для удобства пользования лексиконами есть отдельные таб на странице компонента, где видны только лексиконы компонента. Там же выбор языка. Тут тоже есть автоматизация перевода, одно нажатие кнопки.


Локализация pdoTools
Про работу с pdoResources и pdoMenu не забыл, вот пример:
{'!pdoMenu' | snippet : [
	'parents' => 0,
	'leftJoin' => '{
		"localizator" : {
			"class" : "localizatorContent",
			"alias" : "localizator",
			"on" : "localizator.resource_id = modResource.id"
		}
	}',
	'select' => '{ "localizator" : "modResource.*, localizator.*, modResource.id" }',
        'where' => '{ "localizator.key" : "' ~ ('localizator_key' | option) ~ '"}',
]}
Итого все поля ресурса заменяются на переведенные.

Как использовать
Все поля ресурса подменяются локализированными, кроме content, он выводится через {$_modx->resource.localizator_content}.

Настройки
Для автоматизации перевода нужен api key для яндекс переводчика, получить можно тут: translate.yandex.ru/developers/keys и указать в настройке localizator_key_yandex, так же что бы переводчик понимал с какого языка переводить нужно указать ключ локализации в localizator_default_language

Стоимость
Компонент полностью бесплатен, делал для своего проекта, думаю многим облегчит жизнь.
Отправить свое спасибо можно тут: yasobe.ru/na/localizator или попросить у меня номер карты в лс :)

Демо: localizator.but1head.ru/

Компонент отправил в modstore.pro, исходники на github.com/but1head/localizator
but1head
23 апреля 2017, 20:57
modx.pro
40
16 257
+32

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

Николай Савин
24 апреля 2017, 00:35
+1
Интересное решение. Пока не знаю где применить, но жопой чую уверен, что пригодится и не раз.
P.S. Ссылка на Git не работает.
Sem
Sem
24 апреля 2017, 08:57
0
Автору респект. Теперь мультиязычность сайтов перестанет быть головной болью, с кучей контекстов и дублей ресурсов.
Василий Столейков
24 апреля 2017, 09:35
+1
Круто получилось!
И никаких плагинов, контекстов и дополнительных настроек!
Владимир
24 апреля 2017, 10:28
0
Круто, не терпится попробовать, а на github.com/but1head/localizator — 404
but1head
24 апреля 2017, 12:47
+2
Залил на github
    Владимир
    24 апреля 2017, 13:17
    0
    Спасибо! И вопрос, если не сильно отвлекаю, на рабочий сайт ставить можно?
    PS По описанию это похоже на Lingua (там тоже поля документа создаются для каждого языка. Очень интересно попробовать и сравнить, и да, сателлиты как раз делаю прямо сейчас, до чего же кстати, если все поойдет)
      but1head
      24 апреля 2017, 13:22
      +1
      Уже вижу «A MODX's Lexicon switcher for front-end interface.», у меня одной из задач было уйти от лексиконов.
      По поводу полей — создаются только pagetitle, longtitle, menutitle, introtext, description, content, seotitle, keywords, и подменяются если нужно. В настройках можно задать только перевод определенных полей.

      Демо вполне рабочее, только там pdoTools не понимает что главная в /en/ это не / (ссылка), пока не знаю как его обучить, руками в чанке можно поправить.

      На боевой проект в теории можно, я пока перестраиваю свой проект на эту связку.
        Владимир
        24 апреля 2017, 14:05
        0
        кстати, в Lingua
        Lexicon switcher
        — это не связано с лексиконами MODX, просто переключает поля в документе в соответствии с выбранным с фронтенда языком.
        Даже для минишопа пробовал — было «почти» хорошо.
          but1head
          25 апреля 2017, 12:52
          +5
          Перевел dev версию своего проекта, пока полет нормальный. На 11 языков правда долго переводит :)
          Думаю добавлю в компонент кнопку «перевести все» и чтоб крон обратабывал.



          Скорость загрузки идентична на всех языках, кэш работает для каждой версии.
          Разницы в скорости без и с локализатором не заметил.
            Владимир
            25 апреля 2017, 12:55
            +2
            «перевести все» и чтоб крон обратабывал
            отличная идея!
            Владимир
            28 апреля 2017, 12:48
            0
            Компонент отправил в modstore.pro
            — что-то долго не появляется. Будет ли доступен в modstore.pro?
              but1head
              28 апреля 2017, 18:25
              +1
              Давно уже отправил, modstore видимо уехали в Алматы на встречу
        Игорь Терентьев
        25 июня 2017, 16:57
        0
        Как правильно прописать base href="{$_modx->config.site_url}" для такого варианта s9732.h8.modhost.pro/en/?
        Сейчас у меня там выводится только домен.
Алексей Федоров
24 апреля 2017, 15:10
0
баг с ссылкой на главную, всегда кидает на «голый домен»
В случае поддомена — нет проблемы, а с «папочными» вариантами скидывает на оригинальный язык
P.S.: Видел для мультиязычности на MODX проект SLI (github), но обновлялся годы назад, плюс идет поверх системы, поэтому экспериментировать с ним не решился. Нативное решение очень радует). Отключенный перевод контента — это супер))
Николай Загумённов
25 апреля 2017, 00:28
+1
Афигенно! =) Очень часто делал мультиязычные сайты, на 3-4 языках. Это просто идеальное решение, без контекстов! Спасибо автору!
Константин Ильин
25 апреля 2017, 13:27
0
Однако опередил) Пишу такой же компонент…
but1head
29 апреля 2017, 16:08
+1
modstore.pro/packages/utilities/localizator Пакет в модстор
Ishvan
29 апреля 2017, 19:09
0
есть сайт site.ru и есть сайт site.com так будет расширение работать?
    but1head
    30 апреля 2017, 00:26
    +1
    Я даже не знаю как ответить на этот вопрос.
    Делаете 2 псевдоконтекста и все.
Артём
01 мая 2017, 11:55
0
спасибо… компонент то что нужно! спасибо
Oleh
08 мая 2017, 11:37
0
Спасибо. Про babel можно смело забыть.
Владимир
10 мая 2017, 22:10
0
Вообще не понял где брать все эти ключи локализаций…
попробовал что то сделать, нажимаю автоматический перевод пишет «Для автоматического перевода необходимо добавить хотя бы одну запись в таблицу»…
Что писать в localizator_default_language, ru Russian или Ru ???
Чот скудная документация, извините мозги после годовой работы без выходных не пашут, но хотелось бы поподробней информативней как то…
    Viktor
    11 июня 2017, 19:41
    0
    тоже долго ковырялся пока не перепробовал все варианты
    попробовал что то сделать, нажимаю автоматический перевод пишет «Для автоматического перевода необходимо добавить хотя бы одну запись в таблицу»…
    нужно на странице локализатора добавить основной язык (допустим русский) + те, на которые нужно перевести (допустим украинский) и прописать http hosts
    Что писать в localizator_default_language, ru Russian или Ru ???
    ru

    после всего этого нужно на странице ресурса во вкладке локализации (почему не во вкладке «документ» — не знаю) создать «перевод» (еще одна странность вытекающая из первой, так как это не перевод, а основной текст) и заполнить все поля на основном языке, после этого уже можно жать на автоперевод

    вопрос создателю: будет ли в будущем возможность перевода любых полей, тв параметров, минишоповских и т.п.?

    спасибо за компонент!
serbeh
17 мая 2017, 12:20
0
Восстановите, пожалуйста, демо-сайт.
    but1head
    23 мая 2017, 15:15
    0
    Ввиду того что компонент бесплатный, а хостинг нет, я удалил демку.
    Если кто-нибудь задонатит yasobe.ru/na/localizator то демка чудом оживет.
      but1head
      23 мая 2017, 16:47
      0
      Чудо произошло! Скоро верну демку.
      Дмитрий
      24 мая 2017, 16:09
      0
      А можно еще одну, совсем уж нагловатую просьбу?)
      Можешь запилить исходники демо-сайта, я имею в виду элементы, тоже на GitHub? Я что-то не хочу быдлокодить, но в упор не понимаю, как можно сделать ссылки в меню. А так залез и смотришь, все что хочешь
Дмитрий Храмов
22 мая 2017, 14:47
0
yadi.sk/d/VxBlpjwk3JQG2Z
Не знаете почему вот так всё? Без подписей, надписей?
    but1head
    23 мая 2017, 00:49
    0
    Попробуйте переустановить
      Дмитрий Храмов
      23 мая 2017, 20:09
      0
      Ошибка была в том, что по умолчанию язык панели — английский у меня был. Ваш компонент имеет только русскую локализацию — очень неудобно для иностранных разработчиков
        but1head
        23 мая 2017, 23:29
        +1
        Не делал перевод кроме русского, можете добавить на гитхаб.
          Иван Бочкарев
          21 апреля 2019, 10:57
          0
          Добавил перевод на Английский и Французский языки.
Дмитрий
23 мая 2017, 01:28
0
Чото я не догнал немного, как включить эту прелесть…
Контексты нужно создавать?
Можно в паре предложений маленький «fast start»?
    but1head
    23 мая 2017, 01:52
    1
    +1
    1) создаем локализации (псевдоконтексты)

    2) в настройке localizator_default_language указываем ключ основной локализации (у меня это ru, на скрине pt)
    3) в настройке localizator_key_yandex указываем апи ключ яндекса, translate.yandex.ru/developers/keys

    Конец.
    Контент указывается в табе ресурса.
      Дмитрий
      23 мая 2017, 02:22
      0
      Хм, вроде все так и делал. Не хочет на sitename.com/en/ контент отображать, 404 отдает. хоть и настроил вроде все, и перевод ресурса сделал… Ладно, завтра еще попробую. Спасибо!
      Дмитрий
      23 мая 2017, 11:55
      0
      Можно еще подсказку?
      1. Вот главная страница. К ней сделана локализация во вкладке.

      2. Вот настройки модуля

      3. Вот системные настройки


      И в итоге — перехожу по адресу sitename.com/en/ — получаю 404.
      Где я что пропустил?
        but1head
        23 мая 2017, 14:10
        0
        Пришли доступы modx.pro/users/but1head/, не помню как там через /en/ делать
          but1head
          23 мая 2017, 16:09
          +1
          ****/en/ слэша вконце не хватало
Кирилл
23 мая 2017, 17:44
0
Отличное расширение! Решил проверить вместе с minishop2. Локализация срабатывает частично http://i.imgur.com/v6ev1X4.png
Пробовал подгружать через {$_modx->lexicon->load('minishop2:default')} — разницы нет.
    but1head
    23 мая 2017, 18:29
    +1
    Локализатор грузит свои словари вот так:
    $modx->lexicon->load($cultureKey . ':localizator:site');
    Следовательно вам надо (возможно синтаксис не правильный)
    {$_modx->lexicon->load(('cultureKey' | option) ~ ':minishop2:default')}
    или в плагине\сниппете
    $modx->lexicon->load($modx->cultureKey . ':minishop2:default');
    А вообще должно было «само», но видимо минишоп грузит словари раньше чем локализатор подменит язык.
      Кирилл
      23 мая 2017, 18:37
      0
      Спасибо! Синтаксис правильный.
Дмитрий Храмов
24 мая 2017, 18:25
0
Можно ли пользоваться для локализации товаров в minishop2?
Пока чтото не особо выходит(
    but1head
    24 мая 2017, 18:27
    0
    Выше спрашивали про ms2, что у вас не выходит?
    Теги товаров \ тв параметры не получится, только костылями
      Дмитрий Храмов
      24 мая 2017, 18:35
      0
      названия товаров, метатеги, название опций.
      вообще запутался, может посмотрите доступ в админку дам, отблагодарю
        but1head
        24 мая 2017, 18:37
        +1
        Все инструкции в посте есть, в комментариях тоже
Евгений Webinmd
28 мая 2017, 11:28
0
Есть небольшой вопрос — уточнение.
Есть 2 языка RU EN
Создал два псевдоконтекста, во вкладке Локализация при добавлении перевода можно выбрать эти оба.
То есть получается что, чтобы создать ресурс с переводом, необходимо заполнить 3 вкладки?
1* Основная (там что в основной вкладке Документ)
2* RU
3* EN

Я правильно понял или есть какие-то тонкости?
    but1head
    28 мая 2017, 16:49
    0
    У ресурса вам надо заполнить только pagetitle, далее основную локализацию т.е. RU. Потом нажать «автоматический перевод» и переведется на EN. Все.
Дмитрий Храмов
30 мая 2017, 16:01
-2
Плагин не работает. Всё сделал по инструкции. Автор попросил 10к за локализацию простенького сайта с тремя товарами из минишопа. Гори в аду, аффтар!
    but1head
    30 мая 2017, 16:01
    +2
    Ты болен, Дима.
      Дмитрий Храмов
      30 мая 2017, 16:08
      -2
      да тебе говоришь, ты не понимаешь. за 5 минут бы помог бы, отблагодарил бы, тебе это 5 минут ровно стоит
Murashkin
02 июня 2017, 16:28
0
Здравствуйте. Подскажите, подойдет ли данное решениедля моего проекта. Будет сайт на 5 регионов на поддоменах типа site.ru, kazan.site.ru, spb.site.ru, nn.site.ru, ekb.site.ru. Все поддомены реализованы в одной админке на контекстах.
И у каждого такого сайта 2 языка будет. На контекстах уже не получится, насколько я понимаю, т.к. их функции заняты. Ваше решение, кажется, то, что нужно. Только еще 2 моментна не понял:
1)может ли одна страница быть на 2х языках, но иметь разный темплейт?
2)не очень понял про автоматический перевод. Обязательно ли его подключать и использовать? Можно ли заполнять pagetitle, longtitle и т.п. вручную? Потому что в будущем, возможно, будет китайский язык добавлен, и нет уверенности, что яндекс переводчик нормально переведет.
    but1head
    02 июня 2017, 16:40
    +1
    Подойдет, возможно нужно будет переписать плагин, но если сделали свитч на контекстах тут тоже разберетесь.
    1) Да, в плагине можно проверять $modx->localizator_key и от него менять шаблон, смотрите плагин
    2) Можно вручную

    Свои контексты можете удалять (хотя локализатор для одного контента сделан, т.е. разделение новостей не предусмотрено, с другой стороны если новость не переведена на псевдоконтекст то она не выводится и выдает 404).

    Псевдоконтексты вам нужны такие:
    http_host: site.ru, ключ языка: ru
    http_host: site.ru/en/, ключ языка: en
    http_host: spb.site.ru, ключ языка: ru
    http_host: spb.site.ru/en/, ключ языка: en
    и т.д., или en.spb.site.ru…

      Murashkin
      02 июня 2017, 16:49
      0
      спасибо, попробую разобраться
        Aleksandr Huz
        19 июня 2017, 17:05
        0
        У Вас получилось разобраться?
          Murashkin
          19 июня 2017, 17:13
          0
          Не пробовал пока, проект еще в процессе прототипирования
serbeh
14 июня 2017, 20:53
0
Расскажите, пожалуйста, где можно подробнее почитать про пространства имён, темы и т.д. в лексиконах?
У меня настроен Localizator на два языка( RU — domain.com, EN — domain.com/en/)
Столкнулся с такой проблемой, что при работе с mFilter2 и с выводом списка результатов с ajax кнопкой первая выборка нормально переводится, а после нажатия кнопки «Загрузить ещё» элементы подгружаются не с соответствующими переводами, а просто с плейсхолдерами. И на английской версии сайта(domain.com/en/), если выводить значение {$_modx->config.cultureKey}, то на «первых» результатах правильно выводится «en», а на подгруженных ajax'ом выводится «ru». Видимо при ajax запросе нужно как-то пробрасывать правильный cutureKey, вот только никак не могу понять как и куда…
    but1head
    14 июня 2017, 20:57
    0
    как вариант ставить куку lang=en, писать плагин на onhandlerequest где переключать язык на язык из куки. пока что локализатор под msearch2 не подстраивал.

    логика такая, только тут еще запрос именно msearch2 бы выловить.
    <?php
    if($modx->event->name != 'OnHandleRequest') return;
    $lang = $_COOKIE['lang'];
    if(!$lang) return;
    $modx->setOption('cultureKey', $lang);
      serbeh
      14 июня 2017, 21:00
      0
      Спасибо, сейчас попробую!
        Игорь Терентьев
        24 июня 2017, 01:18
        0
        Ну как, получилось? С такой же проблемой столкнулся.
    serbeh
    14 июня 2017, 21:00
    0
    И ещё вспомнил: в domain.com/en/ не выводятся записи из словаря, который заполняется на странице дополнения Localizator, тоже плейсхолдеры. Проверил на слове из словаря в пространстве имён «mSearch2» — выводится перевод. (Это тоже при выводе mFilter2) Везде, кроме mFilter2 — норм.
    Получается и пространство имён нужно как-то подгружать с ajax'ом?
Juli
16 июня 2017, 16:39
1
0
Добрый день.
Установила компонент, в настройкак localizator_default_language указала, API ключ яндекс добавила, В Ресурсах Локализацию сделала, но заполненные поля не подтягиваются, надо все вручною, исходя из прочитанного понямаю что должно вроде подтягиваться, в настройках также попыталась указать названия дополнительных полей, чтоб они тоже переводились, но на сайт ничего не выводится. Через en.sitename.com выводит изначальный русский текст, а через sitename.com/en/ выводит ошибку 404
Если добавить вызовы в чанки, как у вас в изходниках как github, ничего не генерируется код остается кодом.
Подскажите плиз в чем ошибка и куда копать.
    but1head
    17 июня 2017, 14:48
    0
    В вашем случае надо:
    2 «контекста», ru и en. localizator_default_language = ru. У ресурса заполняется ru, нажимаете авто-перевод — получаете en. Смотрите в лог ошибок, там все должно быть написано. Возможно ключ заблокирован (не дает больше 1кк переводить в сутки). Если уж совсем все плохо контакты в профиле.
Aleksandr Huz
17 июня 2017, 11:35
0
Никита, привет!
Подскажи, пожалуйста, как вывести pdomenu, чтобы срабатывала локализация, без использования fenom?
    but1head
    17 июня 2017, 14:46
    0
    В шапке указан пример, переписать все на родной синтаксис, ('localizator_key' | option) заменить на [[++localizator_key]], должно сработать. А лучше включить феном.
Aleksandr Huz
17 июня 2017, 15:06
0
Пишу вот так, ничего не выводиться. Подскажи, пожалуйста, где ошибки?

&leftJoin = `{
        	"localizator" : {
        		"class" : "localizatorContent",
        		"alias" : "localizator",
        		"on" : "[[*localizator.resource_id]] = [[*id]]"
        	}
        }`
	&select = `{ "localizator" : "modResource.*, localizator.*, [[*id]]" }`
        &where = `{ "[[*localizator.key"]]: "' ~ [[++localizator_key]] ~ '"}`
    Володя
    17 июня 2017, 16:28
    0
    задайте параметр
    &showLog=`1`
    и посмотрите в чем дело. Предполагаю что вот это точно криво
    "on" : "[[*localizator.resource_id]] = [[*id]]"
      Aleksandr Huz
      18 июня 2017, 11:02
      0
      Владимир, добрый день!

      Вызываю так:
      &leftJoin = `{
          		"localizator" : {
          			"class" : "localizatorContent",
          			"alias" : "localizator",
          			"on" : "localizator.resource_id = modResource.id"
          		}
      	    }`
      	    &select = `{ "localizator" : "modResource.*, localizator.*, modResource.id" }`
              &where = `{ "localizator.key" : "[[++localizator_key]]"}`
      Лог:
      "0.0027568: pdoTools loaded
      0.0000181: xPDO query object created
      0.0001328: leftJoined localizatorContent as localizator
      0.0000141: Added selection of localizatorContent: SQL_CALC_FOUND_ROWS modResource.*, localizator.*, modResource.id
      0.0000219: Processed additional conditions
      0.0002921: Added where condition: localizator.key=, modResource.parent:IN(0), OR:modResource.id:IN(0), modResource.published=1, modResource.hidemenu=0, modResource.deleted=0, modResource.context_key=web
      0.0000482: Sorted by modResource.menuindex, ASC
      0.0001478: SQL prepared "SELECT SQL_CALC_FOUND_ROWS modResource.*, localizator.*, modResource.id FROM `buffalo_modxsite_content` AS `modResource` LEFT JOIN `buffalo_modxlocalizator_content` `localizator` ON localizator.resource_id = modResource.id WHERE  ( `localizator`.`key` = '' AND  ( `modResource`.`parent` IN (0) OR `modResource`.`id` IN (0) )  AND `modResource`.`published` = 1 AND `modResource`.`hidemenu` = 0 AND `modResource`.`deleted` = 0 AND `modResource`.`context_key` = 'web' )  ORDER BY modResource.menuindex ASC "
      0.0007360: SQL executed
      0.0000601: Total rows: 0
      0.0000081: Rows fetched
      0.0000060: Returning raw data
      0.0000021: Tree was built
      0.0043030: Total time
      6 291 456: Memory usage

      localizator_key ничего не выводит, заменил на cultureKey, для других языков меню выводит, а вот для ru пусто.
        Дмитрий
        18 июня 2017, 15:58
        0
        А вы перевод-то страницы создали?
          Aleksandr Huz
          19 июня 2017, 15:21
          0
          для всех страниц создал переводы.
            Дмитрий
            19 июня 2017, 15:25
            0
            А вы выбираете страницы в том же языке, для которого создан перевод?
              Aleksandr Huz
              19 июня 2017, 17:13
              0
              Дмитрий,
              ситуация такая, что есть 2 контекста для регионов.
              site.ru
              site.ru/region/
              Переключение контекстов сделано по плагину Безумкина bezumkin.ru/sections/tips_and_tricks/2439/

              Настройка локализации
                but1head
                19 июня 2017, 17:15
                +1
                Господи иисусе. Локализатор замена контекстам, вы еще babel поставьте, чтоб наверняка.
                  Aleksandr Huz
                  19 июня 2017, 17:56
                  0
                  Как локализатор можно использовать, если у тебя для другого региона другая инфа, и она заполнена в migx и tv?
                    but1head
                    19 июня 2017, 18:25
                    +1
                    Написать мини сниппет который распарсит json из tv и покажет то что надо.
    but1head
    17 июня 2017, 16:31
    0
    Как-то так
    &leftJoin = `{
    		"localizator" : {
    			"class" : "localizatorContent",
    			"alias" : "localizator",
    			"on" : "localizator.resource_id = modResource.id"
    		}
    	}`
    	&select = `{ "localizator" : "modResource.*, localizator.*, modResource.id" }`
            &where' = `{ "localizator.key" : "[[++localizator_key]]"}`
    ]}
      Aleksandr Huz
      18 июня 2017, 10:29
      0
      У меня только так сработало:
      &leftJoin = `{
          		"localizator" : {
          			"class" : "localizatorContent",
          			"alias" : "localizator",
          			"on" : "localizator.resource_id = modResource.id"
          		}
      	    }`
      	    [[++cultureKey:ne=`ru`:then=`
      		&select = `{ "localizator" : "modResource.*, localizator.*, modResource.id" }`
      		&where = `{ "localizator.key" : "[[++cultureKey]]"}`
      	   `]]
      [[++localizator_key]] - ничего не выводит
Rootiys
23 июня 2017, 19:14
0
С tv не работает?
    but1head
    23 июня 2017, 19:37
    +1
    Нет, но чуть-чуть магии и плагинов решат любую задачу
      Rootiys
      23 июня 2017, 19:39
      0
      Знаний не хватает(
      Алексей П
      04 июля 2017, 22:39
      +1
      А можно схематично описать как с помощью «магии» можно сделать перевод для tv параметров? Нужно расширять таблицу локализатора? Перевод ведь должен где-то храниться. Или предполагается, что он будет делаться на лету?
Bor
Bor
25 июня 2017, 16:18
0
Друзья, поясните, как в итоге выводить контент и как настроить pdomenu))
Для контента нашел: {$_modx->resource.localizator_content}, но не понимаю, как это использовать))
пока получилось только вывести pagetitle.
Дополнение крутое.
    Алексей П
    26 июня 2017, 23:26
    0
    Тоже не мог вывести контент. Оказалось вся проблема из-за визуального редактора. У меня стоял ckeditor. И содержимое поля просто не сохранялось.
    С tinymce работает.
      Bor
      Bor
      26 июня 2017, 23:32
      0
      А контент в итоге нужно выводить так — [[*content]], в локализованной версии?
        Алексей П
        26 июня 2017, 23:37
        +1
        Нет.
        {$_modx->resource.localizator_content}
        Вот так.
        Проверь, еще должен быть включен fenom для обработки страниц (системные настройки / pdotools)
          Bor
          Bor
          26 июня 2017, 23:41
          0
          Спасибо, заработало!
Алексей П
02 июля 2017, 14:12
0
У меня вопрос по поводу локализации на поддомене.
Создал на хостинге поддомен. В настройках локализатора создал два псевдоконтекста
site.ru
en.site.ru
Перехожу на en.site.ru выдает 500 ошибку
Если делать через папку /en/ все работает
Как корректно настроить работу через поддомен?
    but1head
    02 июля 2017, 16:56
    0
    Что в логах?

    Можете прислать доступ, гляну. Контакты в профиле.
Алексей П
09 июля 2017, 14:39
0
Проблема при работе с minishop2
При переключении языков почему-то выводятся разные корзины. Т.е. происходит независимое добавление товаров на разных локализациях. Подозреваю, что это связано с тем, что у меня одна из локализаций сделана на поддомене.
Как побороть эту проблему?
    Алексей П
    09 июля 2017, 16:07
    0
    Проблема была в том, что сессии были разные для поддомена и домена.
    Решение
    В системной настройке session_cookie_domain указал .site.com
Борис
09 июля 2017, 22:03
0
Классный компонент.
Подскажите пример, как вывести переведённые поля pagetitle и description у товаров в категории минишопа?

    but1head
    09 июля 2017, 22:05
    0
    {$_modx->resource.pagetitle}
    {$_modx->resource.description}

    Все стандартно, компонент подменяет значения
      Борис
      09 июля 2017, 22:26
      0
      На странице товара так и делаю, значения подменяются.
      А как получить их в каталоге товаров, т.е через msProducts?
        but1head
        09 июля 2017, 22:34
        +1
        В шапке пример для pdomenu, тоже самое для msProducts
          Борис
          09 июля 2017, 22:43
          0
          Спасибо, получилось!
Игорь Терентьев
11 июля 2017, 21:43
0
У кого-нибудь получилось сделать чтобы при ajax-пагинации или при фильтрации через mFilter2 сохранялся текущий язык?
Этот коммент видел, но у меня не получилось сделать modx.pro/components/12012-localizator-multilingual-seo-translation/#comment-82299
    Игорь Терентьев
    11 июля 2017, 22:31
    0
    Методом тыка все-таки нашел нужное событие:)
    Вот такой плагин получился (возможно что-то лишнее):
    <?php
    $eventName = $modx->event->name;
    
    switch($eventName) {
        //case 'OnWebPageInit':
            //if ($modx->context->get('key') == 'mgr') {return;}
            //$modx->lexicon->load($modx->cultureKey . ':minishop2:default');
            //break;
        case 'OnParseDocument':
            if ($modx->context->get('key') == 'mgr') {return;}
            $lang = $_COOKIE['lang'];
            if(!$lang) return;
            $modx->setOption('cultureKey', $lang);
            $modx->lexicon->load($lang . ':minishop2:default');
            break;
        case 'OnLoadWebDocument':
            if ($modx->context->get('key') == 'mgr') {return;}
            $value = $modx->getOption('cultureKey');
            setcookie("lang", $value, time() + (86400 * 365));
            break;
    }
    
    return;
      Klike
      01 августа 2017, 14:59
      0
      Ещё при добавлении товара в корзину / изменении количества в корзине, оформление заказа можно такой плагин добавить, чтобы jGrowl сообщения в корректном языке выводились.

      <?php
      switch ($modx->event->name) {
          case 'msOnBeforeAddToCart':
          case 'msOnBeforeRemoveFromCart':
          case 'msOnBeforeChangeInCart':
          case 'msOnSubmitOrder':
              $request = $_SERVER['HTTP_REFERER'];
              $host = $find = $_SERVER['HTTP_HOST'];
              if($request) {
              	if(strpos($request, '/') !== false) {
              		$request = str_replace($_SERVER['HTTP_ORIGIN'] . '/', '', $request);
              		$tmp = explode('/', $request);
              		$find = $host . '/' . $tmp[0] . '/';
              	} else {
              		$find = $host . '/' . $request;
              	}
              }
              $q = $modx->newQuery('localizatorLanguage', array(
                  array('http_host' => $find),
                  array('OR:http_host:=' => $host)
              ));
              $q->select('cultureKey');
              $lang = $modx->getValue($q->prepare());
              $modx->setOption('cultureKey', $lang);
              $modx->lexicon->load($lang . ':minishop2:cart');
              break;
      }
        Игорь Терентьев
        01 августа 2017, 16:08
        0
        Спасибо! Этот плагин ведь не работает, если языковые версии сделаны через папки (site.ru/en/)?

        Попытался сделать с учетом папок, но тоже не хочет работать…:
        <?php
        $eventName = $modx->event->name;
        
        switch($eventName) {
            case 'msOnBeforeAddToCart':
            case 'msOnBeforeRemoveFromCart':
            case 'msOnBeforeChangeInCart':
            case 'msOnSubmitOrder':
                $http_host = $_SERVER['HTTP_HOST'];
                $uri = $_SERVER['REQUEST_URI'];
                if(substr($uri, 0, 1)) {
                    $uri = mb_substr($uri, 1);
                    $tmp = explode('/', $uri);
                    if($path = $tmp[0]) {
                        $tmp = $modx->getObject('localizatorLanguage', array('http_host:LIKE' => "%/{$path}/"));
                        if($tmp == '') {
                            $tmp = $modx->getObject('localizatorLanguage', array('http_host:LIKE' => "%{$http_host}"));
                        }
                    }
                }
                $lang = $tmp->key;
                $modx->setOption('cultureKey', $lang);
                $modx->lexicon->load($lang . ':minishop2:cart');
                break;
        }
        
        return;
          Игорь Терентьев
          16 февраля 2018, 18:51
          1
          +1
          Попросили запостить конечный рабочий вариант: gist.github.com/ig0r74/bea4170495890e5caa3e0179d06119fb
            Alex Zhuravlev
            16 февраля 2018, 19:03
            0
            Спасибо Игорь, полезная инфа
            Alex Zhuravlev
            16 февраля 2018, 19:40
            0
            Еще не забыть добавить события на плагин
            OnWebPageInit
            OnParseDocument
            OnLoadWebDocument
            msOnBeforeAddToCart
            msOnBeforeRemoveFromCart
            msOnBeforeChangeInCart
            msOnSubmitOrder
            msOnChangeOrderStatus
Игорь Терентьев
15 июля 2017, 13:30
0
Может есть у кого пример кода, как перенести контент ресурсов в определенную языковую версию.
Или как через API создать перевод.
    Игорь Терентьев
    15 июля 2017, 13:50
    0
    Может кому пригодится:
    <?php
    $local = $modx->newObject('localizatorContent');
    $local->set('key', 'en');
    $local->set('resource_id',35);
    $local->set('pagetitle','TEST');
    $local->set('content','TEST CONTENT');
    $local->set('ative',1);
    $local->save();
    Доступные поля можно посмотреть в БД
    but1head
    15 июля 2017, 13:55
    0
    <?php
    $lang = 'ru',
    $localizator = $modx->getService('localizator');
    $resources = $modx->getIterator('modResource');
    foreach($resources as $resource) {
    	$tmp = $modx->getObject('localizatorContent', array('resource_id' => $resource->id, 'key' => $lang));
    	if($tmp) {
    		$tmp = $modx->newObject('localizatorContent');
    		$tmp->fromArray(array(
    			'key' => $lang,
    			'resource_id' => $resource->id,
    			'active' => 1,
    			'pagetitle' => $resource->pagetitle,
    			// ...
    		));
    	} else {
    		// обновление если нужно, fromArray или ->set(key, value);
    	}
    	$tmp->save();
    }
    ну а потом уже можно вызывать процессор core/components/localizator/processors/mgr/content/translate.class.php
      Игорь Терентьев
      15 июля 2017, 15:06
      0
      Спасибо!
      Игорь Терентьев
      21 июля 2017, 23:07
      0
      Подскажи еще пожалуйста. Правильно запускаю процессор?
      <?php
      $resources = $modx->getIterator('modResource', array('class_key'=>'msProduct'));
      foreach($resources as $resource) {
          print $resource->pagetitle;
          $processorProps = array(
              'resource_id' => $resource->id
          );
          $otherProps = array(
              'processors_path' => $modx->getOption('core_path') . 'components/localizator/processors/'
          );
          $response = $modx->runProcessor('mgr/content/translate', $processorProps, $otherProps);
          return $response->response;
      }
      На выходе получаю просто `Array`
        Sany
        30 января 2018, 09:04
        0
        подскажите получилось ли у вас перенести контент? какая правильная последовательность действий? как правильно вызвать процессор?
          Игорь Терентьев
          30 января 2018, 12:23
          0
          Да. Вот, должен быть рабочий вариант:
          <?php
          $resources = $modx->getIterator('modResource', array('class_key'=>'msProduct'));
          foreach($resources as $resource) {
              print $resource->pagetitle;
              $processorProps = array(
                  'resource_id' => $resource->id
              );
              $otherProps = array(
                  'processors_path' => $modx->getOption('core_path') . 'components/localizator/processors/'
              );
              $response = $modx->runProcessor('mgr/content/translate', $processorProps, $otherProps);
              // return $response->response;
              
              // return $response->isError() ? print_r($response->getAllErrors(), 1) : print_r($response->response,1);
          }
          Не вижу отличий, но он, по крайней мере, сохранен у меня в консоли.
            Sany
            30 января 2018, 14:51
            0
            подскажите еще… как этим скриптом перенести поле content уже созданных ресурсов в локализатор о перевести на 3 языка?
      Игорь
      06 января 2018, 02:08
      0
      Доброй ночи! Объясните, пожалуйста, «чайнику»:
      1. Каким образом необходимо выполнить вышеуказанный код для переноса контента ресурсов (например, товары miniShop2) из определенной категории (например, id-11) в языковую версию (ru)?
      2. Как «потом вызывать процессор core/components/localizator/processors/mgr/content/translate.class.php»?
Алексей П
20 июля 2017, 00:24
0
А как можно локализовать пункты фильтра mFilter2?
Для пунктов фильтрации по цвету решил вводить цвета в опции на латинице и потом через словарь выводить перевод.
А как быть с названиями категорий?
    Игорь Терентьев
    20 июля 2017, 00:33
    0
    Примерно так можно (на примере способов оплаты):

    {foreach $payments as $payment}
        <label class="payment input-parent">
            <input type="radio" name="payment" value="{$payment.id}" id="payment_{$payment.id}" {$payment.id == $order.payment ? 'checked' : ''}>
            {set $paymentname = 'po_pay_' ~ $payment.name | translit}
            {$paymentname | lexicon}
            {if $payment.description?}
                {set $paymentdescr = 'po_pay_descr_' ~ $payment.description | translit}
                <small>
                    {$paymentdescr | lexicon}
                </small>
            {/if}
        </label>
    {/foreach}

    translit — сниппет транслитерации.
      Алексей П
      20 июля 2017, 01:29
      0
      Получается это нужно категории тоже в словарь загонять?
      А подтянуть перевод из локализации никак нельзя? Это же названия родительских ресурсов по сути.
        Игорь Терентьев
        20 июля 2017, 01:33
        0
        Наверное можно приджойнить.
        Если как в топике сделать leftJoin, не работает?
        У меня просто не было категорий в фильтре…
          Алексей П
          20 июля 2017, 02:10
          0
          У меня там уже идет leftjoin локализатора.
          Получается надо сначала приджойнить категории, а потом джойнить к категориям и продуктам локализатор. Так чтоли?
          Вызов фильтра:
          {'!mFilter2' | snippet : [
          	'paginator'=>'pdoPage@wia',
          	'class'=>'msProduct',
          	'element'=>'msProducts',
          	'tplOuter'=>'wia.mFilter2.outer',
          	'parents'=>'[[*id]]',
          	'tpls'=>'wia.msProducts.row',
          	'filters'=>'ms|price:number,
          				resource|parent:categories,
          				msoption|color:default,
          				msoption|size:default',
          				
          	'tplFilter.outer.ms|price'=>'wia.mFilter2.filter.price.slider',
          	'tplFilter.row.ms|price'=>'wia.mFilter2.filter.price.row',
          	'tplFilter.outer.msoption|color'=>'wia.mFilter2.filter.outer',
          	'tplFilter.row.msoption|color'=>'wia.mFilter2.filter.checkbox.color',
          	'tplFilter.outer.msoption|size'=>'wia.mFilter2.filter.outer',
          	'tplFilter.row.msoption|size'=>'wia.mFilter2.filter.checkbox',
          	'tplFilter.outer.resource|parent'=>'wia.mFilter2.filter.outer',
          	'tplFilter.row.resource|parent'=>'wia.mFilter2.filter.checkbox',
          
          	'includeThumbs'=>'260x237',
          
          	'sort'=>'id:asc',
          	'leftJoin' => '{"localizator" : {"class" : "localizatorContent","alias" : "localizator","on" : "localizator.resource_id = msProduct.id"}}',
          	'select' => '{ "localizator" : "msProduct.*, localizator.*, msProduct.id" }',
          	'where' => '{ "localizator.key" : "' ~ ('localizator_key' | option) ~ '"}'
          	
          	
          ]}
    but1head
    20 июля 2017, 04:32
    0
    словари локализатора = родным словарям, вынес для удобства. в mfilter2 пункты добавляются в словари ms2, тут можно добавить в словари локализатора. все хранится в «теме» (или как там она) localizator — frontend.

    про категории только джойны
      Алексей П
      22 июля 2017, 00:30
      0
      Так и не разобрался как сделать джойны для категорий в фильтре.
      В результате сделал через сниппет. В него передается id категории, а на выходе локализованный pagetitle.
      Не знаю насколько это правильное решение, но по крайней мере работает.
      Алексей П
      22 июля 2017, 01:46
      0
      Или еще как вариант через расширение класса mse2FiltersHandler
Алексей Яковлев
13 августа 2017, 14:51
0
Прошу прощения за уровень вопроса, но не могу разобраться, как сделать «переключатель» языков, те же флажки. Настроил три языка «по папкам», когда ввожу адрес с папкой — локализация выводится как задумано. Создал сниппет getLanguages (как здесь), вызываю его, а на выходе — пустота, и все, что в хтмл после вызова сниппета — отсутствует. Где ошибся, как правильно? За компонент и советы большое спасибо!
    but1head
    13 августа 2017, 15:06
    0
    yadi.sk/i/QddzUsVX3LwnAm
    <?php
    $output = "<ul>";
    $languages = $modx->getIterator('localizatorLanguage', ['active' => 1]);
    foreach($languages as $lang) {
    	if($lang->key == $modx->localizator_key) continue;
    	$url = 'http://' . $lang->http_host . $_SERVER['REQUEST_URI'];
    	$output .= "<li><a href=\"{$url}\"><img src=\"assets/template/img/lang/{$lang->key}.svg\"><span>{$lang->name}</span></a></li>";
    }
    $output .= "</ul>";
    return $output;
      Алексей Яковлев
      13 августа 2017, 15:17
      0
      Спасибо, почти работает, но если у меня урл основного языка вида хост.ру, то с адреса хост.ру/en на основной ссылка не возвращает. И на конце ссылки два слэша "//" вместо одного. Как исправить?
        Игорь Терентьев
        13 августа 2017, 16:01
        0
        Я вот так сделал. Костыль, но работает:

        <base href="{if $_modx->config.cultureKey == 'el'}{$site_url = $_modx->config.site_url}{else}{$site_url = $_modx->config.site_url ~ $_modx->config.cultureKey ~ '/'}{/if}">
        el заменить на cultureKey основного языка.

        И уже ниже можно использовать {$site_url} для правильной ссылки на главную.
          Алексей Яковлев
          13 августа 2017, 16:20
          0
          Спасибо, но не вполне понял, как пользовать костыль. Полная картина у меня такова: основной язык сайта, в настройках — ru (чтобы «видеть» локализатор). С помощью локализатора созданы языки, основной — en c адресом хост.en, дополнительные с адресом хост.en/ru/ и т.д. При вызове вышеозначенного сниппета я с основного хоста переключаюсь на страницу с нужным языком. Но вот обратно, на аналогичную страницу с основным языком ссылка не ведет. К тому же, при переключении на те языки, что «в папках» (это срабатывает) — в адресной строке множатся косяки: хост.en/ru//fi//ru// и т.д. Как бы справиться?..
            Алексей Яковлев
            13 августа 2017, 16:49
            0
            То есть, знал бы синтаксис, поправил бы в сниппете, чтобы для каждого языка в локализаторе брался бы «хост языка» (хост.en, хост.en/ru/ etc...) и на ссылках-«флажках» подставлялся бы http:// + «хост языка» + [[*alias]] текущей страницы.
            Кажется, этого, в моем случае по крайней мере, было бы достаточно… Кодить, вот, не умею, чтоб проверить.
              Алексей Яковлев
              13 августа 2017, 17:00
              1
              0
              а, ну вот так вроде получилось:
              <?php
              $output = "<div>";
              
              $languages = $modx->getIterator('localizatorLanguage', ['active' => 1]);
              foreach($languages as $lang) {
              	if($lang->key == $modx->localizator_key) continue;
              	$url = 'http://' . $lang->http_host;
              	$output .= "<a href=\"{$url}/[[*alias]].html\"><img src=\"../layout/{$lang->key}-icon.png\" style=\"width:24px\"><span>{$lang->name}</span></a>";
              }
              $output .= "</div>";
              return $output;
              Тоже, правда, костылем выглядит…
Raimei
21 августа 2017, 19:09
0
У кого-нибудь получилось подружить локализатор и msearch2? К babel возвращаться совсем не хочется
    but1head
    21 августа 2017, 19:12
    0
    Что именно подружить?
      Raimei
      21 августа 2017, 19:15
      0
      Ваш модуль и поисковик Василия, больше ничего. Сейчас к сожалению не индексируются слова из таблицы локализатора.
      Raimei
      21 августа 2017, 21:15
      0
      Напишите сколько это будет стоить. Возьму на заметку
Борис
21 августа 2017, 23:49
0
Использую локализатор + минишоп.
Локализатор меняет значение id товара в форме с кнопкой Купить, поэтому в корзину добавляется другой товар.
То есть вместо id товара выводится id записи в таблице локализатора.

Подскажите, как поправить?

{'msProducts' | snippet : [
	'limit' => 0,
	'sortby' => 'menuindex',
	'leftJoin' => '{
		"localizator" : {
			"class" : "localizatorContent",
			"alias" : "localizator",
			"on" : "localizator.resource_id = msProduct.id"
			}
		}',
	'select' => '{ "localizator" : "msProduct.id, localizator.*" }',
	'where' => '{ "localizator.key" : "' ~ ('localizator_key' | option) ~ '"}',
]}
    but1head
    21 августа 2017, 23:53
    +2
    'select' => '{ "localizator" : "modResource.*, localizator.*, msProduct.id" }',
Николай Загумённов
02 сентября 2017, 12:19
2
+2
Хочу поделиться сниппетом, аналог pdoField, так как я часто пользуюсь pdoField.

Сниппет getLocalizatorField

<?php
$sp = &$scriptProperties;

$resource_id = $modx->getOption('resource_id', $sp, $modx->resource->id);
$field = $modx->getOption('field', $sp, 'pagetitle');
$key = $modx->getOption('key', $sp, $modx->getOption('cultureKey'));

$q = $modx->newQuery( "localizatorContent" );
$q->where( array( "`resource_id` = '" . $resource_id . "'", "`key` = '" . $key . "'" ) );
$q->select( array( $field ) );
$s = $q->prepare();  // print $q->toSQL(); die;
$s->execute();
$array = $s->fetch(PDO::FETCH_ASSOC);
$field_value = $array[$field];

return $field_value;
Вызов:

{'getLocalizatorField' | snippet : [ 
       'resource_id' => 20,
       'field' => 'content'
 ]}
    Aleksandr Huz
    24 октября 2017, 14:37
    0
    Спасибо, Николай.

    Хотелось бы выводить так:
    {4 | localizator : 'pagetitle'}

    Написал модификатор для этого. Буду благодарен, если кто-то улучшит код.
    $pdo = $modx->getService('pdoTools');
    
    // localizator
    $fenom->addModifier('localizator', function ($id, $field = null) use ($pdo, $modx) {
        $pdo->debugParserModifier($id, 'localizator');
        
        /** @var modResource $resource */
        if (empty($id)) {
            $resource = $modx->resource;
        } elseif (!is_numeric($id)) {
            $field = $id;
            $resource = $modx->resource;
        } elseif (!$resource = $pdo->getStore($id, 'resource')) {
            $resource = $modx->getObject('modResource', $id);
            $pdo->setStore($id, $resource, 'resource');
        }
        
        $key =  $modx->getOption('cultureKey');
        if( $modx->getOption('cultureKey') != 'ru' ) {
            $q = $modx->newQuery( "localizatorContent" );
            $q->where( array( "`resource_id` = '" . $id . "'", "`key` = '" . $key . "'" ) );
            $q->select( array( $field ) );
            $s = $q->prepare();  // print $q->toSQL(); die;
            $s->execute();
            $array = $s->fetch(PDO::FETCH_ASSOC);
            $field_value = $array[$field];
            return $field_value;
        }
        
        $output = '';
        if (!empty($resource)) {
            if (!empty($field)) {
                if (strtolower($field) == 'content') {
                    $output = $resource->getContent();
                } else {
                    $output = $resource->get($field);
                    if (is_null($output)) {
                        $output = $resource->getTVValue(preg_replace('#^tv\.#i', '', $field));
                    }
                }
            } else {
                $output = $resource->toArray();
            }
        }
        $pdo->debugParserModifier($id, 'localizator');
        return $output;
    });
      Вадим Раевский
      18 ноября 2017, 17:17
      0
      Нубский вопрос, как это подключить?
      Дмитрий Мансуров
      26 марта 2019, 02:40
      0
      Я дописал и поправил ваш код.
      Теперь он не путается со сниппетом localizator и дружит с ТВ полями
      Работает так
      {9 | locfield : 'tv_name'}
      Можно использовать id tv поля, можно имя (видно из кода)
      Запилил я это все в плагин (проверено)
      <?php
      
      /** @var modX $modx */
      switch ($modx->event->name) {
          case 'pdoToolsOnFenomInit':
              /** @var Fenom $fenom
                  Мы получаем переменную $fenom при его первой инициализации и можем вызывать его методы. 
                  Например, добавим модификатор вывода имени домена сайта из произвольной ссылки.
              */
              $pdo = $modx->getService('pdoTools');
      
              // localizator
              $fenom->addModifier('locfield', function ($id, $field = null) use ($pdo, $modx) {
                  $pdo->debugParserModifier($id, 'locfield');
                  
                  /** @var modResource $resource */
                  if (empty($id)) {
                      $resource = $modx->resource;
                  } elseif (!is_numeric($id)) {
                      $field = $id;
                      $resource = $modx->resource;
                  } elseif (!$resource = $pdo->getStore($id, 'resource')) {
                      $resource = $modx->getObject('modResource', $id);
                      $pdo->setStore($id, $resource, 'resource');
                  }
                  
                  $key =  $modx->getOption('cultureKey');
                  if( $modx->getOption('cultureKey') != 'ru' ) {
                      $q = $modx->newQuery( "localizatorContent" );
                      $q->where( array( "`resource_id` = '" . $id . "'", "`key` = '" . $key . "'" ) );
                      $q->select( array( $field ) );
                      $s = $q->prepare();  // print $q->toSQL(); die;
                      $s->execute();
                      $array = $s->fetch(PDO::FETCH_ASSOC);
                      $field_value = $array[$field];
                      if(empty($field_value)){
                          if(is_numeric($field)){
                              $tvId = intval($field);
                          }else{
                              $tvObj = $modx->getObject('modTemplateVar', array('name' => $field));
                              $tvId = $tvObj->get('id');
                          }
                          
                          $q = $modx->newQuery( "locTemplateVarResource" );
                          $q->where( array( "`contentid` = '" . $id . "'", "`key` = '" . $key . "'", "`tmplvarid` = '" . $tvId . "'" ) );
                          $q->select(  'value'  );
                          $s = $q->prepare();   
                          $s->execute();
                          $array = $s->fetch(PDO::FETCH_ASSOC);
                          
                          return $array['value'];
                      }else{
                          return $field_value;
                      }
                      
                  }
                  
                  $output = '';
                  if (!empty($resource)) {
                      if (!empty($field)) {
                          if (strtolower($field) == 'content') {
                              $output = $resource->getContent();
                          } else {
                              $output = $resource->get($field);
                              if (is_null($output)) {
                                  $output = $resource->getTVValue(preg_replace('#^tv\.#i', '', $field));
                              }
                          }
                      } else {
                          $output = $resource->toArray();
                      }
                  }
                  $pdo->debugParserModifier($id, 'locfield');
                  return $output;
              });
              break;
      }
      Галочку
      pdoToolsOnFenomInit
      не забудьте

      И для страждущих getImageList (проверено)
      [[getImageList?  &tpl=`why_we.tpl` &value=`[[*why_we]]`]]
      или даже так, когда данные в другом ресурсе (не успел проверить, но вроде должно)
      {'getImageList' | snippet : [
          'tpl' => 'why_we.tpl',
          'value' => (9 | locfield : 'tv_name')
      ]}
        Дмитрий Мансуров
        28 марта 2019, 23:40
        0
        Мелкая правка
        if(is_numeric($field)){
                                $tvId = intval($field);
                            }else{
                                $tvObj = $modx->getObject('modTemplateVar', array('name' => $field));
                                if($tvObj)$tvId = $tvObj->get('id');
                            }
                            if($tvId == 0){
                                $resource = $modx->getObject('modResource', $id);
                                if($resource) return $resource->get($field);
                            }
Raimei
11 сентября 2017, 10:26
0
Этим получится сделать поиск через mSearch2?
    but1head
    11 сентября 2017, 14:01
    +1
    Сомневаюсь
      Raimei
      11 сентября 2017, 14:02
      0
      У вас имеется решение? Или может предвидится?
        but1head
        11 сентября 2017, 14:06
        0
        Нету. Не предвидится, все исходники на github, вы можете самостоятельно решить эту проблему и поделиться ею с обществом (как я сделал с локализатором). Компонент бесплатный, мне не особо интересно сращивать его с mSearch2 бесплатно, темболее времени на это у меня нет.
          Raimei
          11 сентября 2017, 14:08
          0
          Какова стоимость? Можно даже примерно
            but1head
            11 сентября 2017, 14:10
            0
            темболее времени на это у меня нет.
Алексей П
18 сентября 2017, 23:22
0
Не пойму, как вывести локализованные SEO-теги.
Пробовал так
[[*seotitle]]
Пусто
Пробовал так
{$_modx->resource.seotitle}
Тоже пусто
    but1head
    18 сентября 2017, 23:25
    0
    del
    but1head
    18 сентября 2017, 23:32
    +2
    {$_modx->resource.seotitle} — выводит, на демо проверил, все ок.

    <title>{$_modx->resource.seotitle ?: $_modx->resource.longtitle ?: $_modx->resource.pagetitle}</title>
      Алексей П
      18 сентября 2017, 23:38
      0
      Хм… Мистика. Заработало. Видимо я — рукожоп
      Алексей П
      18 сентября 2017, 23:39
      0
      Спасибо)
Алексей П
29 сентября 2017, 14:55
0
Использую связку minishop2 и localiztor.
Localizator отрабатывает, но термины из словаря minishop2 не заменяются.
Пробовал добавлять в шаблон
{$_modx->lexicon->load(('cultureKey' | option) ~ ':minishop2:default')}
но термины все равно не подменяются.
Alex Zhuravlev
16 октября 2017, 01:40
1
0
Имею конфигурацию
site.com/ru/ и site.com/en/
в HTTP HOST (localizator) прописано site.com/ru/ и site.com/en/

вывожу
{'site_url' | option} или {$_modx->config.site_url}
и получаю site.com/ а должно быть site.com/ru/ или /en/

Посмотрел на примере у Владимира и там тоже самое если перейти на EN и посмотреть ссылку в шапке на логотипе, то она ведет на русский контекст

Как правильно выводить линк на главную страницу того (псевдо) контекста где сейчас находится пользователь а не посылать его на основной по умолчанию web
<a class="site-logo" href="{'site_url' | option}">Site</a>
или
<a class="site-logo" href="{'site_url' | option}{'cultureKey' | option}/">Site</a> 
    Игорь Терентьев
    16 октября 2017, 10:39
    +2
    Для такой конфигурации (el)site.com/ и site.com/en/ я так сделал:
    <base href="
    {if $_modx->config.cultureKey != 'el'}
    	{$site_url = $_modx->config.site_url ~ $_modx->config.cultureKey ~ '/'}
    {else}
    	{$site_url = $_modx->config.site_url}
    {/if}
    ">
    Тебе скорее всего подойдет такой вариант:
    {$site_url = $_modx->config.site_url ~ $_modx->config.cultureKey ~ '/'}
    Ниже уже можешь использовать переменную $site_url
      Alex Zhuravlev
      16 октября 2017, 14:42
      0
      Игорь, спасибо.
      Простите за дубль вопроса, невнимательно прочитал топик.
Alex Zhuravlev
16 октября 2017, 11:47
0
Еще один момент, при конфигурации site.com/ru/ и site.com/en/ создаю страницу для 404 и прописываю ее в системных настройках и дальше ее перевожу через localizator и все работает если вызываю 404 из контекстов, но если получить 404 из site.com/404 (без контекста) то получаю поля из основного контекста web без участия localizator…
А как сделать что бы нельзя было попасть на site.com а сразу перекидывать пользователя на /ru/ или /en/?

У меня nginx + apache и в последнем

php_flag register_globals Off
AddDefaultCharset utf-8
RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_URI} ^/$ [NC]
RewriteCond %{HTTP:Accept-Language} (ru|uk|by|kz) [NC]
RewriteRule .* https://site.com/ru/ [R=302,L]

RewriteCond %{REQUEST_URI} ^/$ [NC]
RewriteRule .* https://site.com/en/ [R=302,L] 

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
Alex Zhuravlev
16 октября 2017, 22:24
2
0
Дописал под себя getLanguages.
Сделал вывод в placeholders и добавил css class «active»

getLanguages
<?php
$pdo = $modx->getService('pdoTools');

$uri = $_SERVER['REQUEST_URI'];
if(substr($uri, 0, 1)) {
    $uri = mb_substr($uri, 1);
    $tmp = explode('/', $uri);
    if($path = $tmp[0]) {
        $tmp = $modx->getObject('localizatorLanguage', array('http_host:LIKE' => "%/{$path}/"));
        if($tmp) {
            $uri = str_replace("{$path}/", "", $uri);
        }
    }
}

$protocol = 'https://';
$languages = $modx->getIterator('localizatorLanguage');
foreach($languages as $language) {
    if(mb_substr($language->http_host, -1) == '/') {
        $placeholders = array(
            'cultureKey'=>$language->key,
            'active'=>$language->key == $modx->localizator_key ? 'active' : '',
            'url'=>$protocol . $language->http_host . $uri,
        );
    } else {
        $placeholders = array(
            'cultureKey'=>$language->key,
            'active'=>$language->key == $modx->localizator_key ? 'active' : '',
            'url'=>$protocol . $language->http_host . '/' . $uri,
        );
    }
    $output .= $pdo->getChunk($tpl, $placeholders);
}

return $output;

В шаблоне
<div class="langs">
	{$_modx->runSnippet('!getLanguages', ['tpl' => 'section-langs-1',])}
	<div class="dropdown-menu">
		{$_modx->runSnippet('!getLanguages', ['tpl' => 'section-langs-2',])}
	</div>
</div>

Содержимое section-langs-1
<a href="#" data-toggle="dropdown" role="button" aria-expanded="false"></a><img class="imglang {$active}" src="/assets/img/flags/{$cultureKey}.png" alt="{$cultureKey}">

Содержимое section-langs-2
<div class="dropdown-item">
    {if $active != 'active'}
        <a class="{$active}" href="{$url}"><img class="imglang {$active}" src="/assets/img/flags/{$cultureKey}.png" alt="{$cultureKey}"></a>
    {else}
        <div class="{$active}"><img class="imglang {$active}" src="/assets/img/flags/{$cultureKey}.png" alt="{$cultureKey}"></div>
    {/if}
</div>

На уникальность не претендую, но уверен что кому то поможет.
Критика и правки приветствуются.
    Alex Zhuravlev
    27 октября 2017, 13:23
    +1
    В снипете getLanguages забыл дописать $output = ''; в самом начале, а иначе в логе будет много PHP notice: Undefined variable: output
Владимир
17 октября 2017, 12:30
0
Просто заметил что:
в новом FireFox (56.0.1 (64-бит)) не прокручивается окно локализации и не дает в контент сделать запись.
В Хроме все нормально (Версия 61.0.3163.100 (Официальная сборка), (64 бит)). Win 8.1
Алексей П
27 декабря 2017, 16:38
+1
После обновления до версии 2.6.1 в админке пропали локализации. На фронте тексты остались. Получается не могу отредактировать ни одну локализацию
    Алексей П
    30 декабря 2017, 22:45
    0
    В инструментах разработчика в хроме видно, что возникает ошибка 500 при попытке обращения к файлу assets\components\localizator\connector.php
      Алексей П
      30 декабря 2017, 22:56
      0
      Выяснилось, что после обновления modx в корневой папке отсутствовал файл config.core.php, что вызывало ошибку при попытке его подключения в коннекторе
Константин Ильин
05 января 2018, 17:46
0
Никита подскажи пожалуйста, а у тебя нормально ставит ссылки в page.nav с site_url например
http://localizator.but1head.ru/en/
и выводит ли через феном site_url

Не работает
{$_modx->config['site_url']}
Через феном не выводит нужный site_url, а просто дефолт

у меня подмена site_url для феном такая, но вот беда пагинацией
case 'OnHandleRequest':
        if($modx->context->key == 'mgr') return;
        $language = 'en';
        $modx->config['site_url'] =  $_SERVER['REQUEST_SCHEME'] . '://' .$_SERVER['HTTP_HOST'] .'/'. $language.'/';
    break;
Пагинация выдает такие ссылки
site.ru/en/en/cat.html?page=2

Или это глюк pdoPage, а точнее глюк формирования page.nav?
Остальные сниппеты нормально работают, в том числе uri в самом pdoPage, т.к. обертка pdoResource
    but1head
    05 января 2018, 18:13
    0
    {'site_url' | option}
    У меня вроде pdopage норм работает, trade-leader.com (11 языков)

    Сейчас нет компа под рукой
      Константин Ильин
      05 января 2018, 19:46
      0
      trade-leader.com (11 языков)
      У тебя там на поддоменах, а глюк когда по папке раскиданы версии 'http://but1head.ru/en/'

      Так тоже выводит дефолтный site_url

      У тебя подмена плейслохолдера только происходит
      $modx->setPlaceholders(array(
                      'cultureKey' => $cultureKey,
                      'site_url' => $_SERVER['REQUEST_SCHEME'] . '://' . $language->http_host,
                  ), '+');
      т.е.
      //Нерабочие варианты
      {$_modx->config['site_url']}
      {'site_url' | option}
      {'site_url' | placeholder}
      
      //Рабочие
      {'+site_url' | placeholder}
       [[!++site_url]]

      Все таки я склоняюсь, что pdoPage не дружит с base, но на это наверно только Василий может ответить)
Игорь
30 января 2018, 19:39
0
Подскажите, как правильно сформировать карту сайта для локализаций (псевдоконтестов) для разных доменов? Здесь trade-leader.com и trade-leader.ru карта сайта формируется верно.
    Дмитрий
    30 января 2018, 20:52
    0
    вам XML карту надо?
      Игорь
      30 января 2018, 22:49
      0
      Да, верно. Обычно для этого использую pdoSitemap+RobotsBuilder, но сейчас такая связка не срабатывает для разных доменов, точне XML карта корректно выводится только после очистки кеша сайта.
      Игорь
      31 января 2018, 15:38
      0
      Никита, огромное спасибо за помощь и сам компонент. Сейчас есть ошибки в разборе XML — «error on line 8 at column 3: Extra content at the end of the document», попытаюсь решить их самостоятельно.
        but1head
        31 января 2018, 16:09
        0
        webmaster яндекса? он хочет для разных разделов (авто, каталог, маркет) доп.данные, все остальные валидаторы норм проверяют. сайт 2 года живет и яндекс его нормально ест.

        В ресурсе sitemap укажите «настройки» > тип содержимого XML
        <?xml version="1.0" encoding="UTF-8"?>
        
        <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
        {'@FILE snippets/sitemap.php' | snippet}
        </urlset>
          Игорь
          31 января 2018, 19:36
          0
          Спасибо, все работает! Никита, не сочтите за наглость, но вы не планировали добавить в XML-карту атрибут hreflang? Сам «чайник», а атрибут hreflang очень рекомендуют Яндекс и Google для мультиязычних сайтов.
            but1head
            31 января 2018, 19:51
            0
            форматы кода стран не всем подойдут, можно просто в head добавить вручную
            <link rel="alternate" hreflang="en" href="http://trade-leader.com/" />
                <link rel="alternate" hreflang="ru" href="http://trade-leader.ru/" />
                <link rel="alternate" hreflang="pt" href="http://pt.trade-leader.com/" />
            и т.д.
              Игорь
              31 января 2018, 20:15
              0
              Да, уже «подсмотрел» у вас на сайте trade-leader.com)), очень мне он нравиться.
      Игорь
      11 февраля 2018, 02:08
      0
      Случайно обнаружил, что в XML карте url главной страницы выводится с «index» —
      <loc>http://trade-leader.com/index</loc>
      . У меня на сайте добавляется и / —
      <loc>http://site.com/index/</loc>
      . Как исключить «index» с XML карты?
Юрий
08 февраля 2018, 12:22
0
Привет, не до конца понял как работает компонент.
Но на старте возникает проблема:
при вставки в локализатор контента, он не вставляется, и не переводится соответственно. Остаются заголовки, И так далее, а сам контент исчезает при повторном открытии: Видно на видео
    but1head
    08 февраля 2018, 14:13
    0
    поле контента пока что поддерживает только tiny mce rte.
Andrey Frost
12 февраля 2018, 21:43
0
Граждане, подскажите пожалуйста с такой задачей: есть 4 разных сайта на одном движке, организовано все это дело через контексты — все прекрасно работает, но тут встала задача сделать языковые версии для всех 4 сайтов. Решил через localizator, работает только на одном контексте, как запилить на остальных 3-х?
    Дмитрий
    13 февраля 2018, 10:23
    0
    Кхм. Localizator как-таки и создан для того, чтобы уйти от контекстов. Поэтому, как я полагаю, он просто совершенно не создан для того, чтобы делать языковые версии для множества контекстов.
Andrey Frost
13 февраля 2018, 18:01
0
таки допилил ) суть в том, что было 4 лендинга (4 контекста), а разбивать на 4 клиент не захотел, так то бы естественно раскопировал бы, да на каждом по отдельности сделал бы языковые версии, в итоге получилось 6 языков на 4-х контекстах.
Dima
16 февраля 2018, 01:01
0
Простите за глупый вопрос, но не получается разобраться.
На сайте два языка: русский и английский. Создал, к примеру, два «контекста» site.com и site.com/en/
После переключения на англоязычную версию — ссылки в меню становятся на английском, но все равно ведут на русскоязычные версию сайта, т.е. должно быть быть site.com/en/about.html а ведет на site.com/about.html. При переходе на англоязычную версию сайта () в base отображается адрес site.com. Должен быть site.com/en/? А если вбить в base site.com/en/, то все стили на сайт ломаются, вообще не подгружаются
    Игорь Терентьев
    16 февраля 2018, 12:11
    0
    У стилей, картинок, скриптов слэш в начале пути поставь: /assets/css/…
      Dima
      16 февраля 2018, 17:06
      0
      спасибо!
Alex Zhuravlev
19 февраля 2018, 12:05
0
Всем привет. Подскажите как правильно вывести текущий CultureKey в чанке товара minishop (tpl.msProducts.row) и что бы при выборе фильтра в mFilter2 он оставался.

На сайте один контекст и два языка (en и ru) через localizator в системной настройке cultureKey стоит «ru»
Если вывожу в чанке {$_modx->config['cultureKey']} или {'localizator_key' | option} то вижу текущий язык, но при отработке фильтра ajax'ом язык {$_modx->config['cultureKey']} слетает на установленный в системных настройках а {'localizator_key' | option} вовсе не отображает.
    Дмитрий
    19 февраля 2018, 12:57
    +1
    Чтобы локализации работали с mFilter, необходимо накидать плагин. У меня примерно такой:
    <?php
    if($modx->context->key == "mgr"){return;}
    $modx->setOption('cultureKey', 'en');
    if (!empty($_COOKIE['lang'])){
        if ($_COOKIE['lang']=='en'){
            $modx->setOption('cultureKey', 'en');
        } else {
            $modx->setOption('cultureKey', 'ru');
        }
    }
    событие OnInitCulture
    Переписать можно куда лучше и универсальнее, просто задачи не стояло. Надеюсь, помог.
      Alex Zhuravlev
      19 февраля 2018, 17:21
      0
      Не получилось, не вижу языки после ajax
      Вот демка localizator.tirinipul.ru/catalog/
      Я уже перепробовал все что мог, не понимаю куда копать дальше.
        Дмитрий
        19 февраля 2018, 18:14
        +1
        Ах да. Сам написал не совсем правильно.
        Смотрите, если почитать код, то там можно увидеть, что есть обращение к куки.
        Но у вас на демке куки не пишутся. Значит что? Что в этом проблема. И тут я вспомнил, что нужен еще один плагин. Я его просто в другое место спрятал и поэтому сразу не нашел.
        <?php
        if($modx->context->key == "mgr"){return;}
        $alias = $modx->context->getOption('request_param_alias', 'q');
        $request = $_REQUEST[$alias];
        $tmp = explode('/', $request);
        if ($tmp[0]=='en'){
            $modx->setOption('cultureKey', 'en');
            setcookie('lang','en',0,'/');
        } else {
            $modx->setOption('cultureKey', 'ru');
            setcookie('lang','ru',0,'/');
        }
        Событие OnHandleRequest, например.
          Alex Zhuravlev
          19 февраля 2018, 23:19
          0
          Дима, большое спасибо, все заработало.
          Нужно было еще сессии и кеш прибить.
Михаил
02 марта 2018, 20:06
0
Здравствуйте. Задам сюда, что бы не плодить темы…
Подскажите пожалуйста, поменять порядок вывода языков, если используешь приведенный тут getLanguages снипет?

Отметку активного языка сделал через условие, а как менять порядок вывода не знаю.
<?php
$output = "";

// определяем есть ли языки через "папки"
$uri = $_SERVER['REQUEST_URI'];
if(substr($uri, 0, 1)) {
    $uri = mb_substr($uri, 1);
    $tmp = explode('/', $uri);
    if($path = $tmp[0]) {
        $tmp = $modx->getObject('localizatorLanguage', array('http_host:LIKE' => "%/{$path}/"));
        if($tmp) {
            $uri = str_replace("{$path}/", "", $uri);
        }
    }
}

$languages = $modx->getIterator('localizatorLanguage');
$tekush = $modx->localizator_key;
foreach($languages as $language) {
    
    if(mb_substr($language->http_host, -1) == '/') {
        $link = $language->http_host . $uri;
    } else { 
        $link = $language->http_host . '/' . $uri;
    }
    if ($tekush == $language->key) {
            $output .= "                <li><a href=\"http://{$link}\"  class=\"checked\">{$language->name}</li>\n"; 
        } else {
            $output .= "                <li><a href=\"http://{$link}\">{$language->name}</li>\n"; 
        };
};
return $output;
Михаил
02 марта 2018, 20:11
0
И еще, как правильно реализовать добавление характеристик товаров небольшого каталога для многоязычности с использованием локализатора?

если 3 языка, то просто делать для каждого ресурса по 3 тв параметра для каждой характеристики и потом в шаблоне по условию, в зависимости от текущего языка их выводить?
Михаил
03 марта 2018, 07:33
0
И еще один глупый вопрос… а как разное поле contant на разных языках заполнить?
Alex Zhuravlev
11 марта 2018, 00:21
0
Поставил SEO TAB что бы делать 301 редиректы битых ссылок, и при добавлении я указываю id ресурса на который должна вести ссылка, и столкнулся с проблемой что в компоненте линк генерируется исходя из контекста и в итоге получается что site.ru/test я могу указать а вот site.ru/EN/test не могу так как localizator же на псевдо контекстах. prntscr.com/ipggei
Может сделать второй контекст пустой?
Подскажите куда копать, может сталкивался.
Андрей Розум
19 марта 2018, 12:30
0
Поставил на два сайта, на одном из них неприятный баг.
Когда добавляю или пытаюсь изменить значение двух полей полей — Аннотация и SEO Описание, то после сохранения они заменяются на 0.
Думал может конфликтует с каким дополнением, но сделал на другом сайте тот же набор дополнений и там все по-прежнему работает. Как-то можно найти причину подмены текста на 0?
    but1head
    19 марта 2018, 13:31
    1
    +1
    github.com/but1head/localizator/blob/master/core/components/localizator/model/schema/localizator.mysql.schema.xml вот тут надо поменять phptype=«text» на phptype=«string». Чуть позже пересоберу компонент.
      Андрей Розум
      19 марта 2018, 15:42
      0
      Поменял, но все равно в этих двух строках после сохранения 0.
      Андрей Розум
      19 марта 2018, 22:46
      0
      В общем так и не понял что не так, пока перекинул аннотации в поле для ключевых слов.
      Роман Воропаев (Volk)
      07 апреля 2018, 08:24
      0
      Точно такая же проблема, после сохранения появляется в этих полях «0»
      Последняя версия MODX и пакета
        Роман Воропаев (Volk)
        07 апреля 2018, 08:43
        +1
        github.com/but1head/localizator/blob/master/core/components/localizator/model/schema/localizator.mysql.schema.xml вот тут надо поменять phptype=«text» на phptype=«string». Чуть позже пересоберу компонент.
        Все, проблема решена
      Алексей
      07 июля 2018, 15:22
      0
      github.com/but1head/localizator/blob/master/core/components/localizator/model/localizator/mysql/localizatorcontent.map.inc.php
      В этом файле тоже text на string нужно заменить
      строка 83 и 90
Raimei
30 мая 2018, 22:07
0
У кого-нибудь получилось использовать редактор отличающийся от TinyMCE?

@but1head скажи хотя бы в какую сторону копать? Всё перерыл, но никак не могу понять — от чего зависит выбор именно Tiny.
Гозман Семён
24 июня 2018, 20:23
0
Не выводит поле content на Русском языке, только на Английском почему-то
{$_modx->resource.localizator_content}
На русском пустота, хотя в локализации и в стандартном теле ресурса есть текст:
С английским всё нормально:

В логах ничего нет, названия переводятся нормально.
Во вкладке локализация переведено с русского на русский и английская версия.

При cultureLAnguage ru ничего не выводит, при en всё как нужно. Разумеется Fenom везде включен.
but1head, очень надеюсь на твою помощь, ибо я в тупике…
    Гозман Семён
    24 июня 2018, 20:52
    0
    Пока закостылил как-то так:
    [[++cultureKey:is=`ru`:then=`[[*content]]`]][[++cultureKey:is=`en`:then=`{$_modx->resource.localizator_content}`]]
    but1head
    24 июня 2018, 21:18
    0
    localizator_default_language указал?
fred Oushen
02 июля 2018, 20:13
0
Прошу вашей помощи, дабы не плодить новые темы, задаем его тут.

Собственно, а как обновить ранее добавленные разделы и страницы, просто в ручную каждый добавлять не есть гуд, пробовал в самом приложении в словарях сделать автоперевод, он не работает, постоянно загрузка идет в логах ошибок нету, в консоле тоже пусто. Подскажите как обновить все?!
Гозман Семён
12 июля 2018, 18:42
0
Рабочий кусок вывода локализованного pdoResources, вдруг кому пригодится. Я долго вкурить не могу почему не работает! Оказывается, что нужно было использовать конструкцию {$_modx->runSnippet()}, а не в том укороченном виде, что представлен в статье
{$_modx->runSnippet('pdoResources', [
	'parents' => 10,
	'depth' => 0,
	'tpl' => 'newsRowTpl',
	'includeTVs' => 'news-image',
	'leftJoin' => '{
		"localizator" : {
			"class" : "localizatorContent",
			"alias" : "localizator",
			"on" : "localizator.resource_id = modResource.id"
		}
	}',
	'select' => '{ "localizator" : "modResource.*, localizator.*, modResource.id" }',
        'where' => '{ "localizator.key" : "' ~ ('localizator_key' | option) ~ '"}',
])}
    Гозман Семён
    12 июля 2018, 18:51
    0
    Метод костыльного программирования продалжался!
    Предыдущий вариант выводил только иностранный перевод, но не русский :D Решил проблему гениально тупо, но работает:
    {$_modx->runSnippet('pdoResources', [
    	'parents' => 10,
    	'depth' => 0,
    	'tpl' => 'newsRowTpl',
    	'includeTVs' => 'news-image',
    	[[++cultureKey:ne=`ru`:then=`
    	'leftJoin' => '{
    		"localizator" : {
    			"class" : "localizatorContent",
    			"alias" : "localizator",
    			"on" : "localizator.resource_id = modResource.id"
    		}
    	}',
        	'select' => '{ "localizator" : "modResource.*, localizator.*, modResource.id" }',
                'where' => '{ "localizator.key" : "' ~ ('localizator_key' | option) ~ '"}',
        `]]
    ])}
    but1head
    12 июля 2018, 19:15
    0
    {'pdoPage' | snippet : [
    'element' => 'ms2GalleryResources',
    'tpl' => '@FILE chunks/article.row.tpl',
    'parents' => 179,
    'limit' => 8,
    'leftJoin' => '{
    		"localizator" : {
    			"class" : "localizatorContent",
    			"alias" : "localizator",
    			"on" : "localizator.resource_id = modResource.id"
    		}
    	}',
    'select' => '{ "localizator" : "modResource.*, localizator.*, modResource.id" }',
    'where' => '{ "localizator.key" : "' ~ ('localizator_key' | option) ~ '", "localizator.active" : 1}',
    ]}
    работает больше года
      Гозман Семён
      12 июля 2018, 19:22
      0
      Вот хоть убей не работает у меня в таком виде, уже весь проект на cultureKey'ях в итоге
    Илья Александрович
    21 марта 2019, 02:29
    0
    Подскажите пожалуйста, как выводите tv поле в шаблоне 'includeTVs' => 'news-image'?
    а если не трудно то покажите шаблон 'tpl' => 'newsRowTpl'. Мне нужно тв с текстом вывести, не получается (через сниппет pdoResources).
    Благодарю.
Евгений
06 августа 2018, 01:16
0
После отключения языка (который не нужен или пока на доработке), он все равно отображается. Это должно быть так или как то фиксится?
Делал вывод по аналогии как тут
    Михаил
    20 мая 2019, 15:44
    0
    Добрый день.
    Возник тот же вопрос… Вам удалось как-то его решить?
      Игорь Терентьев
      20 мая 2019, 17:52
      0
      Не проверял, но скорее всего нужно в сниппете вот эту строку:
      $languages = $modx->getIterator('localizatorLanguage');
      заменить на:
      $languages = $modx->getIterator('localizatorLanguage', array( 'active' => 1 ));
Гозман Семён
21 августа 2018, 09:11
0
Компонент сыпет ошибками в консоль на PHP Version 7.2.8
(ERROR @ html/core/components/localizator/processors/mgr/language/update.class.php : 38) PHP warning: Use of undefined constant key - assumed 'key' (this will throw an Error in a future version of PHP)
eflit
26 декабря 2018, 11:03
0
Здравствуйте, как включить поле в перевод свойства товара minishop2?
Виталий
16 января 2019, 06:48
0
Доброе утро, каким образом реализованы эти вкладки из примера?



Добавление записи в словарь — работает, а удаление — нет в компоненте, у всех не работает?
Степан Прищепенко
25 февраля 2019, 00:23
0
Мой вариант getLanguages на основе текущего:
<?php

$log = $output = '';
$default_host = $modx->getOption('http_host', []);

$pdoFetch = $modx->getService('pdoTools');
$pdoFetch->setConfig($scriptProperties, false);
$pdoFetch->addTime('pdoTools loaded');

preg_match('/([^.]+){1}\.([^.]+)$/i', $_SERVER['HTTP_HOST'], $matches);

$languages = $modx->getIterator('localizatorLanguage', [
	'http_host:LIKE' => "%{$matches[0]}",
	'active'         => 1
]);
$placeholders = [];
$result = false;
foreach($languages as $language) {
	// print_r($language->toArray());

	// if (!$result && $language->http_host == $matches[0]){
	if ($language->key == $modx->localizator_key){
		$result = true;
	}

	if ($default_host == $matches[0]){
		$default_key = $language->key;
	}
	$placeholders[$language->key] = [
		'id'         => $language->id,
		'name'       => $language->name,
		'cultureKey' => $language->key,
		'current'    => ($language->key == $modx->localizator_key),
		'active'     => ($language->key == $modx->localizator_key),
		'url'        => $_SERVER['REQUEST_SCHEME'] . '://' . $language->http_host,
	];
}


// сортировка результата
uasort($placeholders, function ($a, $b){
	return ($a['id'] <=> $b['id']);
});


if (!$result && $default_key && $placeholders[$default_key]){
	$placeholders[$default_key]['active'] = true;
}

$output = !empty($tpl) ? $pdoFetch->getChunk($tpl, ['langs' => $placeholders]) : print_r($placeholders, 1);

// print_r($placeholders);
// die();

if ($modx->user->hasSessionContext('mgr') && !empty($showLog)) {
	$log .= '<pre class="pdoResourcesLog">' . print_r($pdoFetch->getTime(), 1) . '</pre>';
}


if ($scriptProperties['return'] == 'data') {
	return ['data' => $output, 'log' => $log];
}

if (!empty($toPlaceholder)) {
	$modx->setPlaceholder($toPlaceholder, $output);
}

return $output;
пример использования:
{if !$localizator = $_modx->cacheManager->get('localizator_'~$.server.HTTP_HOST)}
  {set $localizator = '!getLanguages' | snippet : [
		'showLog'         => '1',
		'tpl'             => '@FILE:others/chunks/languages__items.tpl',
  ]}
  {set $null = $_modx->cacheManager->set('localizator_'~$.server.HTTP_HOST, $localizator, 1)} {* кэш на 30 минут *}
{/if}

<span class="lang-selector dropdown-el">
	{$localizator}
</span>
SEQUEL.ONE
12 марта 2019, 19:43
0
Возникла проблема с HybridAuth, все ссылки, которые идут в response переходят на сайт провайдера с ошибкой из-за протокола. Протокол HTTP, вместо HTTPS. Что с этим можно сделать? Если в компоненте http_host ввести site.ru/ то это работает, но всё остальное отображается не так. Подставляя URL спереди ещё одну копию https://
    SEQUEL.ONE
    12 марта 2019, 23:48
    0
    Нашёл в чём дело в файле \core\components\localizator\model\localizator\localizator.class.php

    if($language) {
                if (preg_match("/^(http(s):\/\/)/i", $language->http_host)) {
                    $site_url = $language->http_host;
                }
                else
                    $site_url = MODX_URL_SCHEME . $language->http_host;
    Вот эту строчку

    $site_url = MODX_URL_SCHEME . $language->http_host;
    заменить на

    $site_url = 'https://' . $language->http_host;
    Но костыль не очень конечно. Если обновлять на новые версии, то всё потрётся. Как придумать по деликатнее способ?
Артем
23 марта 2019, 13:44
0
А как в msCart вывести переведнные названия товаров?
{'!msCart' | snippet : [
    'tpl' => 'tpl.msCart',
                        ]}
    Артем
    25 марта 2019, 12:48
    0
    {'!msCart' | snippet : [
    'tpl' => 'tpl.msCart',
        'leftJoin' => '{
                        "localizator" : {
                        "class" : "localizatorContent",
                        "alias" : "localizator",
                        "on" : "localizator.resource_id = msProduct.id"
                                    		}
                                    	}',
                                    	'select' => '{ "localizator" : "msProduct.*, localizator.*, msProduct.id" }',
    'where' => '{ "localizator.key" : "' ~ ('localizator_key' | option) ~ '", "localizator.active" : 1}',
                            ]}
Александр
09 апреля 2019, 10:34
0
А как в msGetOrder вывести переведенные названия товаров?
и что бы в письме покупателю они переведенные отправлялись?
    Алексей
    18 апреля 2019, 10:54
    +1
    Присоединяюсь к вопросу. У вас получилось перевести название товаров в msGetOrder и письмо?
Dmitry ShkiL
26 мая 2019, 23:34
0
Доброго времени суток. Столкнулся с такой проблемой не получается вывести pdoCrumbs. Вывожу вот так
{'!pdoCrumbs' | snippet : [
	
	'leftJoin' => '{
		"localizator" : {
		    "class" : "localizatorContent",
		    "alias" : "localizator",
		    "on" : "localizator.resource_id = modResource.id"
	        }
	  }',
	'select' => '{ "localizator" : "modResource.*, localizator.*, modResource.id" }',
	'where' => '{ "localizator.key" : "' ~ ('localizator_key' | option) ~ '"}',


	'outputSeparator' => '<li><i class="far fa-angle-double-right"></i></li>',
	'tpl' => '@INLINE: <li><a class="activated" href="[[+link]]">[[+menutitle]]</a></li>',
	'tplCurrent' => '@INLINE: <li>{$menutitle}</li>',
	'tplHome' => '@INLINE: <li><i class="fas fa-home activated"></i><a class="activated" href="[[+link]]">[[+menutitle]]</a></li>',	
	'tplWrapper' => '@INLINE: <div class="breadcrumbs"><div class="container"><ul>[[+output]]</ul></div></div>',
	'showHome' => 1,
]}
Хотя pdoMenu, pdoResources, MIGX выводить без проблем.

Вот лог
[2019-05-26 23:30:27] (ERROR @ /Volumes/Work/Projects/Salon/web/core/model/modx/modx.class.php : 1031) `` is not a valid integer and may not be passed to makeUrl()
[2019-05-26 23:30:27] (ERROR @ /Volumes/Work/Projects/Salon/web/core/model/modx/modresponse.class.php : 210) Attempted to redirect to an empty URL.
[2019-05-26 23:30:27] (ERROR @ /Volumes/Work/Projects/Salon/web/core/components/pdotools/model/pdotools/pdofetch.class.php : 172) [pdoTools] Error 42000: Expression #89 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'salon.localizator.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
[2019-05-26 23:30:28] (ERROR @ /Volumes/Work/Projects/Salon/web/core/model/modx/modx.class.php : 1031) `` is not a valid integer and may not be passed to makeUrl()
[2019-05-26 23:30:28] (ERROR @ /Volumes/Work/Projects/Salon/web/core/model/modx/modresponse.class.php : 210) Attempted to redirect to an empty URL.
[2019-05-26 23:30:28] (ERROR @ /Volumes/Work/Projects/Salon/web/core/model/modx/modx.class.php : 1031) `` is not a valid integer and may not be passed to makeUrl()
[2019-05-26 23:30:28] (ERROR @ /Volumes/Work/Projects/Salon/web/core/model/modx/modresponse.class.php : 210) Attempted to redirect to an empty URL.
    Игорь Терентьев
    27 мая 2019, 11:50
    0
    Не вижу ошибок, но вот точно работающий вызов:

    {$_modx->runSnippet('pdoCrumbs', [
                    	'tpl' => '@INLINE <span class="help-center-breadcrumbs__item"><a class="help-center-breadcrumbs__link" href="{$link}">{$menutitle}</a></span>',
                    	'tplCurrent' => '@INLINE <span class="help-center-breadcrumbs__item"><span class="help-center-breadcrumbs__link">{$menutitle}</span></span>',
                    	'tplMax' => '@INLINE <span class="help-center-breadcrumbs__item"><span class="help-center-breadcrumbs__link"> ... </span></span>',
                    	'tplWrapper' => '@INLINE <div class="help-center-breadcrumbs">{$output}</div>',
                    	'showHome' => 1,
                        'leftJoin' => '{
                    		"localizator" : {
                    			"class" : "localizatorContent",
                    			"alias" : "localizator",
                    			"on" : "localizator.resource_id = modResource.id"
                    		}
                    	}',
                    	'select' => '{ "localizator" : "modResource.*, localizator.*, modResource.id" }',
                        'where' => '{ "localizator.key" : "' ~ ('localizator_key' | option) ~ '"}',
                    ])}
      Dmitry ShkiL
      27 мая 2019, 12:15
      0
      Ну тогда я совсем нечего не понимаю. Этот вызов тоже у меня не работает.
      Если вызываю так то выводит только на одном языке:
      {'!pdoCrumbs' | snippet : [
      	'outputSeparator' => '<li><i class="far fa-angle-double-right"></i></li>',
      	'tpl' => '@INLINE: <li><a class="activated" href="{$link}">{$menutitle}</a></li>',
      	'tplCurrent' => '@INLINE: <li>{$menutitle}</li>',
      	'tplHome' => '@INLINE: <li><i class="fas fa-home activated"></i><a class="activated" href="{$link}">{$menutitle}</a></li>',	
      	'tplWrapper' => '@INLINE: <div class="breadcrumbs"><div class="container"><ul>{$output}</ul></div></div>',
      	'showHome' => 1,
      ]}
      Добавляю вызов localizator не выводит вообще нечего:
      'leftJoin' => '{
          "localizator" : {
          "class" : "localizatorContent",
          "alias" : "localizator",
          "on" : "localizator.resource_id = modResource.id"
             }
       }',
      'select' => '{ "localizator" : "modResource.*, localizator.*, modResource.id" }',
      'where' => '{ "localizator.key" : "' ~ ('localizator_key' | option) ~ '"}
      Что я мог сделать не так?
        Артем
        27 мая 2019, 13:02
        0
        Вот рабочий вариант
        {'Localizator' | snippet : [
            'snippet' => 'pdoCrumbs',
        ]}
          Dmitry ShkiL
          27 мая 2019, 13:07
          0
          Я так пробывал и тоже не чего не выводит. Очевидно ошибка не в вызове. Но я не знаю как посмотреть что не так.
            Артем
            27 мая 2019, 13:11
            0
            showLog
              Dmitry ShkiL
              27 мая 2019, 13:16
              0
              Знающие подскажите в чем ошибка
              0.0002098: pdoTools loaded
              0.0001490: Conditions prepared
              0.0000281: Query parameters ready
              0.0000520: xPDO query object created
              0.0004518: leftJoined localizatorContent as localizator
              0.0000038: Grouped by modResource.id
              0.0005441: Added selection of modResource: `id`, `type`, `contentType`, `pagetitle`, `longtitle`, `description`, `alias`, `alias_visible`, `link_attributes`, `published`, `pub_date`, `unpub_date`, `parent`, `isfolder`, `introtext`, `content`, `richtext`, `template`, `menuindex`, `searchable`, `cacheable`, `createdby`, `createdon`, `editedby`, `editedon`, `deleted`, `deletedon`, `deletedby`, `publishedon`, `publishedby`, `menutitle`, `donthit`, `privateweb`, `privatemgr`, `content_dispo`, `hidemenu`, `class_key`, `context_key`, `content_type`, `uri`, `uri_override`, `hide_children_in_tree`, `show_in_tree`, `properties`
              0.0000300: Added selection of localizatorContent: modResource.*, localizator.*, modResource.id
              0.0005841: Added where condition: published=1, deleted=0, id:IN(7,1), localizator.key=en
              0.0002360: Sorted by find_in_set(`modResource`.`id`,'7,1'), 
              0.0000050: Limited to 10, offset 0
              0.0004940: SQL prepared "SELECT `modResource`.`id`, `modResource`.`type`, `modResource`.`contentType`, `modResource`.`pagetitle`, `modResource`.`longtitle`, `modResource`.`description`, `modResource`.`alias`, `modResource`.`alias_visible`, `modResource`.`link_attributes`, `modResource`.`published`, `modResource`.`pub_date`, `modResource`.`unpub_date`, `modResource`.`parent`, `modResource`.`isfolder`, `modResource`.`introtext`, `modResource`.`content`, `modResource`.`richtext`, `modResource`.`template`, `modResource`.`menuindex`, `modResource`.`searchable`, `modResource`.`cacheable`, `modResource`.`createdby`, `modResource`.`createdon`, `modResource`.`editedby`, `modResource`.`editedon`, `modResource`.`deleted`, `modResource`.`deletedon`, `modResource`.`deletedby`, `modResource`.`publishedon`, `modResource`.`publishedby`, `modResource`.`menutitle`, `modResource`.`donthit`, `modResource`.`privateweb`, `modResource`.`privatemgr`, `modResource`.`content_dispo`, `modResource`.`hidemenu`, `modResource`.`class_key`, `modResource`.`context_key`, `modResource`.`content_type`, `modResource`.`uri`, `modResource`.`uri_override`, `modResource`.`hide_children_in_tree`, `modResource`.`show_in_tree`, `modResource`.`properties`, modResource.*, localizator.*, modResource.id FROM `modx_site_content` AS `modResource` LEFT JOIN `modx_localizator_content` `localizator` ON localizator.resource_id = modResource.id WHERE  ( `modResource`.`published` = 1 AND `modResource`.`deleted` = 0 AND `modResource`.`id` IN (7,1) AND `localizator`.`key` = 'en' )  GROUP BY modResource.id ORDER BY find_in_set(`modResource`.`id`,'7,1') LIMIT 10 "
              0.0008790: Could not process query, error #1055: Expression #89 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'salon.localizator.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
              0.0000141: Chunks processed
              0.0040200: Total time
              4 194 304: Memory usage
                Dmitry ShkiL
                27 мая 2019, 13:32
                0
                Все разобрался всем спасибо за помощь
Максим Степанов
08 июня 2019, 05:12
0
Доброго времени суток. Подскажите почему может быть такая ошибка?
Notice: Undefined index: localizatorTVs in /home/s/saybme/ved-garant.saybme.beget.tech/public_html/core/components/pdotools/model/pdotools/pdofetchlocalizator.class.php on line 13
на появляется когда меняешь настройку pdoFetch.class на pdotools.pdofetchlocalizator
    MrKarandash
    09 июня 2019, 19:01
    0
    Такая же проблема
    MrKarandash
    09 июня 2019, 19:11
    0
    И не пропускает почему TV где тип migx
Андрей Шевяков
11 июня 2019, 19:58
0
Для Localizator надо создавать несколько контекстов для выбора разных Локалей? Реально сделать на одном контексте, несколько языковых версий? И как сделать переключение языков тогда, если контекст один? Поделитесь опытом?
MrKarandash
17 июня 2019, 15:21
-1
задолбали ошибки везде типа

Notice: Undefined variable: hook in /home/m/melnichvl/cultstroy.su/public_html/core/cache/includes/elements/modsnippet/44.include.cache.php on line 45
Константин Ильин
15 июля 2019, 12:08
0
Подскажите как быть(как правильно) когда вызов идет с ms2GalleryResources
{'!pdoPage@pg' | snippet : [
    'element' => 'ms2GalleryResources'
    'parents' => 30
    'tpl' => 'newsItem'
    'limit' => 18
    'includeOriginal' => 1
    'sortby' => 'menuindex'
    'sortdir' => 'ASC'
]}
{'page.nav' | placeholder}
И такой вызов
{'!ms2GalleryResources' | snippet : [
    'parents' => 7
    'tpl' => 'main.pItem'
    'limit' => 4
    'depth' => 0
    'includeOriginal' => 1
    'sortby' => 'menuindex'
    'sortdir' => 'ASC'
]}
    Артем
    16 июля 2019, 13:26
    0
    Попробуйте так, но я не тестил
    1.
    {'!pdoPage@pg' | snippet : [
        'element' => 'Localizator',
        'snippet' => 'ms2GalleryResources',
        'parents' => 30,
        'tpl' => 'newsItem',
        'limit' => 18,
        'includeOriginal' => 1,
        'sortby' => 'menuindex',
        'sortdir' => 'ASC'
    ]}
    2.
    {'!Localizator' | snippet : [
        'snippet' => 'ms2GalleryResources',
        'parents' => 7,
        'tpl' => 'main.pItem',
        'limit' => 4,
        'depth' => 0,
        'includeOriginal' => 1,
        'sortby' => 'menuindex',
        'sortdir' => 'ASC'
    ]}
Денис
16 июля 2019, 19:53
0
В случае если на сайте уже были документы, необходимо ручками добавлять для них перевод?
Андрей
26 июля 2019, 10:01
0
Добрый день. При попытке перевода автоматически пишет «Для автоматического перевода необходимо добавить хотя бы одну запись в таблицу»
Локализации добавлены, язык по умолчанию выбран
UPD: вопрос снят — нужно было создать один перевод для основного языка на странице, тогда автоматический перевод работает. Было бы здорово указать это в доках))
Андрей
26 июля 2019, 11:03
0
Можно ли с помощью localizator переводить поля вида $_modx->config.name_config?
    Василий Столейков
    26 июля 2019, 13:16
    0
    нет, не получится. Придётся выкручиваться, например лексиконами.
      Андрей
      27 июля 2019, 10:25
      0
      Понял, а подскажите, как через лексиконы сделать переводы тех конфигов, который через компонент config сделаны?
      Андрей
      27 июля 2019, 10:41
      0
      В догонку: получается чтобы сайт работал например на 2 языках: английском и французском, нужно помимо того что заполнены поля в вкладке Документ еще перезаполнить их для основного языка на вкладке Локализации — нет ли возможности если не заполнены локализации тянуть все с вкладки Документ?
        Василий Столейков
        27 июля 2019, 17:30
        0
        Там кажется по умолчанию именно так и сделано. Если не заполнены поля локализации, они подтягиваются с основных.
Сергей
04 августа 2019, 14:09
0
Добрый день. Как сделать localization для каталога tickets?
{'!pdoPage' | snippet : [
        'element' => 'getTickets',
        'parents' => 11,
        'limit'=>0,
        'tvPrefix' => '',
        'includeTVs' => 'img',
        'tpl' => 'tpl.block.item'
    ]}
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
265