当前位置 : 首页 » 文章分类 :  开发  »  Hexo博客(21)博客概览插件

Hexo博客(21)博客概览插件

早就有这个想法了,汇总博客的统计量,比如总共有多少篇文章、最近一次更新是哪天,然后展示在主页上,让人能一眼看出博客的活跃状态。
动手之前感觉这件事情并不难,就是一些html,js,css语句,并且这也不是我第一次给自己的博客写插件了,但过程中还是遇到一些问题,都查资料解决了,做完后感觉还是有很多收获。


获取站点文章总数

文章总数很好获得,Hexo提供一个变量site.posts,是一个数组,其长度就是文章总数,然后使用ejs语句<%= site.posts.length %>输出即可。

获取站点最近更新日期

把站点所有文章按更新日期倒序排序,取第一个,获取其更新日期,就是整个博客的最近更新日期。
排序使用ejs的sort()函数,取数组的第一个用ejs的first()函数,都很方便,如下:

<!-- 最近更新日期,把站点所有文章按更新日期(updated)倒序排序,取第一个 -->
var recent_updated_date = site.posts.sort('updated', -1).first().updated.format('YYYY年MM月DD日');

不过我第一次写的时候,对ejs也不熟悉(当然现在也不熟悉),从网上查到一个first()函数,但用的时候忘了加括号,总是报错。


统计一年(一月)内新增文章数

逻辑也很简单,还是遍历站点所有文章,将其发布日期和指定日期作比较病计数。
但实际写起来绕了个弯,一开始想的比较复杂,把文章的年、月、日都获取到,和计算好的一年前时间的年、月、日分别比较,这样写逻辑非常复杂,还总出错。
后来上网查了查JavaScript的Date对象,发现是可以直接比较大小的,然后就很简单了:

<!-- 最近一年的文章数 -->
var one_year_count=0;
<!-- 最近30天的文章数 -->
var one_month_count=0;

var nowdate = new Date(); <!-- 当前日志的Date对象 -->
var one_year_ago = new Date(nowdate-365*24*60*60*1000); <!-- 一年前的Date对象 -->
var one_month_ago = new Date(nowdate-30*24*60*60*1000); <!-- 30天前的Date对象 -->

<!-- 遍历站点所有文章,按日期统计 -->
site.posts.forEach(function(post){
    var post_date = post.date.toDate(); <!-- 文章的发表日期Date对象 -->
    if (post_date > one_year_ago){ <!-- Date对象可直接比较 -->
      one_year_count = one_year_count+1;
    }
    if (post_date > one_month_ago){ <!-- Date对象可直接比较 -->
      one_month_count = one_month_count+1;
    }
});

有个问题,文章数的统计是每次博客生成触发的,不是实时的。也就是说是以hexo g生成博客内容的时间作为当前时间统计的个数,部署后不会自动刷新。曾经想改为页面刷新时重新统计,发现做不到,在js函数中是引用不到hexo提供的site变量的,只在构建环境中才能读到。


JavaScript实时动态显示当前时间

最后还给这个小插件加了个花哨功能,使用JavaScript动态实时的显示当前时间。
实现步骤如下:

  • 1、写一个表示当前时间的<span></span>,指定id为now_time_span,内容先空着,在后面的js函数中设置此id的内容。
  • 2、写一个js函数showNowTime(),设置id为now_time_span的html元素的内容为格式化的当前时间。
  • 3、设置一个js定时器,每1000毫秒触发一次,调用showNowTime()函数。

代码如下:

<!-- 在此位置插入一个表示当前时间的span,指定id,在后面的js函数中设置此id的内容 -->
<span id="now_time_span"></span>
<script type="text/javascript">
    <!-- 自定义JavaScript日期格式 -->
    <!-- (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423 -->
    <!-- (new Date()).Format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18 -->
    Date.prototype.Format = function (fmt) { //author: meizz
        var o = {
            "M+": this.getMonth() + 1, //月份
            "d+": this.getDate(), //日
            "h+": this.getHours(), //小时
            "m+": this.getMinutes(), //分
            "s+": this.getSeconds(), //秒
            "q+": Math.floor((this.getMonth() + 3) / 3), //季度
            "S": this.getMilliseconds() //毫秒
        };
        if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
    }

  <!-- js函数,设置id为now_time_span的html元素的内容为格式化的当前时间 -->
  function showNowTime(){
    document.getElementById("now_time_span").innerText = "当前时间:"+new Date().Format("yyyy-MM-dd hh:mm:ss");
  }

  <!-- 立即调用一次showNowTime()函数,给now_time_span赋初始值 -->
  showNowTime();

  <!-- js定时器,每1000毫秒触发一次,调用showNowTime()函数 -->
  setInterval("showNowTime()",1000);
</script>

其中有个比较复杂的自定义JavaScript Date格式的函数,从网上找的。


侧边栏加载overview插件

以下针对freemind/free2mind主题,其他主题请自行更改。
在themes\free2mind\layout\_widget目录下新建ejs脚本文件overview.ejs,写入上述所有代码。
在主题配置文件themes\free2mind_config.yml中,widgets配置项下新增overview插件,使得插件能被加载。

overview.ejs完整代码如下:

<!-- 2018.2.10,masikkk新增,添加博客概览侧边栏 -->
<div class="widget">
    <h4><%= __('博客概览') %></h4>
    <ul class="blogroll list-unstyled">

    <%
      <!-- 最近更新日期,把站点所有文章按更新日期(updated)倒序排序,取第一个 -->
      var recent_updated_date = site.posts.sort('updated', -1).first().updated.format('YYYY年MM月DD日');

      <!-- 最近一年的文章数 -->
      var one_year_count=0;
      <!-- 最近30天的文章数 -->
      var one_month_count=0;

      var nowdate = new Date(); <!-- 当前日志的Date对象 -->
      var one_year_ago = new Date(nowdate-365*24*60*60*1000); <!-- 一年前的Date对象 -->
      var one_month_ago = new Date(nowdate-30*24*60*60*1000); <!-- 30天前的Date对象 -->

      <!-- 遍历站点所有文章,按日期统计 -->
      site.posts.forEach(function(post){
        var post_date = post.date.toDate(); <!-- 文章的发表日期Date对象 -->
        if (post_date > one_year_ago){ <!-- Date对象可直接比较 -->
          one_year_count = one_year_count+1;
        }
        if (post_date > one_month_ago){ <!-- Date对象可直接比较 -->
          one_month_count = one_month_count+1;
        }
      });
    %>
    本博客共有文章<%= site.posts.length %>篇,最近更新日期<%= recent_updated_date %>,最近一年新增文章<%= one_year_count %>篇,最近30天新增文章<%= one_month_count %>篇。
    </ul>

    <!-- 在此位置插入一个表示当前时间的span,指定id,在后面的js函数中设置此id的内容 -->
    <span id="now_time_span"></span>
    <script type="text/javascript">
        <!-- 自定义JavaScript日期格式 -->
        <!-- (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423 -->
        <!-- (new Date()).Format("yyyy-M-d h:m:s.S")      ==> 2006-7-2 8:9:4.18 -->
        Date.prototype.Format = function (fmt) { //author: meizz
            var o = {
                "M+": this.getMonth() + 1, //月份
                "d+": this.getDate(), //日
                "h+": this.getHours(), //小时
                "m+": this.getMinutes(), //分
                "s+": this.getSeconds(), //秒
                "q+": Math.floor((this.getMonth() + 3) / 3), //季度
                "S": this.getMilliseconds() //毫秒
            };
            if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
            for (var k in o)
            if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
            return fmt;
        }

      <!-- js函数,设置id为now_time_span的html元素的内容为格式化的当前时间 -->
      function showNowTime(){
        document.getElementById("now_time_span").innerText = "当前时间:"+new Date().Format("yyyy-MM-dd hh:mm:ss");
      }

      <!-- 立即调用一次showNowTime()函数,给now_time_span赋初始值 -->
      showNowTime();

      <!-- js定时器,每1000毫秒触发一次,调用showNowTime()函数 -->
      setInterval("showNowTime()",1000);
    </script>

</div>

效果图如下:


博客概览侧边栏插件

参考


上一篇 LeetCode.027.Remove Element 从数组中移除指定元素

下一篇 LeetCode.020.Valid Parentheses 括号匹配

阅读
评论
2k
阅读预计8分钟
创建日期 2018-02-12
修改日期 2018-02-12
类别

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论