Автоматическая генерация оглавления страницы

Автоматическая генерация оглавления страницы MODX Revo
Для улучшения юзабилити обычно в статьях блога выводят оглавление (содержимое) с якорными ссылками до заголовков в статьях. Сделать это можно разными способами: руками, генерить автоматически при помощи jQuery, либо сниппета. Т.к. далеко не все сайты используют библиотеку jQuery, разберем вариант со сниппетом.

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

Создаем сниппет с именем AutoContent и следующим кодом:

<?php
// Если в тексте нет заголовков от h1 до h5 - выходим
if (!preg_match_all('#<h([1-5])>(.*?)</h[1-5]>#', $input, $headers)) {return;}
// Если заголовков меньше 2х - тоже выходим
if (count($headers[0]) < 2) {return;}

$base = $modx->makeUrl($modx->resource->id, '', '', 'full');
$from = $to = array();
$depth = 0;
$start = null;
// Генерация меню
$contents = '<ul id="page-contents">';
foreach ($headers[2] as $i => $header) {
	$header = preg_replace('#\s+#', ' ', trim(rtrim($header, ':!.?;')));
	$anchor = str_replace(' ', '-', $header);
	$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 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);

return $contents . $input;

Далее вызываем данный сниппет фильтром вывода, например вот так:

[[*content:AutoContent]]

Небольшой разбор сниппета

Алгоритм работы простой: сниппет выбирает все заголовки от h1 до h5 и генерирует из них вложенный список, а после этого добавляет якоря перед заголовками в тексте.

Информация для тех у кого фиксированное меню

В случае если у вас зафиксировано сверху меню, 90% что при переходе по оглавлению у вас заголовок будет улетать под меню, по этому вам необходимо добавить немного CSS, например:

a.page-contents-link {display:block;position:relative;top:-70px;visibility:hidden}

где -70px — это высота меню (70px).

Источник
Поделиться с друзьями
Алексей

Веб-дизайнер и SEO оптимизатор. Занимаюсь созданием сайтов с 2010 года и их продвижение с 2012 года!

Оцените автора
( 1 оценка, среднее 5 из 5 )
Web-Revenue.ru
Добавить комментарий

  1. Денис

    Здравствуйте! А как вы заполняете и выводите содержание для своих постов? Используете ли текстовые редакторы вроде tinymce или ckeditor, или просто верстку в поле контент вставляете? Если через редактор, то как там сделать вставки кода? Вижу вы используете подсветку синтаксиса prism. Как для блоков с кодом, если работать через текстовый редактор, удобно задавать классы, стили и тд, а картинки условные оборачивать в различные блоки, для модальное галереи условной

    Ответить
    1. Алексей автор

      Здравствуйте. Если речь чисто о MODX, то использую обычно tinymce rte, там можно настроить вставку кода, шаблонов (верстки) посмотрите урок https://web-revenue.ru/modx-revo/tinymce-rich-text-editor. А верстка обычно сажается (если сложная) на pageblocks https://web-revenue.ru/modx-revo/pageblocks — нечто похожее можно сделать на migx https://web-revenue.ru/modx-revo/migx-v-migx

      Ответить
  2. Юлия

    Алексей, здравствуйте!
    Подскажите, пожалуйста, как в данном случаем можно подсветить заголовки при скролле?

    Ответить
    1. Алексей автор

      Здравствуйте. А можно подробнее? Зачем их вообще подсвечивать?

      Ответить
      1. Юлия

        Не совсем верно написала, простите.
        На оглавление добавлять класс активности при скролле, когда доходит до заголовка

        Ответить
        1. Алексей автор

          Если скрипт срабатывает и добавляет нужные классы, далее оформляете все как нужно

          Ответить