table-of-contents-plus
table-of-contents-plus copied to clipboard
Allow toc labels to be different from actual headings
It would be great to be able to override headings in the toc instead of just being able to exclude them.
My use-case is that I have headings that are too long to fit in a single line in my sidebar. I'd like to use shorter labels in the toc.
One approach would be a shorttag to define an override:
<h2>The actual heading[toc-label]The toc label[/toc-label]</h2>
It would also be sufficient to provide a filter hook in extract_headings()
so that the override can be implemented individually.
If anyone has the same issue, you can edit toc.php
to achieve this. In extract_headings()
after
// remove undesired headings (if any) as defined by heading_levels
if ( count($this->options['heading_levels']) != 6 ) {
$new_matches = array();
for ($i = 0; $i < count($matches); $i++) {
if ( in_array($matches[$i][2], $this->options['heading_levels']) )
$new_matches[] = $matches[$i];
}
$matches = $new_matches;
}
add this
for ($i = 0; $i < count($matches); $i++) {
$matches[$i][3] = $matches[$i][0]; //save original match for anchor injection
$matches[$i][4] = preg_replace('/\[toc-label\].*\[\/toc-label\]/', '', $matches[$i][0]); //save title without shorttag
$label = preg_replace(array('/.*\[toc-label\]/', '/\[\/toc-label\].*/'), '', $matches[$i][0]);
$matches[$i][0] = '</h' . $matches[$i][2] . '>' . $matches[$i][1] . $label . '</h' . $matches[$i][2] . '>';
}
and replace
for ($i = 0; $i < count($matches); $i++) {
// get anchor and add to find and replace arrays
$anchor = $this->url_anchor_target( $matches[$i][0] );
$find[] = $matches[$i][0];
$replace[] = str_replace(
array(
$matches[$i][1], // start of heading
'</h' . $matches[$i][2] . '>' // end of heading
),
array(
$matches[$i][1] . '<span id="' . $anchor . '">',
'</span></h' . $matches[$i][2] . '>'
),
$matches[$i][0]
);
// assemble flat list
if ( !$this->options['show_heirarchy'] ) {
$items .= '<li><a href="#' . $anchor . '">';
if ( $this->options['ordered_list'] ) $items .= count($replace) . ' ';
$items .= strip_tags($matches[$i][0]) . '</a></li>';
}
}
with
for ($i = 0; $i < count($matches); $i++) {
// get anchor and add to find and replace arrays
$anchor = $this->url_anchor_target( $matches[$i][0] );
$find[] = $matches[$i][3]; // <= use original match
$replace[] = str_replace(
array(
$matches[$i][1], // start of heading
'</h' . $matches[$i][2] . '>' // end of heading
),
array(
$matches[$i][1] . '<span id="' . $anchor . '">',
'</span></h' . $matches[$i][2] . '>'
),
$matches[$i][4] // <= use title without shorttag
);
// assemble flat list
if ( !$this->options['show_heirarchy'] ) {
$items .= '<li><a href="#' . $anchor . '">';
if ( $this->options['ordered_list'] ) $items .= count($replace) . ' ';
$items .= strip_tags($matches[$i][0]) . '</a></li>';
}
}
but editing the plugin means future updates will override it.
This is true, unless the next update (if any) includes this functionality itself. But it is the only sane workaround I have found.