Автоматическое оглавление для статьи

Задача: появилась необходимость сделать якорное меню у ранее опубликованных статей, статей много, вручную дополнять их содержанием и расставлять якоря по тексту займут недели...

Решение: регулярным выражением вытащить из текста все <h2>, дописать к ним якоря и вывести список ссылок.

Самое главное чтобы в тексте не было одинаковых заголовков <h2>.

1
$text = '
	<h2>Заголовок 1</h2>
	<p>...</p>
	<h2>Заголовок 2</h2>
	<p>...</p>
	<h2>Заголовок 3</h2>
	<p>...</p>
	<h2>Заголовок 4</h2>
	<p>...</p>
';

$text = stripslashes($text);
preg_match_all("/<h2.*?>(.*?)<\/h2>/i", $text, $items);
print_r($items);
PHP

В некоторых CMS нет возможности получить текст в переменной – поможет буферизация вывода:

od_start();
$text = ob_get_clean();

Получим массив, в котором $items[0] будет содержать теги, $items[1] только тексты.

Array(
	[0] => Array(
		[0] => <h2>Заголовок 1</h2>
		[1] => <h2>Заголовок 2</h2>
		[2] => <h2>Заголовок 3</h2>
		[3] => <h2>Заголовок 4</h2>
	)
	[1] => Array(
		[0] => Заголовок 1
		[1] => Заголовок 2
		[2] => Заголовок 3
		[3] => Заголовок 4
	)
)
2
<div class="texts-list">
	<h3>Содержание</h3>
	<ol>
		<?php
		foreach ($items[1] as $i => $row) {
			echo '<li><a href="#tag-' . ++$i . '">' . $row . '</a></li>';
		}
		?>					
	</ol>
</div>
HTML
3
foreach ($items[0] as $i => $row) {
	$text = str_replace($row, '<a name="tag-' . ++$i . '"></a>' . $row, $text);
}		

echo $text;
PHP
4
5
<?php
$text = '
	<h2>Заголовок 1</h2>
	<p>...</p>
	<h2>Заголовок 2</h2>
	<p>...</p>
	<h2>Заголовок 3</h2>
	<p>...</p>
	<h2>Заголовок 4</h2>
	<p>...</p>
';

$text = stripslashes($text);
preg_match_all("/<h2.*?>(.*?)<\/h2>/i", $text, $items);

if (!empty($items[1])) {
	?>
	<div class="texts-list">
		<h3>Содержание</h3>
		<ol>
			<?php
			foreach ($items[1] as $i => $row) {
				echo '<li><a href="#tag-' . ++$i . '">' . $row . '</a></li>';
			}
			?>					
		</ol>
	</div>
	<?php	
}

if (!empty($items[0])) {
	foreach ($items[0] as $i => $row) {
		$text = str_replace($row, '<a name="tag-' . ++$i . '"></a>' . $row, $text);
	} 
}

echo $text;
PHP
05.03.2019, обновлено 29.09.2019
5915
Предыдущая запись PHP функции для checked и selected

Комментарии 1

Кирилл Зарубко Кирилл Зарубко
24 января 2022 в 17:39
Здравствуйте. Подскажите пожалуйста как сделать, чтобы отображалось оглавление из всех заголовков. Попробовал сделать так, отображается, но вместе текста заголовка идет его порядковый номер.(1.1, 2.2) и т.д.
preg_match_all("/<h([1-6]).*?>(.*?)<\/h([1-6])>/i", $text, $items);

, чтобы добавить комментарий.

Другие публикации

Как дописать стили в атрибут style тегов HTML через PHP
Данный вопрос возникает при верстке писем т.к. стили прописанные в head в почтовых сервисах и программах не работают, а...
19732
+3
Преобразование цветов в PHP
Несколько примеров как перевести цвета из HEX в RGB и обратно с помощью PHP.
16856
-1
Работа с FTP в PHP
Протокол FTP – предназначен для передачи файлов на удаленный хост. В PHP функции для работы с FTP как правило всегда доступны и не требуется установка дополнительного расширения.
20471
+2
Как преобразовать текст из textarea в параграфы HTML
Такой вопрос возникает при вставке текста из формы на сайт (отзывы, комментарии и т.д.) с форматированием элементом p.
7774
+3
Шорткоды на регулярных выражениях
Часто на сайтах возникает необходимость вставлять в тексты страниц динамичные информационные блоки – баннеры, телефоны...
5974
+3
Работа с директориями в PHP
Набор PHP функций для работы с директориями, получение списка файлов в папке, копирование и удаление содержимого папок.
31908
-1