Dipublikasikan: 6 Desember 2025
Terakhir diperbarui: 6 Desember 2025
Dipublikasikan: 6 Desember 2025
Terakhir diperbarui: 6 Desember 2025
Raymond Kelvin Nando — Berikut adalah Reading Time & Table Of Content – Script Code PHP,
Anda bisa menempelkan kode dibawah ini di functions.php atau bisa melalui plugins WPCodePro.
Fitur – Fitur :
<?php
if (!is_admin()) {
/* ============================================================= */
/* PHP — Reading Time + TOC */
/* ============================================================= */
add_filter('the_content', function($content) {
if (!is_single()) return $content;
/* === Reading Time === */
$text = wp_strip_all_tags(get_post_field('post_content', get_the_ID()));
$word_count = str_word_count($text);
$minutes = ceil($word_count / 200);
$reading_time_html = '
<div id="wpcode-reading-time">
<span class="rt-clock">⏱</span> '.$minutes.' min read
<div id="wpcode-progressbar"></div>
</div>
';
/* === Collect Headings === */
preg_match_all('/<h([2-4]).*?>(.*?)<\/h[2-4]>/', $content, $matches, PREG_SET_ORDER);
$toc_html = '';
if ($matches) {
$toc_html .= '
<div id="wpcode-toc">
<div class="toc-title">Daftar Isi</div>
<ul class="toc-level toc-lvl-2">
';
$current_lvl = 2;
foreach ($matches as $i => $match) {
$lvl = intval($match[1]);
$title = strip_tags($match[2]);
$id = "section-".($i+1);
$content = str_replace(
$match[0],
'<h'.$lvl.' id="'.$id.'">'.$match[2].'</h'.$lvl.'>',
$content
);
while ($current_lvl < $lvl) {
$current_lvl++;
$toc_html .= '<ul class="toc-level toc-lvl-'.$current_lvl.'">';
}
while ($current_lvl > $lvl) {
$toc_html .= '</ul>';
$current_lvl--;
}
$toc_html .= '
<li class="toc-item level-'.$lvl.'">
<span class="toc-arrow">▸</span>
<a href="#'.$id.'">'.$title.'</a>
</li>
';
}
while ($current_lvl > 2) {
$toc_html .= '</ul>';
$current_lvl--;
}
$toc_html .= '</ul></div>';
}
return $reading_time_html . $toc_html . $content;
});
/* ============================================================= */
/* CSS */
/* ============================================================= */
add_action('wp_head', function() { ?>
<style>
#wpcode-progressbar{
margin-top:6px;height:3px;width:0%;
background:var(--cs-accent,#0073ff);
border-radius:2px;
}
/* sidebar desktop */
#wpcode-sidebar-left{
position:fixed;
top:120px;
left:max(0px,calc((100vw - var(--cs-container-width,1140px))/2 - 240px));
width:240px;
padding:18px;
background:#fff;
border-radius:14px;
border:1px solid rgba(0,0,0,.08);
font-size:14px;
opacity:0;
animation:fadeIn .4s ease forwards;
z-index:9999;
}
@keyframes fadeIn{
from{opacity:0;transform:translateX(45px);}
to{opacity:1;transform:translateX(15px);}
}
/* TOC */
#wpcode-toc ul{list-style:none;margin:0;padding-left:0;}
#wpcode-toc li{margin:6px 0;display:flex;align-items:center;gap:6px;}
.toc-arrow{font-size:12px;opacity:.6;transition:.2s;cursor:pointer;}
.level-3{padding-left:14px;}
.level-4{padding-left:26px;}
#wpcode-toc a{color:inherit!important;text-decoration:none;}
.toc-item.active > a{
font-weight:700;
color:var(--cs-accent,#0073ff)!important;
}
.toc-item.active .toc-arrow{
transform:rotate(90deg);
opacity:1;
}
#wpcode-reading-time{margin-bottom:12px;font-weight:600;}
/* ==== AUTO-COLLAPSE H3–H4 ==== */
#wpcode-toc .toc-lvl-3,
#wpcode-toc .toc-lvl-4 {
display:none;
}
.toc-item.open > ul {
display:block !important;
}
/* ========================= */
/* MOBILE MODE */
/* ========================= */
@media(max-width:992px){
#wpcode-sidebar-left{display:none!important;}
#wpcode-mobile-btn{
position:fixed;
right:16px;
bottom:100px;
background:#0073ff;
color:#fff;
padding:10px 14px;
border-radius:50px;
font-size:14px;
font-weight:600;
box-shadow:0 4px 12px rgba(0,0,0,.25);
z-index:99999;
cursor:pointer;
}
#wpcode-mobile-panel{
position:fixed;
bottom:-100%;
left:0; right:0;
height:60%;
background:#fff;
border-radius:18px 18px 0 0;
box-shadow:0 -6px 18px rgba(0,0,0,.18);
padding:18px;
overflow-y:auto;
transition:bottom .35s ease;
z-index:999999;
}
#wpcode-mobile-panel.open{
bottom:0;
}
}
</style>
<?php });
/* ============================================================= */
/* JS */
/* ============================================================= */
add_action('wp_footer', function() { ?>
<script>
document.addEventListener("DOMContentLoaded", function() {
const rt = document.querySelector("#wpcode-reading-time");
const toc = document.querySelector("#wpcode-toc");
/* ========== DESKTOP SIDEBAR ========== */
if (window.innerWidth >= 992) {
if (rt || toc){
const sidebar = document.createElement("div");
sidebar.id = "wpcode-sidebar-left";
if (rt) sidebar.appendChild(rt);
if (toc) sidebar.appendChild(toc);
document.body.appendChild(sidebar);
}
}
/* ========== MOBILE PANEL ========== */
if (window.innerWidth < 992) {
if (rt || toc){
const btn = document.createElement("div");
btn.id = "wpcode-mobile-btn";
btn.innerText = "Daftar Isi";
document.body.appendChild(btn);
const panel = document.createElement("div");
panel.id = "wpcode-mobile-panel";
if(rt) panel.appendChild(rt);
if(toc) panel.appendChild(toc);
document.body.appendChild(panel);
btn.addEventListener("click", ()=> panel.classList.toggle("open"));
document.addEventListener("click", function(e){
if (!panel.contains(e.target) && !btn.contains(e.target)){
panel.classList.remove("open");
}
});
}
}
/* ========== PROGRESS BAR ========== */
const bar = document.querySelector("#wpcode-progressbar");
if(bar){
window.addEventListener("scroll", () => {
let h = document.documentElement;
bar.style.width = (h.scrollTop / (h.scrollHeight - h.clientHeight)) * 100 + "%";
});
}
/* ========== TOC BEHAVIOR ========== */
const headerOffset = 120;
const headings = document.querySelectorAll("h2[id],h3[id],h4[id]");
const tocLinks = document.querySelectorAll("#wpcode-toc a");
/* CLICK — EXPAND H3–H4 */
tocLinks.forEach(a => {
a.addEventListener("click", function(e){
e.preventDefault();
const id = this.getAttribute("href").substring(1);
const el = document.getElementById(id);
if (!el) return;
const top = el.offsetTop - headerOffset;
window.scrollTo({ top: top, behavior: "smooth" });
setTimeout(()=> {
activate(id);
const li = this.parentElement;
li.classList.add("open");
}, 250);
});
});
/* SCROLL SPY */
window.addEventListener("scroll", () => {
let scrollPos = window.scrollY + headerOffset + 60;
headings.forEach(h => {
if (h.offsetTop <= scrollPos && (h.offsetTop + h.offsetHeight) > scrollPos) {
activate(h.id);
}
});
});
/* MARK ACTIVE + EXPAND PARENTS */
function activate(id){
document.querySelectorAll(".toc-item").forEach(li => li.classList.remove("active"));
const active = document.querySelector(`#wpcode-toc a[href="#${id}"]`);
if (!active) return;
const li = active.parentElement;
li.classList.add("active");
/* AUTO-EXPAND PARENTS */
let parent = li.parentElement;
while(parent && parent.id !== "wpcode-toc"){
if (parent.classList.contains("toc-level")){
const parentLi = parent.parentElement;
if (parentLi.classList.contains("toc-item")){
parentLi.classList.add("open");
}
}
parent = parent.parentElement;
}
}
});
</script>
<?php });
}
Untuk tampilan front-endnya bisa disesuaikan pada masing – masing tema anda, Semoga bermanfaat.