Здравствуйте, дорогой читатель in4wp.ru — на связи опять я, скромный автор блога. Сегодня я бы хотел обсудить с вами со всеми такой несложный, но крайне важный вопрос : как сделать оглавление (содержание) статьи на вашем блоге, тем более этот вопрос важен, когда у вас длиннющая статья, типа этой.
На самом деле тут несколько вариантов, я опишу как плагины, так и варианты создания содержания статьи без плагинов! Так что читайте до конца, чтобы не пропустить ничего интересного.
Но сначала, по традиции оффтоп: меня второй день валит вирусня на хостинге. Кто сможет помочь? Я сейчас разбираюсь в этой теме и скоро напишу статейку. Так что не пропусти — подпишись!
Ну а мы переходим дальше.
Как создавать оглавление статьи средствами HTML?
Да, знания HTML все-таки нужны. И чем дальше в лес, в смысле, чем больше развивается IT индустрия — тем больше нужно будет знать, чтобы хотябы оставаться на плаву.
Но не будем о грустном :)
Итак, зачем нам HTML ? Всё очень просто. Я раньше делал в первых статьях своих (например этой или этой) — делал следующее:
Есть такое понятие в HTML — якорь! Это может быть даже пустой тег. Вот например.
И всё, внутри этого параграфа даже писать ничего не нужно.

Как только все якоря проставлены — осталось создать само содержание статьи — это также делается через HTML прямо в текстовом редакторе самой статьи.
Я делал это так:
…
Мой кусок кода
style="list-style-type:decimal;"
дает приказ показывать список в виде цифр по порядку. Вы ведь знаете, что обычно тег <li> дает список с точками слева. Так вот вместо этих точек будут цифры.
Ниже мы видим список пунктов. Причем в ссылке
Пункт 1
Мы видим не саму ссылку, а лишь ссылку на нужный якорь на этой же странице. После нажатия на подобную ссылку, у вас ссылка страницы примет вид:
http://ваш_сайт/урл_страницы#yakor1
Вот живой пример:
http://in4wp.ru/intervyu-s-maksimom-vojtikom-avtor-bloga-seoslim-ru/#guest
Эта ссылка ведет на интервью с Максимом Войтиком, причем именно на вопрос о том , когда он приедет ко мне в гости. Перейди — узнаешь.
Вот и всё, на seo оптимизацию это никак не влияет. Если вы переидете по подобной ссылке с другого сайта — вам откроется эта страница и сразу перекинет к этому абзацу, где стоит этот якорь.
Ну, надеюсь понятно объяснил. Если нет — задавайте вопросы в комментариях. А мы пойдем дальше.
Как создать содержание статьи без плагинов
На самом деле вариант с HTML вставками — вполне рабочий. Его можно использовать. Но блин, так много времени отнимает. Я, хоть и не сторонник левых кодов и функций на блоге, но мне пришлось признать, что подобная функция как автоматическое создание оглавления (содержания) статьи очень нужна и полезна на сайте,а тем более на блоге. Ведь у блоггеров зачастую бывают длинные, интересные и полезные статьи.
Не буду ходить вокруг да около, давайте к делу.
Идем в файл functions.php и вписываем туда функцию:
/**
* Содержание для больших постов.
* Автор: Тимур Камаев
* Страница: http://wp-kama.ru/?p=1513
* Версия: 2.8.7
*
* Changelog: http://wp-kama.ru/?p=1513#obnovleniya
*/
class Kama_Contents{
// defaults options
public $opt = array(
// Отступ слева у подразделов в px.
'margin' => 40,
// Теги по умолчанию по котором будет строиться содержание. Порядок имеет значение.
// Можно указать атрибут class элемента: array('.foo','.two'). Можно указать строкой: 'h2 h3 h4'
'selectors' => array('h2','h3','h4'),
// Ссылка на возврат к содержанию. '' - убрать ссылку
'to_menu' => 'к содержанию ↑',
// Заголовок. '' - убрать заголовок
'title' => 'Содержание:',
// Css стили. '' - убрать стили
'css' => '.kc-gotop{ display:block; text-align:right; } .kc-title{ font-style:italic; padding:1em 0; }',
// Минимальное количество найденных тегов, чтобы содержание выводилось.
'min_found' => 2,
// Минимальная длина (символов) текста, чтобы содержание выводилось.
'min_length' => 2000,
// Ссылка на страницу для которой собирается содержание. Если содержание выводиться на другой странице...
'page_url' => '',
// Название шоткода
'shortcode' => 'contents',
);
public $contents; // collect html contents
private $temp;
protected static $inst;
public function __construct( $args = array() ){
$this->set_opt( $args );
return $this;
}
## статический экземпляр
static function init( $args = array() ){
is_null( self::$inst ) && self::$inst = new self( $args );
//if( $args ) self::$inst->set_opt( $args );
return self::$inst;
}
public function set_opt( $args = array() ){
$this->opt = (object) array_merge( $this->opt, (array) $args );
}
/**
* Обрабатывает текст, превращает шоткод в нем в содержание.
* @param (string) $content текст, в котором есть шоткод.
* @return Обработанный текст с содержанием, если в нем есть шоткод.
*/
public function shortcode( $content ){
if( false === strpos( $content, '['. $this->opt->shortcode ) )
return $content;
// получаем данные о содержании
if( ! preg_match('~^(.*)\['. $this->opt->shortcode .'([^\]]*)\](.*)$~s', $content, $m ) )
return $content;
$contents = $this->make_contents( $m[3], $m[2] );
return $m[1] . $contents . $m[3];
}
/**
* Заменяет заголовки в переданном тексте (по ссылке), создает и возвращает содержание.
* @param (string) $content текст на основе которого нужно создать содержание.
* @param (array/string) $tags массив тегов, которые искать в переданном тексте.
* Можно указать: имена тегов "h2 h3" или классы элементов ".foo .foo2".
* @return html код содержания.
*/
public function make_contents( & $content, $tags = '' ){
if( mb_strlen( strip_tags($content) ) < $this->opt->min_length ) return; // выходим если текст короткий
$this->temp = new stdClass;
$this->temp->i = 0;
$this->contents = '';
if( is_string($tags) && $tags = trim($tags) ){
$tags = array_map('trim', preg_split('~\s+~', $tags ) );
}
if( ! $tags ) $tags = $this->opt->selectors;
// set patterns from given $tags
$class_patt = $tag_patt = '';
$level = array();
foreach( $tags as $k => $val ){
// class
if( $val{0} == '.' ){
$val = substr( $val, 1 );
$link = & $class_patt;
}
// html tag
else{
$link = & $tag_patt;
}
if( $link ) $link .= '|';
$link .= $val;
$level[] = $val;
}
$this->temp->tag_level = array_flip( $level );
// заменяем все заголовки и собираем содержание в $this->contents
$patt_in = array();
$patt_suffix = '>(.*?)';
if( $class_patt ) $patt_in[] = '(?:<([^\s]+)([^>]*class=["\'][^>]*('. $class_patt .')[^>]*["\'][^>]*)'. $patt_suffix .')';
if( $tag_patt ) $patt_in[] = '(?:<('. $tag_patt .')([^>]*)'. $patt_suffix .')';
$patt_in = implode('|', $patt_in );
// TODO убрать это ограничение, как-то... Регулярка не понимает одновременное foo|foo2 - выполняет либо/либо
if( count($patt_in) > 1 ) return __CLASS__ .': don`t use tags and attributes selectors in the same time - use separately';
$_content = preg_replace_callback("@$patt_in@is", array( &$this, '__make_contents_callback'), $content, -1, $count );
// preg_match_all("@$patt_in@is", $content, $m, PREG_SET_ORDER );
// die( print_r( $m ) );
if( ! $count || $count < $this->opt->min_found ) return;
$content = $_content; // опять работаем с важной $content
// html содержания
$contents = '';
if( $this->opt->title )
$contents .= '
‘. «\n»; $contents .= ‘
- opt->title ? ‘ id=»kcmenu»‘ : ») .’>’. «\n» . implode(», $this->contents ) . ‘
‘.»\n»; $this->contents = ‘
‘; static $css; $css = ( ! $css && $this->opt->css ) ? ‘
‘ : »; return $this->contents = $css . ‘
‘; } ## вырезает шоткод из контента public function strip_shortcode( $text ){ return preg_replace(‘~\[‘. $this->opt->shortcode .'[^\]]*\]~’, », $text ); } ## callback функция для замены и сбора содержания private function __make_contents_callback( $match ){ $tag = $match[1]; $attrs = $match[2]; if( count($match) == 4 ){ $level_tag = $match[1]; $title = $match[3]; } elseif( count($match) == 5 ){ $level_tag = $match[3]; $title = $match[4]; } else return ‘parse error of preg_replace_callback() in ‘. __CLASS__ .’ class’; $anchor = $this->__sanitaze_anchor( $title ); //die( print_r( $match ) ); $level = @ $this->temp->tag_level[ $level_tag ]; if( $level > 0 ) $sub = ( $this->opt->margin ? ‘ style=»margin-left:’. ($level*$this->opt->margin) .’px;»‘ : ») . ‘ class=»sub sub_’. $level .'»‘; else $sub = ‘ class=»top»‘; // собираем содержание $this->contents[] = «\t». ‘<li’. $sub .’>’. $title .’
‘. «\n»; // заменяем $out = »; if( $this->opt->to_menu ){ $out .= ++$this->temp->i == 1 ? » : ». $this->opt->to_menu .»; } $out .= ‘‘.»\n».'<‘. $tag . $attrs .’>’. $title .»; return $out; } ## транслитерация для УРЛ private function __sanitaze_anchor( $str ){ $conv = array( ‘а’=>’a’, ‘б’=>’b’, ‘в’=>’v’, ‘г’=>’g’, ‘д’=>’d’, ‘е’=>’e’, ‘ё’=>’e’, ‘ж’=>’zh’, ‘з’=>’z’, ‘и’=>’i’, ‘й’=>’y’, ‘к’=>’k’, ‘л’=>’l’, ‘м’=>’m’, ‘н’=>’n’, ‘о’=>’o’, ‘п’=>’p’, ‘р’=>’r’, ‘с’=>’s’, ‘т’=>’t’, ‘у’=>’u’, ‘ф’=>’f’, ‘х’=>’h’, ‘ц’=>’c’, ‘ч’=>’ch’, ‘ш’=>’sh’, ‘щ’=>’sch’, ‘ы’=>’y’, ‘э’=>’e’, ‘ю’=>’yu’, ‘я’=>’ya’, ‘А’=>’A’, ‘Б’=>’B’, ‘В’=>’V’, ‘Г’=>’G’, ‘Д’=>’D’, ‘Е’=>’E’, ‘Ё’=>’E’, ‘Ж’=>’Zh’, ‘З’=>’Z’, ‘И’=>’I’, ‘Й’=>’Y’, ‘К’=>’K’, ‘Л’=>’L’, ‘М’=>’M’, ‘Н’=>’N’, ‘О’=>’O’, ‘П’=>’P’, ‘Р’=>’R’, ‘С’=>’S’, ‘Т’=>’T’, ‘У’=>’U’, ‘Ф’=>’F’, ‘Х’=>’H’, ‘Ц’=>’C’, ‘Ч’=>’Ch’, ‘Ш’=>’Sh’, ‘Щ’=>’Sch’, ‘Ы’=>’Y’, ‘Э’=>’E’, ‘Ю’=>’Yu’, ‘Я’=>’Ya’, ); $str = strip_tags( $str ); $str = strtr( $str, $conv ); $str = strtolower( $str ); $str = preg_replace(«/[^a-z0-9′-_\.~+=\$\*]+/u», ‘-‘, $str ); // все ненужное на «-» $str = preg_replace(‘/-+/’, ‘-‘, $str ); //$str = trim( $str, ‘-‘); // начальные и конечные ‘-‘ return $str; } }
И всё!!!! Вуа-ля.
Представляете — все просто оказывается :)
Я не буду вдаваться в детали этого кода. Я думаю, вам это сейчас не очень интересно — главное — он работает!
Вопрос — как? Хороший вопрос.
Содержание или оглавление статьи создается на блоге, согласно вашей seo разметке, т.е. по заголовкам и подзаголовкам.
[tip]Заголовки H2 — это главы нашей статьи
Заголовки H3 — подглавы или как там их правильно назвать. [/tip]
У меня кстати есть подобные статьи, с разделениями. Но ниже чем H3 я уже не спускался. Вот пример.

[contents]
И будет вам счастье.
Осталось только стилизовать содержимое. Это всё делается через CSS классы, в файле style.css вашей темы. Если у вас возникнут с этим проблемы — обращайтесь. Если не хотите обращаться ко мне — рекомендую бесплатный [urlspan]курс по CSS[/urlspan].
Пользуясь случаем, хочу объявить о том, что у меня есть БЕСПЛАТНЫЙ курс по созданию блога с нуля — ПОЛУЧИТЬ КУРС. Помогаю новичкам в развитии.
[urlspan]Подписывайтесь[/urlspan] на обновления, чтобы не пропускать полезных статей.
А на сегодня у меня всё.
[bye]
Насчет Камы абсолютно согласна этот человек реально вносит вклад в развитие WordPress а, сама тоже пользуюсь его кодом. А насчет способа создания оглавления пусть каждый выбирает, как ему удобнее, хорошо, что есть альтернатива
Привет, Денис! А первый способ подойдет для любой CMS?
В общем попробовал на blogger сделать такое оглавление – не получилось… Или я что-то не так сделал (хотя проверил несколько раз), или же для blogspot этот способ не подходит…
А оглавления у вас хорошие получаются. Главное плавные переходы бы сделать.
Давно искал подробную инструкцию.
Спасибо большое 8)
Отлична статья