Alfred Sun +

用js在jekyll博客中实现标签云和标签页

Posted by Alfred Sun github pages

本文主要讨论在jekyll博客中借助javascript和json,实现标签云和标签页。标签云可以用jquery.tagcloud.js插件实现,标签页则使用jQuery读取json数据文件,用地址传递参数给js函数,使用的是异步加载技术,请看演示页面

标签云

Tag Cloud可以使用GitHub上这个简单的jQuery Plugin实现(演示实例),使用方法也很Simple:

<div id="whatever">
  <a href="/path" rel="7">peace</a>
  <a href="/path" rel="3">unity</a>
  <a href="/path" rel="10">love</a>
  <a href="/path" rel="5">having fun</a>
</div>

然后

$.fn.tagcloud.defaults = {
  size: {start: 14, end: 18, unit: 'pt'},
  color: {start: '#cde', end: '#f52'}
};

$(function () {
  $('#whatever a').tagcloud();
});

首先要加载jquery,如果博客里还加载了其他的js库,在另外一个js库中也定义了符号的话,那么在使用符号时就发生了冲突。所以在加载jquery时还要解决$命名冲突。请看这篇文章,我用的办法是定义jQuery的别名:

<script src="/js/jquery-1.7.1.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
  var jq = jQuery.noConflict();
</script>

下面是标签云的代码:

<script src="/js/jquery.tagcloud.js" type="text/javascript" charset="utf-8"></script>
<script language="javascript">
  jq.fn.tagcloud.defaults = {
    size: {
      start: 12,
      end: 22,
      unit: 'px'
    },
    color: {
      start: '#7CCD7C',
      end: '#CD0000'
    }
  };

  jq(function() {
    jq('#tag_cloud a').tagcloud();
  });
</script>

注意,一定要注明节点id:tag_cloud和每个tag用以标识字体大小的属性rel;在Jekyll文件里面可以这样写:

<div id="tag_cloud">
  {% for tag in site.tags %}
    <a href="#{{ tag[0] }}-ref" title="{{ tag[0] }}" rel="{{ tag[1].size }}">
      {{ tag[0] }}&nbsp;
    </a>
  {% endfor %}
</div>

<script src="/js/jquery.tagcloud.js" type="text/javascript" charset="utf-8"></script> 
<script language="javascript">
    $.fn.tagcloud.defaults = {
        size: {start: 12, end: 22, unit: 'px'},
        color: {start: '#7CCD7C', end: '#CD0000'}
    };
    $(function () {
        $('#tag_cloud a').tagcloud();
    });
</script>

标签页

在谢益辉的博客里看到的用js实现标签云。可以看到,这个标签页上,在标签云之后跟着各个标签的文章列表,如果我只想看到某个标签的文章列表,要怎么做呢?

前面我写了篇文章《用jekyll和jQuery实现异步加载文章列表》,使用jQuery异步加载文章列表。同样的,我们也可以编写个函数加载某个标签的所有文章的列表。

首先,生成文章列表数据的json模板是:

---
layout: nil
---

[
{% for post in site.posts %}
  {"title":"{{post.title}}",
  "url":"{{site.url}}{{post.url}}",
  "date":"{{ post.date | date:'%Y-%m-%d' }}",
  "tags":[{% for tag in post.tags %}"{{tag}}"{% if forloop.last == false %} ,{% endif %}{% endfor %}]}
  {% if forloop.last == false %},{% endif %}{% endfor %}
]

用jekyll处理之后得到的json文件在这里

定义javascript函数showTag(),异步加载某一个标签的文章列表

<script type="text/javascript">
  function showTag(tagStr) {
    jq.getJSON("../post.json",
    function(data) {
      jq('#show-tag').empty(content);
      var content = "<h2>分类:" + tagStr + "</h2><ul class=\"posts\">";
      var count = 0;
      jq.each(data,
      function(i, item) {
        jq.each(item.tags,
        function(j, tag) {
          if (tag == tagStr) {
            content += "<li class=\"listing-item\"><time datetime=\"" + item.date + "\">" + item.date + "</time><a href=\"" + item.url + "\">" + item.title + "</a></li>";
            count++;
          }

        });
      });
      if (count > 0) {
        content += "</ul>";
        postNumStr = "<span>(" + count + "篇文章)</span>";
        jq('#show-tag').append(content);
        jq('#show-tag>h2').append(postNumStr);
      }
    });
  }
</script>

而标签页的核心代码为

<div id="tag_cloud">
  {% for tag in site.tags %}
  <a href="javascript:;" onclick="showTag('{{ tag[0] }}')" title="{{ tag[0] }}" rel="{{ tag[1].size }}">
    {{ tag[0] }}
  </a>
  {% endfor %}
  </div>

<div id="show-tag">
  <div style="text-align:center">
    <img src="/images/loading.gif"/>&nbsp;&nbsp;loading...
  </div>
</div>

戳这里查看完整代码。

下面这段代码用url地址来传递参数

<script type="text/javascript">
  var href = window.location.href;
  var pos = href.indexOf('?tag=');
  var paraStr = href.substring(pos + 5);
  if (pos > 0) {
    showTag(decodeURI(paraStr));
  } else {
    showTag("");
  }
</script>

post模板里的标签列表部分代码:

{% if page.tags != empty %}
<ul class="tags emphnext">
  <li>标签:</li>
  {% for tag in page.tags %}
  <li>
    <a href="{{ site.baseurl }}/tags/?tag={{tag | cgi}}">
      {{ tag }}
    </a>
    {% if forloop.last == false %}, {%endif %}
  </li>
  {% endfor %}
</ul>
{% endif %}

侧面栏上标签列表的代码:

<div id="tag_sidebar">
  {% for tag in site.tags %}
  <a href="{{site.baseurl}}/tags/?tag={{tag[0] | cgi}}" title="{{ tag[0] }}">
    {{ tag[0] }}<sup>{{ tag[1].size }}</sup>&nbsp;
  </a>
  {% endfor %}
</div>

其他 Tag Cloud Plugin

除了上面介绍的那个Plugin外,博主还找到另外两个3D的标签云Plugin。

此外,看到这样一篇文章,告诉我们如何用Flash Movie和 R 来实现Tag Cloud;文章中提出了一个比较好的思路,统计Post的查阅频率或者tag的使用频率(ofen used or rarely used),然后据此来设定tag字体的大小。

[Comments]:

Related Blog