WordPress中文章自动添加目录
思路
我所使用的模板不能自动生成目录,这样不但显得文章没有层次而且阅读时也很不方便。
解决这个问题首先想到的就是插件,找了几个安装量比较大的插件,如:Easy Table of Contents、LuckyWP Table of Contents、Table of Contents Plus等等,经过考查发现这些并不能满足我的需求(悬浮在页面一侧,随页面滚动而动)。无奈只能自己修改页面,主要思路是利用正则表达式过滤标题,生成目录。具体实现方案有如下两种:
1. 使用JS读取页面过滤标题,生成文章目录,再插入到页面中;
2. 利用PHP,在文章输出之前生成目录最后一次性渲染页面;
实现
考虑到如果JS操作,势必要在页面渲染完成后重新编排页面,可能会造成浏览器的重排,而使用PHP时就不会有这个问题。所以我们采用第二种方案。具体步骤如下:
修改functions.php
文件
在参考了文章WordPress非插件添加文章目录功能后,在functions.php中的末尾出添加以下代码,具体效果查看本站文章的左悬目录。
function article_index(content) {matches = array();
ul_li = '';rh = "/<h[23]>(.*?)<\/h[23]>/im";
h2_num = 0;h3_num = 0;
//判断是否是文章页
if(is_single()){
if(preg_match_all(rh,content, matches)) {
// 找到匹配的结果
foreach(matches[1] as num =>title) {
hx = substr(matches[0][num], 0, 3);start = stripos(content,matches[0][num]);//匹配每个标题字符串的起始位置end = strlen(matches[0][num]);//匹配每个标题字符串的结束位置
if(hx == "<h2"){h2_num += 1; //记录h2序列
h3_num = 0;
// 文章标题添加id,便于目录导航的点击定位content = substr_replace(content, '<h2 id="h2-'.num.'">'.title.'</h2>',start,end);title = preg_replace('/<.+?>/', "", title); //获取h2的文字内容ul_li .= '<li class="h2_nav"><a href="#h2-'.num.'" class title="'.title.'">'.title."</a><i></i></li>\n";
}else if(hx == "<h3"){
h3_num += 1; //记录h3序列content = substr_replace(content, '<h3 id="h3-'.num.'">'.title.'</h3>',start,end);title = preg_replace('/<.+?>/', "", title); //获取h3里面的文字ul_li .= '<li class="h3_nav"><a href="#h3-'.num.'" class title="'.title.'">'.title."</a><i></i></li>\n";
}
}
}content = content . "<aside class=\"mod-article__nav\"><div class=\"mod-article__nav-side\"></div><ul class=\"js_article_nav mod-article__nav-list animated fadeIn\" style=\"display: block;\">\n" .ul_li . "</ul></aside>\n";
return content;
}elseif(is_home){
returncontent;
}
}
add_filter( "the_content", "article_index" );
修改style.min.css
样式文件
在style.min.css
样式文件最后增加样式:
.mod-article__nav-list::-webkit-scrollbar-button:end:increment,.mod-article__nav-list::-webkit-scrollbar-button:start:decrement{background-color:#fff}.mod-article__nav-list::-webkit-scrollbar-track-piece:vertical:end,.mod-article__nav-list::-webkit-scrollbar-track-piece:vertical:start{background-color:#fff}.mod-article__nav{position:fixed;right:50%;top:50%;width:190px;margin-right:570px;margin-top:-200px;background:#fff;overflow:hidden}.mod-article__nav .mod-article__nav-side{position:absolute;top:0;left:5px;width:0;height:100%;min-height:40px;background-color:#eaeaea;border:1px solid #eaeaea;border-top:0;border-bottom:0}.mod-article__nav .mod-article__nav-side:before{content:"";position:absolute;top:2px;left:-4px;width:8px;height:8px;background:#d1d1d1}.mod-article__nav .mod-article__nav-side:after{content:"";position:absolute;bottom:8px;left:-4px;width:8px;height:8px;background:#d1d1d1}.mod-article__nav .mod-article__nav-list{display:none;position:relative;height:auto;margin:20px 0;padding-left:18px;max-height:400px;text-indent:0;overflow-y:auto}.mod-article__nav .mod-article__nav-list li{position:relative;color:#666;list-style:none}.mod-article__nav .mod-article__nav-list li a{display:inline-block;max-width:150px;overflow:hidden;white-space:nowrap;-webkit-text-overflow:ellipsis;-khtml-text-overflow:ellipsis;-icab-text-overflow:ellipsis;-moz-text-overflow:ellipsis;text-overflow:ellipsis;color:#333;text-decoration:none}.mod-article__nav .mod-article__nav-list li a:hover{color:#39c}.mod-article__nav .mod-article__nav-list li a:after{display:none}.mod-article__nav .mod-article__nav-list li:hover i{background-color:#39c}.mod-article__nav .mod-article__nav-list .h2_nav{margin-left:0;line-height:15px;font-size:15px}.mod-article__nav .mod-article__nav-list .h3_nav{margin-left:10px;line-height:15px;font-size:15px}.mod-article__nav .mod-article__nav-list .h3_nav a{max-width:136px}.mod-article__nav .mod-article__nav-list .h3_nav i{display:block;border-radius:10px;border:none;background-color:transparent}.mod-article__nav .mod-article__nav-list .active i{background-image:url(../sprite/style-index.75e581e4.png);background-position:-320px -196px;border-radius:0;border:none;background-color:transparent;width:16px;height:12px}.mod-article__nav .mod-article__nav-list li[class~=active]:hover i{background-color:transparent}.mod-article__nav .mod-article__nav-list i{position:absolute;height:8px;width:8px;left:-17px;top:5px;border-radius:10px;background:#d1d1d1;border:1px solid #fff;font-size:12px;cursor:pointer}.mod-article__nav{margin-right:680px}}@media screen and (min-width:1580px) and (max-width:1750px){.mod-article__nav{margin-right:600px}}@media screen and (max-width:1580px){.mod-article__nav{display:none}}