Оценок: 1
Сниппет для создания оглавления статьи

Сниппет для создания оглавления статьи

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

Представленный здесь сниппет обрабатывает содержимое поля и на основе заголовков H2 создает оглавление с сылками на эти самые заголовки. Самим заголовкам добавляется уникальный id.

Код сниппета

Назовем его TextLink.

<?php
$dom = new DOMDocument();
$input = mb_convert_encoding($input, 'HTML-ENTITIES', 'utf-8');
$dom->loadHTML($input);
$xpath = new DOMXPath($dom);
$h2 = $xpath->query('//h2');
if ($h2->length < 2) return ''; // Проверка на количество
$url = $modx->makeUrl($modx->resource->get('id'));
$i = 0;
$out = '';
if ($h2) {
    $out .= '<div class="subtitle">Оглавление</div>';
    $out .= '<ol class="ogl-list">';
    foreach ($h2 as $h) {
    $i++;
    $out .= '<li class="ogl-item"><a href="'.$url.'/#toh'.$i.'" title="'.$h->textContent.'">'.$h->textContent.'</a></li>';
    $nodePre = $h2->item($i-1);
    $nodePre->setAttribute("id", 'toh'.$i);
    }
    $out .= '</ol>';
}
$out .= $dom->saveHTML();
return $out;

Что касается проверки на количество заголовков H2, при условии, как в примере оглавление будет выводится только если заголовков 2 и больше. можно сделать так:

if ($h2->length < 4) return '';

Тогда оглавление будет более к месту. Если h2 меньше, сниппет ничего не выведет.

Использование

Используется вместе с элементом шаблона, плейсхолдером, обычно это [[*content]], следующим образом:

[[*content:TextLink]]
Оценок: 1
Надежный хостинг VPS серверов
  • Свои ISO образы
  • VDS с оплатой раз и навсегда
  • Аренда VDS на любой срок, с оплатой по дням
  • Большое разнообразие конфигураций
  • Дата-центры в ЕС и России
+ скидка 10%

Комментарии (3)

  1. День добрый.

    Почему то в исходном коде после использования получаются коды букв а не символы. Возможно что то с конвертацией: $input = mb_convert_encoding($input, 'HTML-ENTITIES', 'utf-8');
    Пробовал разные варианты конвертации, но получить кириллицу не получается.

    vital 30 сентября 2019, 05:07 0
    • Или проблема в чем то еще. На сервере с php5.6 все нормально, php7.1 — ошибка 500, чуть позже смогу посмотреть что не так, пока нет доступа к серверным логам

      Владимир 30 сентября 2019, 11:40 0
      • Удалось ли посмотреть?

        Виталий 07 октября 2019, 13:36 0