Skip to content

Instantly share code, notes, and snippets.

@livingstonef
Last active December 15, 2015 20:29
Show Gist options
  • Save livingstonef/5318759 to your computer and use it in GitHub Desktop.
Save livingstonef/5318759 to your computer and use it in GitHub Desktop.
Here is a quick example of how to use the LFT_Toc but have the TOC in a sidebar or anywhere else
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* video.php
*
* Requires PHP version 5.0 or more
*
* LICENSE: This source file is subject to version 3.01 of the GNU/GPL License
* that is available through the world-wide-web at the following URI:
* http://www.gnu.org/licenses/gpl.txt If you did not receive a copy of
* the GPL License and are unable to obtain it through the web, please
* send a note to support@livingstonefultang.com so we can mail you a copy immediately.
*
* @author Livingstone Fultang <livingstone.fultang@gmail.com>
* @copyright 1997-2012 Stonyhills HQ
* @license http://www.gnu.org/licenses/gpl.txt. GNU GPL License 3.01
* @version Release: 1.0.3
*
*/
class LFT_Toc {
/**
* Counts the occurence of header elements in Wordpress content
*
* @param type $content
* @return null|boolean|array
*/
static function hasToc($tiers, $content) {
$pattern = '/<h[2-' . $tiers . ']*[^>]*>(.*?)<\/h([2-' . $tiers . '])>/';
$return = array();
if (empty($content))
return null;
if (!preg_match_all($pattern, $content, $return)) {
return false;
}
return $return;
}
/**
* Generates a table of content only when singular pages are being viewed
*
* @param int $tiers The number of layers of hx tags to index, i.e h2-h6
* @param string $content The Post content
* @param boolean $draw if true will draw the TOC, false will return the toc items
* @param array $return holds the found htags in the $content if hasToc was previously called
* @param int $minimal The minimal number of items required for a TOC to be displayed
*
* @return string
*/
static function generateTableOfContents($tiers, $content, $draw = FALSE, $return = array(), $minimal = 3) {
if (!is_singular())
return $content;
$content = $toc . $content;
$searches = array();
$replaces = array();
$return = (is_array($return) && !empty($return) ) ? $return : LFT_Toc::hasToc($tiers, $content);
if (!empty($return)):
$toc = '<div class="toc pull-left span4">';
$toc .= "<h4>Table of Contents</h4>";
$toc .= "<ol class=\"parent start\">";
$tags = reset($return);
$titles = $return[1];
$levels = end($return);
$_level = 2;
$chapters = array('0', '0', '0', '0', '0', '0');
//We will only display a toc if we have more than 3 htags;
if (sizeof($tags) < $minimal)
return $content;
foreach ($tags as $i => $htag) {
$attributes = array();
$href = md5(str_replace(' ', '', $titles[$i]));
if (preg_match_all("/id=\"([^']*)\"/", $htag, $attributes)) {
$oldIds = end($attributes);
$href = md5(str_replace(' ', '', $titles[$i]) . reset($oldIds));
$newId = 'id="' . $href . '"';
$oldId = 'id="' . reset($oldIds) . '"';
$htagr = str_replace($oldId, $newId, $htag);
$searches[] = $htag;
$replaces[] = $htagr;
} else {
$newId = 'id="' . $href . '"';
$htagr = str_replace('>' . $titles[$i], "\t" . $newId . '>' . $titles[$i], $htag);
$searches[] = $htag;
$replaces[] = $htagr;
}
if ((int) $levels[$i] === (int) $_level):
$chapters[$_level - 1] = ((int) $chapters[$_level - 1] + 1);
$chapter = implode('.', array_slice($chapters, 1, ($levels[$i] - 1)));
$toc .= '<li><span class="toc-chapter">' . strval($chapter) . '</span><a href="#' . $href . '">' . $titles[$i] . '</a></li>';
endif;
if ($levels[$i] > $_level) {
$_steps = ((int) $levels[$i] - (int) $_level);
for ($j = 0; $j < $_steps; $j++):
$toc .= '<ol class="continue">';
$chapters[$levels[$i] - 1 + $j] = (int) $chapters[$levels[$i] - 1 + $j] + 1;
$_level++;
endfor;
$chapter = implode('.', array_slice($chapters, 1, ($levels[$i] - 1)));
$toc .= '<li><span class="toc-chapter">' . strval($chapter) . '</span><a href="#' . $href . '">' . $titles[$i] . '</a></li>';
}
if ($levels[$i] < $_level) {
$_steps = ((int) $_level - (int) $levels[$i]);
$chapters[$levels[$i] - 1] = (int) $chapters[$levels[$i] - 1] + 1;
$_olevel = $_level;
for ($j = 0; $j < $_steps; $j++):
$chapters[$levels[$i] + $j] = 0;
$toc .= '</ol>';
$_level--;
endfor;
$chapters[$_olevel - 1] = 0;
$chapter = implode('.', array_slice($chapters, 1, ($levels[$i] - 1)));
$toc .= '<li><span class="toc-chapter">' . strval($chapter) . '</span><a href="#' . $href . '">' . $titles[$i] . '</a></li>';
}
}
$toc .= '</ol>';
$toc .= '</div>';
endif;
$content = str_replace($searches, $replaces, $content);
if ( $draw ): //If we intend to print the TOC just above the content!
$content = $toc . $content;
else:
$content = array("toc"=>$toc,"content"=>$content);
endif;
return $content;
}
/**
* Appends the table of content to the $content
* AKA. Executes our filter
*
* @param type $content
* @return type
*/
static function writeToc($content, $tiers=4, $draw=FALSE) {
global $toc;
$formatted = LFT_Toc::generateTableOfContents($tiers, $content, $draw);
if(!is_array($formatted) ):
$toc = $formatted['toc'];
$content = $formatted['content'];
else:
$content = $formatted;
endif;
return $content;
}
}
add_filter('the_content', array('LFT_Toc', 'writeTOC'));
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* page-wiki.php
*
* Requires Wordpress 3.5
*
* LICENSE: This source file is subject to version 3.01 of the GNU/GPL License
* that is available through the world-wide-web at the following URI:
* http://www.gnu.org/licenses/gpl.txt If you did not receive a copy of
* the GPL License and are unable to obtain it through the web, please
* send a note to support@stonyhillshq.com so we can mail you a copy immediately.
*
* Template Name: Wiki Page
*
* @author Livingstone Fultang <livingstone.fultang@stonyhillshq.com>
* @copyright 1997-2012 Stonyhills HQ
*
*/
?>
<!-- Include the TOC class -->
<?php global $toc; $toc=null; ?>
<?php include_once( locate_template('/includes/toc.php') ); ?>
<?php get_header(); ?>
<div class="container">
<section>
<div class="row-fluid">
<div class="span8">
<div class="row-fluid">
<?php while (have_posts()) : the_post(); ?>
<div class="article-header clearfix">
<h1 class="pull-left"><?php the_title(); ?></h1>
</div>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<div class="row-fluid">
<div class="span12">
<div class="entry-content">
<!-- we will use the writeTOC method from the_content filter to generate the toc, and store in global $toc; -->
<?php the_content(); ?>
<?php wp_link_pages(array('before' => '<div class="page-link"><span>' . __('Pages:', 'conferencer') . '</span>', 'after' => '</div>')); ?>
</div><!-- .entry-content -->
</div>
</div>
<footer class="entry-meta">
<?php edit_post_link(__('Edit', 'conferencer'), '<span class="edit-link">', '</span>'); ?>
</footer><!-- .entry-meta -->
</article><!-- #post-<?php the_ID(); ?> -->
<?php comments_template('', true); ?>
<?php endwhile; // end of the loop. ?>
</div>
</div>
<div class="span4">
<div class="sidebar" style="padding-left">
<!-- In your sidebar you can print the global $toc; so echo($toc) -->
<!-- Print the Sidebar -->
<?php echo $toc; ?>
<?php get_sidebar(); ?>
</div>
</div>
</div>
</section>
<?php get_sidebar('before-footer'); ?>
</div>
<?php get_footer(); ?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment