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

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

Для одного из сайтов понадобилось вывести оглавление для материалов. Для начала я решил поискать готовые варианты решения, но в большинстве того что мне попадалось использовались регулярные выражения, что мне показалось не очень хорошей идеей, и тут я вспомнил о другом варианте, который использовал при парсинге страниц, а именно класс 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 == 0) 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, при таком условии оглавление будет выводится даже если заголовок только один. можно сделать так:

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

Тогда оглавление будет более к месту.

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

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

[[*content:TextLink]]
Сказать $пасибо

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

  1. vital 30 сентября 2019, 05:07
    0

    День добрый.

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

    1. Владимир 30 сентября 2019, 11:401
      0

      Или проблема в чем то еще. На сервере с php5.6 все нормально, php7.1 — ошибка 500, чуть позже смогу посмотреть что не так, пока нет доступа к серверным логам

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

        Удалось ли посмотреть?