MODX. Подборка информации и советов по написанию сниппетов

В сниппетах можно использовать как php, так и xPDO.

$scriptProperties — массив содержащий все параметры передаваемые в вызываемый сниппет.

Давайте говорящее имя и описание

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

Оставляйте комментарии к коду

Это важная деталь для любого разработчика, даже если речь идет не о сниппетах. Умение оставлять поясняющие комментарии к коду сэкономит уйму времени тому, кто будет этот код впоследствии разбирать.

Для небольших запросов из базы используйте xPDO

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

Популярные xPDO конструкции

Работа с шаблонами:

/* получаем параметр tpl, указанный при вызове сниппета. 
Если параметр не указан, возьмет имя по умолчанию (3 параметр) */
$tpl = $modx->getOption('tpl',$scriptProperties,'ResourceItem');

Работа с плейсхолдерами:

/* устанавливаем плейсхолдер */
$modx->setPlaceholder('page', $contents);

/* передаем переменную в плейсхолдер */
$modx->setPlaceholder('page.contents', $contents);

Сниппет должен что-то возвращать

Написание универсальных сниппетов, способных работать из любого места вызова — хорошая практика. Для того чтобы сниппет был универсальным, он должен что-то возвращать. 

В примере ниже, сниппет проверяет какое-то значение, и на его основе выводит текст:

// Плохо                                     // Хорошо
if ($_SESSION['theme']) {                    if ($_SESSION['theme']) {
 echo $_SESSION['theme'];                      $output = $_SESSION['theme'];
} else {                                     } else {
 echo "none";                                  $output = "none";
}                                            }
                                             return $output;

Оба варианта будут работать при обычном вызове на странице, но если попробовать записать значение сниппета в переменную, то сработает только второй вариант, возвращающий значение через return.


$fields = $profile->get('extended');
$fields['theme'] = $modx->runSnippet('getTheme'); // Здесь вызываем наш сниппет
$profile->set('extended',$fields);
$profile->save();

Избегайте дублирующийся код и оптимизируйте

Если код дублируется, может возникнуть ситуация, когда в одной части он будет изменен, а в другой останется прежним, и вызовет ошибку.

// ПЛОХО
if (isset($param)) {
    if (isset($param2){
            $output = 5 + $param2;
        }else{
            $output = 5;
    }
    $output .= $anythingelse + $param;
} else {
    if (isset($param2){
            $output = 5 + $param2;
    }else{
            $output = 5;
    }
    $output .= $anythingelse;
}

// ХОРОШО
if (isset($param2){
         $output = 5 + $param2;
}else{
         $output = 5;
}

if (isset($param)) {
   $output .= $anythingelse + $param;
}else{
   $output .= $anythingelse;
}

Отделяйте логику от представления

Чем меньше HTML внутри PHP, тем лучше. HTML могут редактировать контент-менеджеры, администраторы, и прочие люди участвующие в жизнидеятельности сайта. HTML размещенный в php коде либо недоступен, либо крайне опасен. Если необходимо добавить html, можно использовать следующие варианты:

Вызов xPDO getChunk

$props = array(
    'cow' => 'Moo',
    'pig' => 'Oink',
);
return $modx->getChunk('animals', $props);

Использование этих плейсхолдеров в чанке:

<!-- animals -->
Корова говорит "[[+cow]]", а свинка "[[+pig]]".

Установка плейсхолдеров через xPDO setPlaceholder

​
/* устанавливаем плейсхолдер */
$modx->setPlaceholder('page', $contents);

/* передаем переменную в плейсхолдер */
$modx->setPlaceholder('page.contents', $contents);

Далее установленные плейсхолдеры вызываются в шаблоне или чанке в нужном html блоке.

Указывайте параметры по умолчанию

$headTpl = $modx->getOption('headTpl', $scriptProperties, 'defHeadTpl');

Регистрируйте ошибки в журнале логов

Подробности об xpdo.log

$xpdo->log(xPDO::LOG_LEVEL_ERROR,'An error occurred.');