воскресенье, 30 августа 2015 г.

MODX Ограничение доступа к источнику файлов. Каталог upload.

При подготовке сайта к использованию контент менеджером следует опасаться того, что им открыт доступ к файлам ядра системы и прочим жизнено важным файлам сайта, которые случайно могут удалиться/переместиться/похититься пришельцами.
Чтобы избежать таких неприятностей следует создать пользователя content_manager(например) и выделить ему папку upload для того чтобы он использовал её в качестве хранилища файлов, и не мог ничего натворить за её пределами.
В итоге должно получиться что-то типа этого:
Для того чтобы этого добиться сперва создадим папку upload:

После этого создадим источник файлов "Upload". Для этого заходим в Медиа => Источники файлов, и там создаем его:
После чего заходим на страницу редактирования и указываем пути к папке upload:

Ну вот, мы добились того, что у нас сейчас есть два источника файлов: FileSystem - с полным доступ к файлам с корня каталога сайта, и Upload - с доступом к файлам с папки upload, в этом можно убедиться создав или закинув в папку upload какойнибудь файл:
Теперь логично предположить что для того чтобы контент менеджер имел доступ только к источнику файлов Upload нужно чтобы у него не было доступа к источнику файлов Filesystem, а лучше чтобы он вообще его не видел. Для этого можно использовать готовую политику доступа из моего репо: зайти в контроль доступа и импортировать её как это описано в этой статье на примере политики доступа "Content Manager", после чего присвоить её источнику FileSystem в Правах доступа группы пользователей "Content Managers":
Теперь просто добавим наш новый источник файлов в доступы группы пользователей, чтобы получилось как-то так:
Ну вот и все, после Перезагрузки прав доступа мы можем зайти как пользователь content_manager и проверить:
Теперь о том как использовать наш источник файлов в дополнительных полях, где подразумевается работа с файловой системой(например TV Изображение).
Для использования достаточно указать в дополнительном поле на соответствующей вкладке наш источник файлов Upload:
После этого при указании изображения с помощью нашего TV в редактировании ресурса будет виден только источник файлов Upload, и при последующем выводе в теле страницы будет добавляться 'upload/' к пути файла.
Насчет последнего: чтобы этого добиться при использовании нашего TV в MIGX необходимо на соответствующей вкладке указать source From: tv, как это сделано в конфиге images-tv-upload в моем репо.

Ссылки:
Статья - инструкция по созданию группы пользователей Content Managers
Политика доступа None Media для ограничения доступа к истонику файлов
Конфиг Images TV Upload с использованием TV image и его источника файлов
Оффициальная документация по MODX Media Sources
Читать далее

среда, 26 августа 2015 г.

Мультиязычность в MODX с Babel. Развернутое руководство. Автоматический перенос ресурсов

Я в свое время столкнулся с такой задачей и так и не смог найти развернутого решения(а тем более на русском языке): от начала и до конца - как же происходит реализация мультиязычности в MODX.

Есть несколько способов реализации мультиязычности: от нескольких готовых решений, среди которых Babel и xLexicon, так и множество велосипедов, в том числе с session(как я однажды попробовал сделать).
В этой статье будет рассмотрено организация мультиязычности с помощью Babel.

Итак, для начала нужно понять что мультиязычность реализовывается с помощью контекстов. Контексты представляют из себя своеобразные разделы сайта - хранилища ресурсов(документов) со своими настройками системы, которые можно переопределять в настройках этого контекста.


Первым шагом к мультиязычности будет создание контекста для всех дополнительных языков помимо основого(для примера будет реализована мультиязычность для английского и немецкого). С начала переименуем контекст "Website" в "Русский":
Потом создадим контекст для английского языка:
И таким же образом для немецкого языка. После этого мы получим такой список контекстов:

После этого скачиваем компонент Babel через Приложения > Установщик > Загрузить дополнения > Поиск, и устанавливаем его, проверим что в Context Keys прописаны все наши контексты для мультиязычности.

После установки заходим во все наши ресурсы и создаем переводы для соседних контекстов(по сути просто копируем ресурсы в другие контексты с созданием связи).
Если ресурсов много, да еще и в виде кучи деревьев, то можно воспользоваться моим скриптом копирования ресурсов с созданием связи, который переносит все ресурсы из одного контекста в другой с пометкой в pagetitle (например [EN] или [DE]).

После создания переводов страниц в соответствующей менюшке отображаются связи, и к ним можно перейти по ссылкам:

Теперь приведем в порядок наши контексты, в них нужно создать следующие настройки:
Для основного контекста(web - Русский):
base_url: /
cultureKey: ru
site_url: http://your_site.ru/
site_start: 1
Для дополнительных контекстов(en - English, de - Deutsch)
base_url: /en/
cultureKey: en
site_url: http://your_site.ru/en/
site_start: 3
где "en" заменяем на то сочетание букв, которое соответствует нужному языку, а в site_start прописываем id главного ресурса соответствующего контекста.

Теперь создадим плагин switchContext для переключение контекста:
И назначим его на событие "OnHandleRequest":
Теперь нужно убедится что проставлены настройки системы и ЧПУ из этой статьи, после чего добавить в файл .htaccess такие строчки:

# redirect all requests to /en/favicon.ico and /de/favicon.ico
# to /favicon.ico
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(en|de)/favicon.ico$ favicon.ico [L,QSA]
  
# redirect all requests to /en/assets* and /de/assets* to /assets*
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(en|de)/assets(.*)$ assets$2 [L,QSA]
  
# redirect all requests to /en/upload* and /de/upload* to /upload*
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(en|de)/upload(.*)$ upload$2 [L,QSA]
 
# redirect all other requests to /en/* and /de/*
# to index.php and set the cultureKey parameter
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(en|de)?/?(.*)$ index.php?cultureKey=$1&q=$2 [L,QSA]

вместо строчек #The Friendly URLs part.

Ну вот и все, все настроено для того чтобы работала мультиязычность, можно зайти по адресу site.ru/en и убедиться что там выводится главный ресурс из соответствующего контекста.

Теперь перед нами стоит задача вывода ссылок для переключения между языками. С этим справиться нам поможет сниппет BabelLinks, который можно положить в том месте где должны быть ссылки переключения языков:
<div class="lang-links>
   [[!BabelLinks? &showCurrent=`1`]]
</div>

Теперь, когда у нас настроена мультиязычность нам нужно задуматься о том как будут выводится те слова на сайте, которые не относятся к какому-либо ресурсу, которые лежат в шаблонах или чанках и представляют из себя невинные "Цена", "Оплата" и т.д. Нам же их тоже нужно переводить, но и в ресурс никакой их не положишь, не уместно будет. Тут нам на помощь приходит lexicon или Словари в MODX, о которых я уже писал в этой статье.
Все что нам нужно дополнительно сделать - это создать папки "en" и "de" в папке lexicon, где под такими-же именами записать переводы для слов, после чего помещать в шаблоны или чанки такой вызов lexicon:
[[!%sitename.example? &namespace=`sitename` &language=`[[++cultureKey]]`]]

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

ПРИМЕЧАНИЕ:
Как вы наверняка заметили: в lexicon вызове используется переменная [[++cultureKey]], которую мы определили в настройках контекстов. Мы таким образом можем вызывать настройки системы из соответствующей страницы в админке и настройки контекстов, которые переопределяют настройки системы.
Для чего это я поясняю: благодаря такому приему можно так-же прописывать id ресурсов, на которые у нас идет непосредственная ссылка из шаблонов или чанков. Это нам может пригодится в тех случаях когда нужно вывести какие-то данные или дочерние ресурсы непосредственно из какого-то определенного раздела. Например у нас есть раздел "Отзывы", из которого в шапке на каждой странице нужно выводить последний оставленный отзыв. Этот раздел "Отзывы" в русском контексте будет например под id: 7, а в английском контексте под id: 9, таким образом прописав соответствующие айдишники под именами "reviews_id" в настройках наших контекстов мы сможем при вызове сниппета getResources(например) выводить в каждом контексте отзывы на нужном нам языке прописав &parents=`[[++reviews_id]]`.
Если же мы напишем свой сниппет, то нам может понадобиться получить этот reviews_id в теле сниппета, для чего мы можем выполнить
$reviews_id = $modx->getOption('reviews_id'); 

Ссылки:
Плагин switchContext
Скрипт копирования ресурсов с созданием связи Babel

Начало работы в MODX. Первоначальная настройка. Приложения для установки, настройки системы и дружелюбные URL

Управление словарями в MODX

[MODx] 10. Using Babel for Muti-languages support
Настройка мультиязычности MODx REVO + Babel без .htaccess
Settings MODX
Читать далее