优化 Jekyll 的相关文章列表
缘起
相关文章这个模块一直算是博客的一个标配组件之一, jekyll默认也是有着site.related_posts
这个函数的, 可以调用jekyll帮助你生成的相关博文列表. 不过其准确性和相关性都很让人不放心… 从其源码来看, 在默认关闭lsi
的情况下, related_post产出的其实就是简单的最近文章列表…
这样当然不可以! 于是, 本文就是我在针对related_post
这部分做了一些优化后的产物~ 请君品鉴 ^_^
无插件方法
首先当然是希望能在不使用插件的情况下实现, 于是就看到了Jekyll Related Posts without Plugin - 羡辙杂俎 这个大神级妹子的博文~ 很有启发性嘛 基本上我要做的她都做过啦…哈哈
不过我稍微简化了以下代码以及结构, 所以可能会更易懂一些喽~哈
1 | {% raw %} |
思路很简单, 确保其具有共同tag, 在无相关文章的情况下就不展示此模块了. 因为本身liquid的语法非常有限, 不借助插件的情况下, 想要实现更多功能的话, 就比较麻烦了. 如果有哪位XDJM有不借助插件的排序, 求务必告知我哦~
Update
哈哈, 和朋友@小田讨论了下, 终于想到一个不用插件实现排序的方法了~ 代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 {% raw %}
{% comment %} 一致到获取postsAfterFilter以及tagCountEachPost的部分都没有变化{% endcomment %}
{% comment %} 下面则使用了一个叠加for循环来逐次寻找最大的tagcount, 然后同步输出对应postsAfterFilter的值{% endcomment %}
{% if postsAfterFilter.size > 0 %}
<div class="relatedposts">
<h2>Related Posts:</h2>
<ul class="article-list">
{% assign j = tagCountEachPost | size | minus: 1 %}
{% assign maxIndex = 0 %}
{% assign getFirstNumber = true %}
{% assign selectedIndex = "-"|split: "-" %}
{% for p in (0..j) %}
{% for i in (0..j) %}
{% unless selectedIndex contains i %}
{% if getFirstNumber %}
{% assign firstNumber = tagCountEachPost[i] %}
{% assign getFirstNumber = false %}
{% endif %}
{% if tagCountEachPost[i] >= firstNumber %}
{% assign firstNumber = tagCountEachPost[i] %}
{% assign maxIndex = i %}
{% endif %}
{% endunless %}
{% endfor %}
{% assign getFirstNumber = true %}
{% assign selectedIndex = selectedIndex | push: maxIndex %}
{% if selectedIndex.size < 6 %}
<li><a href="{{ site.baseurl }}{{ postsAfterFilter[maxIndex]['url'] }}">{{ postsAfterFilter[maxIndex]['title'] }}</a></li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
{% endraw %}思路也很简单, 就是利用for循环写出一个找最大元素的方法, 然后每次记录下最大元素的index, 就能同步输出对应的post了~ 需要注意的就是为了保证index的一一对应, 需要单独保存每次找到的最大值的index, 然后在下一次遍历中跳过
赞!
有插件下增加排序功能
liquid 部分
在上面的基础上(在update之前的基础上), 首先我们需要在liquid中添加几行代码:
1 | {% raw %} |
下面就是插件环节~
插件部分
Jekyll 的插件都是.rb
结尾的文件, 放在_plugins
路径下即可. 这里filters.rb
是我用来专门放置我自己定制的filter的:
1 | # filters.rb |
如此基本就算搞定啦~