Как сделать оглавление статьи

Автор этого кода Тимур Камаев (wp-kama.ru). У него очень много всего интересного на сайте есть. Толковый парень, пишет полезный функционал и следит за чистотой кода.

Сразу скажу, что код отлично работает я устанавливал по методике, описанной ниже — все было ОК. Если вы будете делать все также, то у вас проблем с установкой возникнуть не должно.

Содержание

Tarchyshnik Andrei / Shutterstock.com

Как установить содержание

1. Скопируйте код с описанием класса Kama_Contents

/**
* Содержание для больших постов.
* Автор: Тимур Камаев (wp-kama.ru)
* Страница: http://wp-kama.ru/?p=1513
* Версия: 2.1.4
*/
class Kama_Contents {
var $margin; // отступ слева у подразделов в пикселях. 40
var $def_tags; // теги по умолчанию по котором будет строиться содеражние. Порядок имеет значение. array('h2','h3','h4')
var $to_menu; // ссылка на возврат к содержанию. '' - убрать ссылку
var $css; // css стили. '' - убрать стили
var $title; // Заголовок. '' - убрать заголовок

var $temp;
protected static $instance;

function __construct( $args ){
$this->margin = isset( $args['margin'] ) ? (int) $args['margin'] : 40;
$this->def_tags = isset( $args['def_tags'] ) ? $args['def_tags'] : array('h2','h3','h4');
$this->css = isset( $args['css'] ) ? $args['css'] : '.kc_gotop{ display:block; text-align:right; } .kc_title{ font-style:italic; padding:10px 0 10px; }';
$this->to_menu = isset( $args['to_menu'] ) ? $args['to_menu'] : 'к содержанию ↑';
$this->title = isset( $args['title'] ) ? $args['title'] : 'Содержание:';
}

public static function init( $args = array() ){
is_null( self::$instance ) AND self::$instance = new self( $args );
return self::$instance;
}

## обрабатывает текст превращает шоткод в нем в содержание
function shortcode( $content ){
// получаем данные о содержании
if( ! preg_match('~^(.*)\[contents([^\]]*)\](.*)$~s', $content, $m ) )
return $content;

if( $tags = trim( $m[2] ) )
$tags = array_map('trim', explode(' ', $tags ) );

$contents = $this->make_contents( $m[3], $tags );

return $m[1] . $contents . $m[3];
}

## Создает содержание и заменяет заголовки в переданном тексте
function make_contents( & $content, $tags = array() ){
$this->temp = new stdClass;

if( ! $tags ) $tags = $this->def_tags;

$this->temp->tag_level = array_flip( $tags ); // перевернем

// заменяем все заголовки и собираем содержание в $this->temp->contents
$h_patt = implode('|', $tags );
$content = preg_replace_callback('@<(?:'. $h_patt .')[^>]*>(.*?)</('. $h_patt .')>@is', array( $this, 'make_contents_callback'), $content, -1, $count );

if( ! $count ) return '';

// html содержания
$contents = '';
if( $this->title )
$contents .= '<div class="kc_title" id="kcmenu">'. $this->title .'</div>'. "\n";

$contents .= '<ul class="contents"'. (!$this->title ? ' id="kcmenu"' : '') .'>'. "\n" .
implode('', $this->temp->contents ) .
'</ul>'."\n";

$this->temp = new stdClass; // чистим

static $css;
$css = ( ! $css && $this->css ) ? '<style>'. $this->css .'</style>' : '';

return $css . $contents;
}

## callback функция для замены и сбора содержания
function make_contents_callback( $match ){
$tag = $match[2];
$anchor = $tag .'_'. ++$this->temp->i;

if( 0 < $level = $this->temp->tag_level[ $tag ] )
$sub = ( $this->margin ? ' style="margin-left:'. ($level*$this->margin) .'px;"' : '') . ' class="sub sub_'. $level .'"';
else
$sub = ' class="top"';

// собираем содержание
$this->temp->contents[] = "\t". '<li'. $sub .'><a href="#'. $anchor .'">'. $match[1] .'</a></li>'. "\n";

// заменяем
$out = '';
if( $this->to_menu )
$out .= $this->temp->i == 1 ? '' : '<a class="kc_gotop" href="#kcmenu">'. $this->to_menu .'</a>';
$out .= "<$tag id=\"$anchor\">$match[1]</$tag>";

return $out;
}
}

2.  Вставьте его в конец файла темы functions.php (Внешний вид → Редактор → functions.php).

Возможности вывода меню

  • Оглавление в тексте с помощью шорт-кода [contents]
  • Оглавление вверху каждого поста
  • Оглавление в сайдбаре

Я предпочитаю автоматический вывод в каждой статье, поэтому рекомендую упростить себе работу.

Как автоматически вывести содержание для каждой статьи

Добавьте в тот же файл темы functions.php этот код:

[cc lang=»php»]
## Вывод содержания вверху, автоматом для всех постов
add_filter(‘the_content’, ‘contents_on_post_top’ );
function contents_on_post_top( $content ){
if( ! is_singular() ) return $content;

//$args[‘margin’] = 50;
//$args[‘to_menu’] = false;
//$args[‘title’] = false;
$tags = array(‘h2′,’h3’);
$contents = Kama_Contents::init( $args )->make_contents( $content, $tags );
return $contents . $content;
}
[/cc]

Содержание будет генерироваться по указанным тегам array (‘h2′,’h3’), которые присутствуют в статье.

Да и еще один важный момент — содержание можно закрывать в noindex.