Для того, чтобы автоматически сгенерировать оглавление статьи, можно или распарсить статью до показа пользователю, выделив из неё заголовки h2 - h5 или для той же цели использовать встроенный php класс DOMDocument для более удобного перебора узлов документа (статьи). Рассмотрим оба варианта.

Генерация оглавления с помощью регулярного выражения


Для поиска всех заголовков в статье, воспользуемся функцией preg_match_all() и регулярным выражением вида '/<h([2-5])>\n*(.*?)\n*<\/h[2-5]>/'. Так же нам потребуется передавать в функцию генерации оглавления URL детальной странице, на которой это оглавление будет показываться. Это нужно для правильной работы якорей.


<?php 

/**
 * Получитьь оглавление статьи
 * @param $input - html статьи
 * @param $detailPageUrl
 * @return string|void
 */
function getTableOfContetn($input, $detailPageUrl = ''){
	
    // Если в тексте нет заголовков от h2 до h5 - выходим
    if (!preg_match_all('/<h([2-5])>\n*(.*?)\n*<\/h[2-5]>/', $input, $headers)) {
        return;
    }
    // Если заголовков меньше 2х - не выводим оглавление
    if (is_countable($headers[0]) && count($headers[0]) < 2) {
        return;
    }

    $base = $detailPageUrl;
    $from = $to = [];
    $depth = 0;
    $start = null;
	
    // Генерация оглавления
    $contents = '<div class="page-content-wrapper"><div class="page-content-header">Оглавление</div><ul id="page-contents">';
    foreach ($headers[2] as $i => $header) {
		
        $header = preg_replace('#\s+#', ' ', trim(rtrim($header, ':!.?;')));
        $anchor = 'header_' . $i;
        $header = "<a href=\"{$base}#{$anchor}\">{$header}</a>";

		//Формируем вложенность списка
        if ($depth > 0) {
            if ($headers[1][$i] > $depth) {
                while ($headers[1][$i] > $depth) {
                    $contents .= '<ul>';
                    $depth ++;
                }
            } elseif ($headers[1][$i] < $depth) {
                while ($headers[1][$i] < $depth) {
                    $contents .= '</ul>';
                    $depth --;
                }
            }
        }
		
        $depth = $headers[1][$i];
		
        if ($start === null) {
            $start = $depth;
        }
		
        $contents .= '<li>' . $header . '</li>';

        $from[$i] = $headers[0][$i];
        $to[$i] = '<a id="' . $anchor . '" name="' . $anchor . '" class="page-contents-link"></a>' . $headers[0][$i];
    }
	
    // Закрытие всех открытых списков
    for ($i = 0; $i <= ($depth - $start); $i ++) {
        $contents .= "</ul>";
    }
	
    // Добавление якорей к заголовкам
    $input = str_replace($from, $to, $input);
    $contents .= '</div><!-- END page-content-wrapper-->';

    return $contents . $input;
}


Теперь, можно обработать тело статьи, получить html код оглавления и вывести в удобном нам месте (обычно после заголовка h1).

Пример использования

На примере 1С Битрикс. Файл result_modifier.php шаблона компонента, вызываем нашу функцию передавая в качестве основного аргумента DETAIL_TEXT массива $arResult и пересохраняем DETAIL_TEXT.

//Файл result_modifier.php шаблона вашего компонента детальной страницы новости
$arResult['DETAIL_TEXT'] = getTableOfContetn($arResult['DETAIL_TEXT'], '');


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

Полезная статья?
(Голосов: 2, Рейтинг: 3.44)
Вам также могут понравиться
Обновление остатков товара на складе в 1С Битрикс

Обновление остатков товара на складе в 1С Битрикс

Как правильно обновлять остатки товара на сайта под управлением CMS 1С Битрикс.

Английский для программистов

Английский для программистов

Почему IT-специалисту необходимо освоить английский язык? Разбираем в статье.

Как подключить CSS и JS файлы к шаблону 1С Битрикс

Как подключить CSS и JS файлы к шаблону 1С Битрикс

Как правильно подключать стили и скрипты к шаблону 1С Битрикс.


Комментарии
Защита от автоматических сообщений
CAPTCHA
Введите слово на картинке