Содержание / Оглавление статьи WordPress
Время прочтения: 6 мин.
281

Содержание

    Введение

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

    Плагины Table of Contents для WordPress

    С плагинами всё обстоит просто. На английском языке Содержание статьи звучит как «Table of Contents», или сокращённо «TOC». Здесь я не буду повторять множество обзоров таких плагинов, у каждого из них есть большое разнообразие достоинств и недостатков. Просто приведу пример поиска подходящего плагина.

    В панели администратора WordPress выбираем меню: Плагины – Добавить новый. Наверху в поисковую строку вводим фразу «Table of Contents», и выбираем тот плагин, где присутствует галочка «Совместим с вашей версией WordPress».

    Плагины Table of Contents для WordPress
    Плагины Table of Contents для WordPress

    Обращайте внимание на рейтинг плагина и количество активных установок – чем больше, тем он популярнее и повышается вероятность высокого качества.

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

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

    Содержание статьи WordPress без плагина

    Принцип работы автоматического оглавления заключается в формировании HTML-списка на основе существующих на странице заголовков. Каждому из таких заголовков будет присвоен атрибут ID, а его название используется для анкора ссылок.

    Возможности скрипта

    • Символы пробела преобразуются в символы подчёркивания (а несколько пробелов заменяются одним символом _);
    • когда заголовку уже присвоен атрибут ID, он будет использован без изменений;
    • если попадается дубликат ID, ему присваивается суффикс типа _1, _2 до тех пор, пока не получится уникальный идентификатор (при отключённом параметре numeric для доработанной версии);
    • сохраняется вложенность структуры заголовков и формируется соответствующий список HTML;
    • можно создавать различные типы списков: ul, или ol.

    Параметры скрипта

    ПараметрТипПо умолчаниюОписаниеПример использования параметра
    contentstring'body'Селектор, в котором TOC будет искать заголовки.content: '.article-body'
    headingsstring'h1,h2,h3'Селекторы каких заголовков задействовать.headings: 'h2,h3,h4'

    Доработка

    Лично мне не хватило нескольких параметров, поэтому я добавил их в собственную версию скрипта TOC. За основу была взята версия 0.4.0:

    ПараметрТипПо умолчаниюОписаниеПример использования параметра
    numericboolfalseФормировать ID и целевые URL ссылок не из текста заголовков, а просто пронумеровать их.numeric: true
    excludedstring''Исключить перечисленные через запятую заголовки. Обычно я исключаю «Содержание».excluded: 'Содержание,Примечание'

    Параметр numeric понадобился потому, что мы ведь автоматизируем список с заголовками из Кириллицы. Скрипт добавит русские буквы в ID и в целевой URL, а это будет некрасиво выглядеть при попытке отправить кому-нибудь такую ссылку. Лучше пусть будет номер, который выглядит так:

    id="_10" (href="#_10").

    Префикс _ необходим для корректной работы CSS-фреймворка Twitter Bootstrap 4, в частности для его модуля Scrollspy. Некоторые классы в доработке, также, требуются для данной цели. Работу модуля вы можете наблюдать сейчас на странице в правой боковой колонке – это ещё один способ добавить содержание статьи WordPress.

    Установка Table of Contents на WordPress

    Скачивайте скрипт по ссылке, если вы хотите установить оригинальную версию.

    Актуальная версия доработанного скрипта доступна здесь:
    https://onstartup.ru/wp-content/themes/onstartup/assets/js/toc.min.js

    Подключение файла

    В корневом каталоге используемой темы WordPress создайте каталоги: /assets/js/ и поместите туда загруженный файл toc.min.js.

    Откройте файл functions.php и добавьте туда следующий код:

    /**
     * Enqueue scripts and styles.
     */
    function onstartup_scripts() {
    	wp_enqueue_script( 'toc-script', get_template_directory_uri() . '/assets/js/toc.min.js', array( 'jquery' ), '0.4.0', true );
    }
    add_action( 'wp_enqueue_scripts', 'onstartup_scripts' );

    Использование скрипта Table of Contents

    Предлагается два варианта запуска скрипта.

    1. Установка параметров непосредственно в коде HTML с использованием data-атрибутов.
    2. Через программный API с применением функции JavaScript и указанием параметров.

    HTML и атрибуты DATA

    Откройте в редакторе сайта блок HTML и добавьте следующий код:

    <ul data-toc=".article-body" data-toc-headings="h2,h3,h4" data-toc-numeric="true" data-toc-excluded="Содержание,Примечание"></ul>

    В данном примере установлены все имеющиеся параметры:

    • контейнер для поиска заголовков – CSS класс .article-body;
    • указаны HTML заголовки h2, h3, h4;
    • установлено условие для замены текстов заголовков на цифровую нумерацию;
    • в исключения добавлены заголовки с текстами Содержание и Примечание.

    Для минимального запуска достаточно такого кода (допустимо использование тега ol вместо ul):

    <ul data-toc></ul>

    При этом учитывайте, что в список с параметрами по умолчанию попадут все теги h1h3 внутри контейнера <body>.

    Параметры data-toc-numeric и data-toc-excluded будут доступны только в доработанной версии.

    Вызов функции через программный API

    HTML

    В редакторе WordPress добавьте HTML код:

    <ul id="toc"></ul>

    JS

    Отредактируйте файл, который вы используете для запуска кода jQuery и добавьте следующую функцию:

    if ( $.isFunction( $.fn.toc ) ) {
    	$( "#toc" ).toc( {
    		content: ".article-body",
    		headings: "h2,h3,h4",
    		numeric: true,
    		excluded: "Содержание,Примечание"
    	} );
    }

    Все параметры соответствуют предыдущим примерам.

    Опции numeric и excluded присутствуют лишь в доработанной версии.

    Итог

    На этом обзор скриптов можно считать завершённым, если что-нибудь останется непонятным – всегда отвечу в комментариях. В заключении добавлю развёрнутую копию своей версии файла для детального изучения кода.

    (function ($) {
    	"use strict";
    	var toc = function (options) {
    		return this.each(function () {
    			var root = $(this),
    				data = root.data(),
    				thisOptions, stack = [root],
    				listTag = this.tagName,
    				currentLevel = 0,
    				headingSelectors, excludedHeaders;
    			thisOptions = $.extend({
    				content: "body",
    				headings: "h1,h2,h3",
    				numeric: false,
    				excluded: ""
    			}, {
    				content: data.toc || undefined,
    				headings: data.tocHeadings || undefined,
    				numeric: data.tocNumeric || undefined,
    				excluded: data.tocExcluded || undefined
    			}, options);
    			headingSelectors = thisOptions.headings.split(",");
    			excludedHeaders = function (text) {
    				if ($.inArray(text, thisOptions.excluded.split(",")) !== -1) {
    					return true
    				}
    			};
    			$(thisOptions.content).find(thisOptions.headings).attr("id", function (index, attr) {
    				var generateUniqueId = function (text) {
    					if (excludedHeaders(text)) {
    						return
    					}
    					if (thisOptions.numeric === true) {
    						var prefix = "_";
    						text = 1;
    						while (document.getElementById(prefix + text) !== null) {
    							text++
    						}
    						return prefix + text
    					} else {
    						if (text.length === 0) {
    							text = "?"
    						}
    						var baseId = text.replace(/\s+/g, "_"),
    							suffix = "",
    							count = 1;
    						while (document.getElementById(baseId + suffix) !== null) {
    							suffix = "_" + count++
    						}
    						return baseId + suffix
    					}
    				};
    				return attr || generateUniqueId($(this).text())
    			}).each(function () {
    				var elem = $(this),
    					level = $.map(headingSelectors, function (selector, index) {
    						return elem.is(selector) ? index : undefined
    					})[0];
    				if (excludedHeaders(elem.text())) {
    					return
    				}
    				if (level > currentLevel) {
    					var parentItem = stack[0].children("li:last")[0];
    					if (parentItem) {
    						stack.unshift($("<" + listTag + "/>").attr("class", "d-flex flex-wrap flex-column nav-pills pl-4").appendTo(parentItem))
    					}
    				} else {
    					stack.splice(0, Math.min(currentLevel - level, Math.max(stack.length - 1, 0)))
    				}
    				$("<li/>").attr("class", "nav-item").appendTo(stack[0]).append($("<a/>").text(elem.text()).attr("href", "#" + elem.attr("id")).attr("class", "nav-link px-2 py-1"));
    				currentLevel = level
    			})
    		})
    	},
    	old = $.fn.toc;
    	$.fn.toc = toc;
    	$.fn.toc.noConflict = function () {
    		$.fn.toc = old;
    		return this
    	};
    	$(function () {
    		toc.call($("[data-toc]"))
    	})
    })(window.jQuery);

    Вас могут заинтересовать статьи о том, как реализовать алфавитный указатель, или пагинацию на Bootstrap для WordPress.