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

Содержание

    Введение

    Добавим автоматическое содержание статьи 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.