Create a table of contents in Oxygen Builder
TABLE OF CONTENTS
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.
Friendly Anchor Link
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:
- Test this link in ARTRU's site.
- This link points to WPcanban's "# Hide unused menus".
- This link points to "# Table of Contents Title" by Rank Math.
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="tocDiv" and <ol> has id="tocList".
#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;
}
Related Articles