skip to Main Content

I have created a table of content filter hook which matched the header tag and put it in the table of content div. The div renders before the the_content filter. But, I am trying to render it in a specific div.

The part of single.php where I want to render the table of content is as below:

<div class="container programs">
        <div class="my-4">
            <h2 class="title-underline"><?php echo the_title(); ?></h2>
        </div>
        <div class="overview-nav">
            <div>
                <h3>Overview</h3>
                <p><?php the_excerpt(); ?></p>
            </div>
           //Part where table of content should render. Unfortunately the below code does not work
            <?php

                if(function_exists("add_table_of_content")){
                    add_table_of_content();
                }

            ?>
        </div>
        <?php the_content(); ?>
    </div>

The function for table of content is as below:

//Table of Content
function get_toc($content) {
    $headings = get_headings($content);
    if(count($headings)>0){
      ob_start();
      echo "<div class='table-of-contents'>";
      echo "<div class='heading'>";
      echo toc_print($headings, 0);
      echo "</div>";
      echo "</div>";
      return ob_get_clean();
    }
    return "";
  }

  function single_heading($heading, $flags){

    if($heading['tag'] == 2 && $flags[0]){
    }
    elseif($heading['tag'] == 3 && $flags[1]){
    }
    elseif($heading['tag'] == 4 && $flags[2]){
    }
    elseif($heading['tag'] == 5 && $flags[3]){
    }
    elseif($heading['tag'] == 6 && $flags[4]){
    }
    else{
      return "";
    }
    return "<li>"."<a href=#".str_replace(" ", "_", $heading['name']).">".$heading['name']."</a>"."</li>";
  }

  function toc_print( $a, $depth) {
    $flags = array(
      get_theme_mod("toc_heading2", 1),
      get_theme_mod("toc_heading3", 1),
      get_theme_mod("toc_heading4", 1),
      get_theme_mod("toc_heading5", 1),
      get_theme_mod("toc_heading6", 1),
    );

    $r = "<ul>";
    $depth = 2;
    $depth_save = 2;
    foreach($a as $key => $tag){
        if($tag['tag']==$depth){
            $r = $r.single_heading($tag, $flags);
        }
        elseif($tag['tag']>$depth){
            $r = $r.str_repeat("<li><ul>", $tag['tag']-$depth).single_heading($tag, $flags);
            $depth = $tag['tag'];
        }
        else{
            $r = $r.str_repeat("</ul></li>", $depth - $tag['tag']).single_heading($tag, $flags);
            $depth = $tag['tag'];

        }
    }
    $r = $r.str_repeat("</ul>", $depth-$depth_save+1);
    return $r;
 }

  function get_headings($content) {
    $headings = array();
    preg_match_all("/<h([1-6])(.*)>(.*)</h[1-6]>/", $content, $matches);
    
    for($i = 0; $i < count($matches[1]); $i++) {
      $headings[$i]["tag"] = $matches[1][$i];

      $att_string = $matches[2][$i];
      preg_match("/id="([^"]*)"/", $att_string , $id_matches);

      if(count($id_matches)>1){
        $headings[$i]["id"] = $id_matches[1];
      }
      
      $att_string = $matches[2][$i];
      preg_match_all("/class="([^"]*)"/", $att_string , $class_matches);
      for($j = 0; $j < count($class_matches[1]); $j++) {
        $headings[$i]["classes"][] = $class_matches[1][$j];
      }
      $headings[$i]["name"] = $matches[3][$i];
    }
    return $headings;
  }

  function headingwraps( $matches ) {

    $headings = array();
  
    if(count($matches)>2){
      foreach($matches[2] as $key => $heading){
        $h = "<h".$matches[1][$key]." ";
        $h = $h." ".$heading." ";
        $h = $h.">";
        $h = $h."<span class='toc-span' id='".str_replace(" ", "_", $matches[3][$key])."'></span>";
        $h = $h.$matches[3][$key];
        $h = $h."<span class='toc-span-end' ></span>";
        $h = $h."</h".$matches[1][$key].">";
        array_push($headings, $h);
      }
      return $headings;
    }

    return $headings;
  }

  function add_table_of_content($content) {
    if (get_post_type()!="post") return $content;

    $result = preg_match_all("/<h([1-6])(.*)>(.*)</h[1-6]>/", $content, $matches);
    $headingwrapped = headingwraps($matches);

    $paragraphs = explode("</p>", $content);
    $paragraphs_count = count($paragraphs);
    $new_content = '';
    for ($i = 0; $i < $paragraphs_count; $i++) {
        if ($i === 0) {
            $new_content .= get_toc($content);
        }
            $new_content .= $paragraphs[$i] . "</p>";
    }
    foreach($headingwrapped as $key => $headingrep){
        $new_content = str_replace($matches[0][$key], $headingrep, $new_content);
    }
    return $new_content;

  }

add_filter('the_content', 'add_table_of_content');

I tried to use add_shortcode filter hook to create a shortcode and put that shortcode to that specific div.

<?php echo do_shortocode("add_tale_of_content"); ?>

This did not work.

Updated code using shortcode

//in function.php
add_shortcode('the_content', 'add_table_of_content');

//to render in front end
<?php do_shortcode('add_table_of_content'); ?>

2

Answers


  1. You have to use the name of the shortcode and not the name of the function.

    So if you define your shortcode:

    //in function.php
    add_shortcode('name_of_your_shortcode', 'add_table_of_content');
    
    //to render in front end
    <?php do_shortcode('name_of_your_shortcode'); ?>
    
    Login or Signup to reply.
  2. Why do you use shortcode? You can call the function directly with the below changes:

    <div class="container programs">
        <div class="my-4">
            <h2 class="title-underline"><?php echo the_title(); ?></h2>
        </div>
        <div class="overview-nav">
            <div>
                <h3>Overview</h3>
                <p><?php the_excerpt(); ?></p>
            </div>
            <?php
                //Part where table of content should render.
                $content = get_the_content();
                if (get_post_type() =="post"){
                    echo get_toc($content);
                }
                ?>
        </div>
        <?php echo $content; // This line was changed too ?>
    </div>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search