Skip to content

Octopress 使用關聯文章插件

Published: 7 分鐘

「關聯文章」(related posts)是很多部落格都會使用的功能,讓訪客可以方便發現有興趣的文章。Octopress 雖然也支援這個功能,但是最終山姆鍋還是採用另一個插件來實現。

為什麼要顯示關聯文章?

主要目的當然是讓訪客發現她有興趣的文章,但同時如果做得好,也可以增加搜尋引擎建立站內關聯的機率。不管如何,一般來說是都會建議採用來作為一個網站內容導覽機制。

如何讓 Octopress 支援?

有幾個方法可以讓 Octopress 支援關聯文章的功能:

  1. Octopress 內建
  2. 第三方服務
  3. 第三方插件

使用內建功能

Octopress 內建便支援關聯文章功能,只要在 _config.yml 檔案中,設定:

lsi: true

這樣,Octorpess 在建立網頁時就會幫我們計算關聯文章。但是這個做法有幾個問題:

  • 速度過慢,即使採用 Ruby gsl 模組仍不理想。
  • 大部分關聯文章都是最近發表的文章。

使用第三方服務

目前已經有不少網路服務提供關聯文章支援,山姆鍋過去主要使用LinkWithin這個服務,簡單方便,有縮圖也支援 WordPress 插件。但其實這樣的服務對於搜尋引擎來說,並沒有太大的助益。雖然縮圖可以增加吸引力,但值不值得就見仁見智了。

使用第三方插件

按照 Adding Related Post to Octopress 這篇文章,找到這個改善的關聯文章插件。基本上,它利用文章中設定的標籤(tags)來進行關聯。雖然不精準,也沒有漂亮的縮圖,但是可以直接將連接內嵌在頁面,對於搜尋引擎來說是比較友善。

安裝關聯文章插件

山姆鍋最終採用第三方插件來支援關聯文章的功能。

建立插件程式檔

在 Octopress 的 plugins 目錄中,建立名為 ‘related_posts.rb’的檔案,其內容為:

require 'jekyll/post'

module RelatedPosts

  # Used to remove #related_posts so that it can be overridden
  def self.included(klass)
    klass.class_eval do
      remove_method :related_posts
    end
  end

  # Calculate related posts.
  #
  # Returns [<Post>]
  def related_posts(posts)
    return [] unless posts.size > 1
    highest_freq = Jekyll::Post.tag_freq(posts).values.max
    related_scores = Hash.new(0)
    posts.each do |post|
      post.tags.each do |tag|
        if self.tags.include?(tag) && post != self
          cat_freq = Jekyll::Post.tag_freq(posts)[tag]
          related_scores[post] += (1+highest_freq-cat_freq)
        end
      end
    end

    Jekyll::Post.sort_related_posts(related_scores)
  end

  module ClassMethods
    # Calculate the frequency of each tag.
    #
    # Returns {tag => freq, tag => freq, ...}
    def tag_freq(posts)
      return @tag_freq if @tag_freq
      @tag_freq = Hash.new(0)
      posts.each do |post|
        post.tags.each {|tag| @tag_freq[tag] += 1}
      end
      @tag_freq
    end

    # Sort the related posts in order of their score and date
    # and return just the posts
    def sort_related_posts(related_scores)
      related_scores.sort do |a,b|
        if a[1] < b[1]
          1
        elsif a[1] > b[1]
          -1
        else
          b[0].date <=> a[0].date
        end
      end.collect {|post,freq| post}
    end
  end

end

module Jekyll
  class Post
    include RelatedPosts
    extend RelatedPosts::ClassMethods
  end
end

或者您可以使用最新版本

在文章頁面安插關聯文章

在 ‘source/_includes/custom/asides/‘目錄中,新增一個名為’related_posts.html’的檔案。在要出現關聯文章的頁面樣板,使用下列方式安插進去。

{% include custom/asides/related_posts.html %}

‘related_post.html’需要根據您使用的樣板來調整,底下是「影化身部落格」使用的內容:

{% if site.related_posts.size > 1 %}
<article class="archives">
  <div class="related-posts">
    <h2>您也許會喜歡</h2>
    {% for post in site.related_posts limit:3 %}
      <article class="post type-post status-publish format-standard hentry">
{% capture category %}{{ post.categories | size }}{% endcapture %}
<time datetime="{{ post.date | datetime | date_to_xmlschema }}" pubdate>{{ post.date | date: "<span class='month'>%b</span> <span class='day'>%d</span> <span class='year'>%Y</span>"}}</time>
<header>
<h2 class="entry-title"><a href="{{ root_url }}{{ post.url }}">{% if site.titlecase %}{{ post.title | titlecase }}{% else %}{{ post.title }}{% endif %}</a></h2>
{% if category != '0' %}
  <span class="categories">分類 {{ post.categories | category_links }}</span>
{% endif %}
</header>
      </article>
    {% endfor %}
  </div>
</article>
{% endif %}

參考來源

郭信義 (Sam Kuo)

奔騰網路科技技術長,專長分散式系統、Web 應用與雲端服務架構、設計、開發、部署與維運。工作之餘,喜歡關注自由軟體的發展與應用,偶爾寫一下部落格文章。