Для одного из сайтов понадобилось вывести оглавление для материалов. Для начала я решил поискать готовые варианты решения, но в большинстве того что мне попадалось использовались регулярные выражения, что мне показалось не очень хорошей идеей, и тут я вспомнил о другом варианте, который использовал при парсинге страниц, а именно класс 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]]
День добрый.
Почему то в исходном коде после использования получаются коды букв а не символы. Возможно что то с конвертацией: $input = mb_convert_encoding($input, 'HTML-ENTITIES', 'utf-8');
Пробовал разные варианты конвертации, но получить кириллицу не получается.
Или проблема в чем то еще. На сервере с php5.6 все нормально, php7.1 — ошибка 500, чуть позже смогу посмотреть что не так, пока нет доступа к серверным логам
Удалось ли посмотреть?