prevNext

    Сниппет Навигация по соседним документам Modx Evo

    Сниппет вывода соседних документов в MODX Evolution. Например, ссылки «Следующая статья», «Предыдущая статья», «Предыдущий товар», «Следующий товар».

    На многих сайтах после текста статьи часто можно встретить блок ссылок на другие материалы сайта. Например, ссылки «Следующая статья», «Предыдущая статья». Также на странице товара, помимо самого товара, можно увидеть ссылки на соседние товары из той же категории.

    У Ditto, как и у Wayfinder, я такой возможности не нашел. Поэтому написал простой сниппет и решил поделиться им здесь. Надеюсь кому-то он пригодится. Сниппет, как и было сказано выше, очень простой – отличный пример для тех, кто только начинает писать свои решения для MODX. В коде множество комментариев, так что проблем с пониманием возникнуть не должно.

    Сниппету можно передавать 4 параметра:

    • &tpl – чанк-шаблон для вывода списка ссылок (обязательный параметр)
    • &prevDocs – количество документов с меньшим ID (необязательный параметр)
    • &nextDocs – количество документов с большим ID (необязательный параметр)
    • &sortRevert – порядок сортировки документов (необязательный параметр)

    Чанк-шаблон:

    <a href="[~[+id+]~]">[+pagetitle+]</a>
    
    <?php
        // определяем значения по умолчанию 
        $prevDocs = (isset($prevDocs)) ? $prevDocs : 2; // количество соседних документов с меньшим ID
        $nextDocs = (isset($nextDocs)) ? $nextDocs : 2; // количество соседних документов с большим ID
    
        $sortRevert = (isset($sortRevert)) ? $sortRevert : 0; // параметр определяющий порядок сортировки
    
        // небольшая проверка предоставленных в параметрах значений
        $prevDocs = (int) $prevDocs;
        $nextDocs = (int) $nextDocs;
        $sortRevert = (int) $sortRevert;
    
        // получаем ID документа на котором происходит вызов данного сниппета
        $id = $modx->documentIdentifier;
    
        // получаем ID документа-родителя 
        $parent = $modx->documentObject['parent'];
    
        // проверяем задан ли чанк
        if (!isset($tpl)) {
            echo "No chunk defined for siblings-snippet!";
            return;
        }
    
        // проверяем существует ли чанк
        if ($modx->parseChunk($tpl,array()) === NULL) {
            echo "Chunk specified, but not found!";
            return;
        }
    
        // получаем данные о соседних документах с меньшим ID
        $prev = $modx->db->makeArray($modx->db->select('id, pagetitle', 'modx_site_content', "id < {$id} and parent = {$parent} and published = 1", 'id DESC', $prevDocs));
    
        // получаем данные о соседних документах с большим ID
        $next = $modx->db->makeArray($modx->db->select('id, pagetitle', 'modx_site_content', "id > {$id} and parent = {$parent} and published = 1", 'id ASC', $nextDocs));
    
        // объединяем полученные данный в один массив
        $siblings = array_merge($next, $prev);
    
        // определяем массив в котором будет храниться индексированный массив
        $indexed = array();
    
        // создаем массив с индексами составленными из ID документов
        foreach ($siblings as $sibling) {
            $indexed[$sibling['id']] = $sibling;    
        }
    
        // сортируем
        if ($sortRevert === 1) {
            rsort($indexed);
        } else {
            sort($indexed);
        }
    
        // формируем html
        foreach($indexed as $sibling){
            $html .= $modx->parseChunk(
                $tpl,
                array(
                    'id' => $sibling['id'],
                    'pagetitle' => $sibling['pagetitle']        
                ),
                '[+','+]'
            );
        }
        echo $html;
    ?>
    

    <?php
    $ID = $modx->documentIdentifier;
    $parentId = array_pop($modx->getParentIds($modx->documentIdentifier, 1));
    
    $children = $modx->getActiveChildren($parentId, 'menuindex', 'ASC');
    
    $i=0;
    $key = false;
    while(!$key && $i < count($children)){
        $key = array_search($ID, $children[$i]);
        $i++;
    }
    
    if(!empty($key) && count($children) > 1){
        $placeholders = array(
            'prev'=>($i-2 >= 0 ? '<a href="'.$modx->makeUrl($children[$i-2]['id']).'">« назад</a>' : ''),
            'next'=>($i < count($children) ? '<a href="'.$modx->makeUrl($children[$i]['id']).'">вперед »</a>' : '')
        );
        $output = $modx->parseChunk('prevnext', $placeholders, '[+', '+]');
    }
    return $output;
    ?>
    

    Сниппет выводит результат в чанк prevnext, в котором используются два плейсхолдера:

    [+prev+] [+next+]

    Пример Сниппета вывода соседних документов