This post was published in 2020-11-25. Obviously, expired content is less useful to users if it has already pasted its expiration date.
评测几个wordpress TOC(Table of Contents)插件,并附上我的解决方案。本文仅涉及wordpress主流市场的现成解决方案,不涉及自己造轮子或者魔改。
Table of Contents
我对TOC插件的需求
我期望TOC插件满足以下基本需求:
1. 能够自动生成,而不是使用shortcode手动配置
2. 能够在浏览文章的时候随时访问TOC,无需回到页面顶部
3. 能够在浏览文章的时候实时看到自己处于哪个章节,在移动设备上也要满足这个需求
事实证明,就算以上列举的功能在前端圈里看起来非常容易实现,要找到一个主流的、免费的、开箱即用的、能直接支持这些功能的TOC插件并不容易。
wordpress现成插件及解决方案
在wordpress.org以及几个主流插件市场上搜索TOC相关插件:
LuckyWP Table of Contents
评分高、下载量大,但是存在一个重要功能缺失:
❌ 无法在浏览文章的时候实时看到自己处于哪个章节
Easy Table of Contents
✅ 比上面的LuckyWP Table of Contents要好一些,能够动态显示当前浏览位置。
❓对TOC html anchor支持不够好
Joli Table Of Contents
有免费版和收费版;收费版$29.99,还只提供1年的免费更新。
❌ 重要的几个功能(实时TOC标题、固定页面)需要收费版
❌ heading max-depth似乎做的不够好,算一个小瑕疵
Essential Addons for Elementor
✅ 支持mobile device
❌ 需要先安装Elementor。仅仅从TOC需求的角度来看,为了实现TOC功能需要花钱购买Elementor pro。
❓ 至少从官网的demo来看,他们展示出的TOC demo并不是完全响应式的:只能从TOC导航到相应位置,但是位置变动以后TOC并没有更新。
Fixed TOC
仅在envato market上销售:https://codecanyon.net/item/fixed-toc-wordpress-plugin/7264676
❓ 收费$20
✅ 在mobile device上面也能使用。实现方式为:使用一个固定在页面上的按钮,点击按钮以后弹出TOC组件。
❌ 插件满足我的所有需求:写这篇文章一年半以后,我也买了这个插件来看看到底如何。结果是:符合基本要求,但一些细节设计(比如弹出TOC窗口的触发时机,以及TOC窗口自动最小化的设计)我不是很喜欢。所以本站仍然保持原有TOC架构不变。
我使用的TOC解决方案
我组合了3个插件,仅仅为了实现一个简单的TOC组件,有点得不偿失,这就是免费的代价。
使用的插件
使用如下3个插件:
Easy Table of Contents:一个普通、免费的TOC插件,能够实时显示浏览位置。
Popup maker:弹窗制作插件。
amr shortcode any widget:给现有的widgets制作shortcodes,这样就可以在popup maker中使用它们了。
* 注:2023年1月,我发现这个amr shortcode any widget被wordpress.org拉去安全审核了,但这一审核就是2个月起,到了3月中旬我发现这个插件还是没被放出来。如果这个插件的主页无法获取下载链接,可以直接通过这个链接下载这个插件的v4.0版。
再次更新:amr shortcode any widget应该是存在一个XSS相关的安全漏洞被wordpress.org下架了,而原作者似乎已经inactive一年了,不知道什么时候才能修好漏洞重新上架。考虑到这个漏洞对本博客没有影响,我决定继续使用这个插件,打了个github上面找的补丁:🔗 [Update amr-shortcode-any-widget.php by gregarios · Pull Request #1 · fusillicode/amr-shortcode-any-widget] https://github.com/fusillicode/amr-shortcode-any-widget/pull/1/commits/17bca3ddb319a617659f8486c373c828da856e34
再次更新:今天到论坛上看了一眼才发现amr shortcode any widget的原作者似乎已经离世了,R.I.P. 🔗 [Anna-marie Redpath - Memorial Website] http://am.memorial.pahlman.com/
步骤
1. 激活Easy Table of Contents插件并设置 TOC自动生成并显示 .
2. 制作一个Button:
(从一些互联网教程博客里东拼西凑了一堆代码,注意第52行的 class="button-toc-popup" 一定不能少,这个需要用来当作popup maker trigger)
<?php
add_action( 'wp_head', function () { ?>
<style>
.button-toc-popup {
position:fixed;
z-index:999;
right:10px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
color: #0059A0;
padding: 5px;
background-color: #87CEFA;
border: solid #0059A0 1px;
text-decoration: none;
cursor: pointer;
}
.button-toc-popup:hover, .button-toc-popup:active {
background-color: #00BFFF;
}
@media (min-width:320px) { /* smartphones, iPhone, portrait 480x320 phones */
.button-toc-popup {
top:10%;
height:36px;
width:36px;
}
}
@media (min-width:481px) { /* portrait e-readers (Nook/Kindle), smaller tablets @ 600 or @ 640 wide. */ }
@media (min-width:641px) { /* portrait tablets, portrait iPad, landscape e-readers, landscape 800x480 or 854x480 phones */ }
@media (min-width:961px) { /* tablet, landscape iPad, lo-res laptops ands desktops */ }
@media (min-width:1025px) { /* big landscape tablets, laptops, and desktops */
.button-toc-popup {
top:30%;
height:52px;
width:52px;
}
}
</style>
<?php } );
add_action( 'wp_footer', function(){
echo '<img class="button-toc-popup" src="data:image/svg+xml;base64,PHN2ZyBhcmlhLWhpZGRlbj0idHJ1ZSIgZm9jdXNhYmxlPSJmYWxzZSIgZGF0YS1wcmVmaXg9ImZhcyIgZGF0YS1pY29uPSJsaXN0LW9sIiBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtbGlzdC1vbCBmYS13LTE2IiByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9ImN1cnJlbnRDb2xvciIgZD0iTTYxLjc3IDQwMWwxNy41LTIwLjE1YTE5LjkyIDE5LjkyIDAgMCAwIDUuMDctMTQuMTl2LTMuMzFDODQuMzQgMzU2IDgwLjUgMzUyIDczIDM1MkgxNmE4IDggMCAwIDAtOCA4djE2YTggOCAwIDAgMCA4IDhoMjIuODNhMTU3LjQxIDE1Ny40MSAwIDAgMC0xMSAxMi4zMWwtNS42MSA3Yy00IDUuMDctNS4yNSAxMC4xMy0yLjggMTQuODhsMS4wNSAxLjkzYzMgNS43NiA2LjI5IDcuODggMTIuMjUgNy44OGg0LjczYzEwLjMzIDAgMTUuOTQgMi40NCAxNS45NCA5LjA5IDAgNC43Mi00LjIgOC4yMi0xNC4zNiA4LjIyYTQxLjU0IDQxLjU0IDAgMCAxLTE1LjQ3LTMuMTJjLTYuNDktMy44OC0xMS43NC0zLjUtMTUuNiAzLjEybC01LjU5IDkuMzFjLTMuNzIgNi4xMy0zLjE5IDExLjcyIDIuNjMgMTUuOTQgNy43MSA0LjY5IDIwLjM4IDkuNDQgMzcgOS40NCAzNC4xNiAwIDQ4LjUtMjIuNzUgNDguNS00NC4xMi0uMDMtMTQuMzgtOS4xMi0yOS43Ni0yOC43My0zNC44OHpNNDk2IDIyNEgxNzZhMTYgMTYgMCAwIDAtMTYgMTZ2MzJhMTYgMTYgMCAwIDAgMTYgMTZoMzIwYTE2IDE2IDAgMCAwIDE2LTE2di0zMmExNiAxNiAwIDAgMC0xNi0xNnptMC0xNjBIMTc2YTE2IDE2IDAgMCAwLTE2IDE2djMyYTE2IDE2IDAgMCAwIDE2IDE2aDMyMGExNiAxNiAwIDAgMCAxNi0xNlY4MGExNiAxNiAwIDAgMC0xNi0xNnptMCAzMjBIMTc2YTE2IDE2IDAgMCAwLTE2IDE2djMyYTE2IDE2IDAgMCAwIDE2IDE2aDMyMGExNiAxNiAwIDAgMCAxNi0xNnYtMzJhMTYgMTYgMCAwIDAtMTYtMTZ6TTE2IDE2MGg2NGE4IDggMCAwIDAgOC04di0xNmE4IDggMCAwIDAtOC04SDY0VjQwYTggOCAwIDAgMC04LThIMzJhOCA4IDAgMCAwLTcuMTQgNC40MmwtOCAxNkE4IDggMCAwIDAgMjQgNjRoOHY2NEgxNmE4IDggMCAwIDAtOCA4djE2YTggOCAwIDAgMCA4IDh6bS0zLjkxIDE2MEg4MGE4IDggMCAwIDAgOC04di0xNmE4IDggMCAwIDAtOC04SDQxLjMyYzMuMjktMTAuMjkgNDguMzQtMTguNjggNDguMzQtNTYuNDQgMC0yOS4wNi0yNS0zOS41Ni00NC40Ny0zOS41Ni0yMS4zNiAwLTMzLjggMTAtNDAuNDYgMTguNzUtNC4zNyA1LjU5LTMgMTAuODQgMi44IDE1LjM3bDguNTggNi44OGM1LjYxIDQuNTYgMTEgMi40NyAxNi4xMi0yLjQ0YTEzLjQ0IDEzLjQ0IDAgMCAxIDkuNDYtMy44NGMzLjMzIDAgOS4yOCAxLjU2IDkuMjggOC43NUM1MSAyNDguMTkgMCAyNTcuMzEgMCAzMDQuNTl2NEMwIDMxNiA1LjA4IDMyMCAxMi4wOSAzMjB6Ij48L3BhdGg+PC9zdmc+" >';
});
以及一段额外javascript代码:如果当前页面没有TOC结构,就隐藏TOC按钮:
3. 新建一个popup window,然后在popup内容里填写TOC的widget shortcode。(这个shortcode需要去 Appearance->widgets->widgets for shortcodes 里面生成,如下图所示)
4. 将Button class: .button-toc-popup 设置为popup trigger,触发条件为Click to open .
5. (可选)你可以在popup编辑器里继续调整popup的样式(弹出位置、弹出效果、距离等)
效果
* 注明:我对本站的TOC进行了一些后续修改(见本文后面的部分),所以下面的演示视频中的TOC样式可能和你按照上面的步骤做出来的效果略有区别。
桌面端:
移动端:
后续改进
就本站而言,我还写了一些JS代码,提供了以下额外功能:
TOC滑动条(很长的目录也能显示);
TOC滑动条---自动居中(当前所在的目录一定会自动位于TOC popup的中间位置,这样就不需要手动滑动过长的TOC了);
自动修改TOC弹窗的标题为文章标题,效果
电脑端打开网页后会自动弹出TOC窗口,不需要手动再点击一次;移动端则不会自动弹出窗口。