Create a table of contents in Oxygen Builder

ARTRU

Why don't I use a table of contents plugin?

For "low tech" brothers, just hit the TOC plugin for fast, neat and quick. I myself like to play around because this "table of contents" is not a big deal, but for it to work well, it also needs to be configured properly.

I used to use Gutenberg's TOC. Everything was great until I decided to change to another plugin. I have to delete the block that creates the table of contents for each article, Oh! Oh my God. Luckily, I only had about 10 posts back then.

From that day on, I decided to change which plugin has the function of automatically creating a table of contents according to the heading tag title. Too bad there is nothing that makes the picture happy, if it's genuine, you have to pay a fee.

Thanks to AI technology like ChatGPT, Bard, Bing, I can create "home-made TOC".

How to create a table of contents correctly?

Before creating a TOC, we need to understand how to configure the table of contents to be SEO-friendly and user-friendly.

There are plugins that create a table of contents automatically but set heading tags as id="section-1" and the link pointing to this heading tag is href="#section-1".

So you need to pay attention to these little details. Currently there may not be much demand for this issue.

Here are a few standard link anchor examples:

Smooth Scroll (Smooth Scroll)

Help users feel more comfortable, more eye-catching.

It is especially useful to use a url with a #hashtag sent from another site to help users know where this #hashtag item is located in the article.

Sticky (Pin) table of contents

This is also a good feature for users. When reading the article they can know where they are reading the article instead of having to scroll to the top of the page to check the table of contents.

Currently, I have not used this feature for the website. Will update if there are any changes.

Instructions for creating a table of contents

These codes I apply to the Oxygen Builder drag and drop. You can also apply to other Builders and Themes.

Code to create table of contents automatically

The code below has the function:

  • Create cards <a> according to h2-h6 in the article content.
  • Add attributes href="#" to the cards <a>.
  • Sort the cards <a> according to the rule of recursion <ol> <li>

Put PHP Code This places the position where you want the table of contents to be displayed.

/* MÃ PHP TẠO MỤC LỤC TỰ ĐỘNG H2-H6. SỬ DỤNG get_the_content() */
function generate_toc($content)
{
	preg_match_all('/<h([2-6]).*?>(.*?)<\/h\1>/', $content, $matches, PREG_SET_ORDER);
	$toc           = '<ol id="tocList">';
	$current_level = 2;
	foreach ($matches as $match)
	{
		$level         = $match[1];
		$heading       = $match[2];
		$id            = sanitize_title($heading);
		if ($level > $current_level)
		{
			$toc .= str_repeat('<ol>', $level - $current_level) . '<li><a href="#' . $id . '">' . $heading . '</a>';
		}
		else if ($level < $current_level)
		{
			$toc .= str_repeat('</li></ol>', $current_level - $level) . '</li><li><a href="#' . $id . '">' . $heading . '</a>';
		}
		else
		{
			$toc .= '</li><li><a href="#' . $id . '">' . $heading . '</a>';
		}
		$current_level = $level;
	}
	$toc .= str_repeat('</li></ol>', $current_level - 2);
	$content = '<div id="tocDiv"><p>MỤC LỤC</p>' . $toc . '</div>';
	return $content;
};
$content          = get_the_content();
$content_with_toc = generate_toc($content);
echo $content_with_toc;

After applying the above code, the table of contents will have the following structure:

<div id="tocDiv">
	<p>MỤC LỤC</p>
	<ol id="tocList">
		<!-- Danh sách mục lục -->
		<li></li>
		<li></li>
		<li></li>
	</ol>
</div>

Add "id" attribute to heading tags

This is for the purpose that when the user clicks on the link in the table of contents, they will move to the correct heading tag.

PHP Code to add the id for the heading tags that should be put in the file function.php in child theme or create more mu-plugins or maybe the same place where you put the code to create the table of contents above, but I don't recommend this way.

/* MÃ PHP TẠO THUỘC TÍNH ID CHO CÁC THẺ HEADING H2-H6 TRONG NỘI DUNG BÀI VIẾT */
function prefix_heading_ids($content)
{
	$pattern = '#(?P<full_tag><(?P<tag_name>h\d)(?P<tag_extra>[^>]*)>(?P<tag_contents>[^<]*)</h\d>)#i';
	if (preg_match_all($pattern, $content, $matches, PREG_SET_ORDER))
	{
		$find    = array();
		$replace = array();
		foreach ($matches as $match)
		{
			if (strlen($match['tag_extra']) && false !== stripos($match['tag_extra'], 'id='))
			{
				continue;
			}
			$find[]         = $match['full_tag'];
			$id      = sanitize_title($match['tag_contents']);
			$id_attr = sprintf(' id="%s"', $id);
			$replace[]         = sprintf('<%1$s%2$s%3$s>%4$s</%1$s>', $match['tag_name'], $match['tag_extra'], $id_attr, $match['tag_contents']);
		}
		$content = str_replace($find, $replace, $content);
	}
	return $content;
}
add_filter('the_content', 'prefix_heading_ids');

Recursively sort CSS code for table of contents

Below is the recursively sort CSS code for the wrapped table of contents <div> have id=&quot;tocDiv&quot; and <ol> has id=&quot;tocList&quot;.

#tocDiv {
	width: 100%;
	border-radius: 10px;
	box-shadow: 5px 5px 10px 5px rgba(0, 0, 0, 0.5);
	overflow: hidden;
	margin: 50px 0px 50px 0px;
}
#tocDiv p {
	font-weight: bold;
	text-align: center;
	display: block;
}
#tocDiv ol {
	list-style: none;
}
#tocList {
	padding-left: 20px;
	white-space: nowrap;
	overflow-x: auto;
	padding-bottom: 20px;
	margin-bottom: 0px;
}
#tocList a {
	margin-right: 10px;
}
#tocList ol {
	padding-left: 20px;
}
#tocList {
	counter-reset: item;
}
#tocList>li:before {
	counter-increment: item;
	content: counter(item) ". ";
}
#tocList>li>ol {
	counter-reset: item2;
}
#tocList>li>ol>li:before {
	counter-increment: item2;
	content: counter(item) "." counter(item2) " ";
}
#tocList>li>ol>li>ol {
	counter-reset: item3;
}
#tocList>li>ol>li>ol>li:before {
	counter-increment: item3;
	content: counter(item) "." counter(item2) "." counter(item3) " ";
}
#tocList>li>ol>li>ol>li>ol {
	counter-reset: item4;
}
#tocList>li>ol>li>ol>li>ol>li:before {
	counter-increment: item4;
	content: counter(item) "." counter(item2) "." counter(item3) "."
		counter(item4) " ";
}
#tocList>li>ol>li>ol>li>ol>li>ol {
	counter-reset: item5;
}
#tocList>li>ol>li>ol>li>ol>li>ol>li:before {
	counter-increment: item5;
	content: counter(item) "." counter(item2) "." counter(item3) "."
		counter(item4) "." counter(item5) " ";
}

CSS Code smooth scrolling effect while making the heading 100px from the top so it's not obscured by the Header.

html {
	scroll-behavior: smooth;
}
:target {
	scroll-margin-top: 100px;
}
COMMENT

Related Articles