本站文章推薦算法

Article recommendation in Hugo. 文章推薦算法舉例。經過艱苦卓絕的試驗,網站第四版終於完工了!現在介紹一下本站各類推薦中用到的算法。本人不懂編程,這裏只是瞎貓撞上死耗子。源碼直接在我 Github 上找就可以。後來發現有些寫麻煩了,懶得改了。

『如果兩篇文章的系列相同,那關聯度是最高的,我們可以據此設置加權


案:2021 年 12 月發現 Hugo 竟然自帶 相關文章推薦,吐血!自帶的性能比我手寫的好很多,節省了 1/3 的時間。

本站的索引 taxonomies 有分類 categories、系列 series、標籤 tags、作者 author、備註 notes。每篇文章都有 1 箇分類、0-1 個系列、0-3 個標籤、0-1 箇備註。分爲網誌、讀書、作品、春秋學刊等 section

一級難度

從簡單的開始說。以下都是主葉中的。

作品

「作品」的 sectiongallery。按修改時間倒序列出所有 typegallery 的文章:

1
2
3
{{ range  (where site.RegularPages.ByLastmod.Reverse "Type" "gallery") }}
    <a href="{{ .Permalink }}">{{ .Title }}</a>
{{ end }}

二級難度

最近修改

思路如下:

  1. 按最近修改時間倒序,列出所有文章
  2. 篩選出所有發布時間和修改時間不一致的文章
  3. 排除最近發布出現的文章
  4. 列出前 4 項
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{{ $latest := slice }}
{{ range first 8 (where site.RegularPages.ByPublishDate.Reverse "Type" "post") }}
    {{ $latest = $latest | append . }}
{{ end }}  

{{ $1lastmod := slice }}
{{ $lastmod := slice }}
{{ range (where site.RegularPages.ByLastmod.Reverse "Type" "post") }}
    {{ if ne .Lastmod .Date }}
        {{ $1lastmod = $1lastmod | append . }}
        {{ $lastmod = $1lastmod | complement $latest }}
    {{ end }}
{{ end }}

{{ range first 4 $lastmod }}
    <a href="{{ .Permalink }}">{{ .Title }}</a>
{{ end }}

最簡單的方法就是直接按修改時間倒序列出,但是大部分都會和最近發布重複,就顯得沒意義了。

封面置頂

4 張圖片,我這樣安排:1 張除了網址之外的最近發布;2 張除了網址之外的最近修改;隨機 1 張年度 🔝。

 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
{{- range first 1 (where site.RegularPages.ByDate.Reverse "Type" "in" site.Params.Sections4) -}}
    <div>
        <a href="{{ .Permalink }}"target="_blank">
            <div class="recommendation-card scale" style="background-image: url({{ .Params.img }})"></div>
        </a>
    </div>
{{ end }}

{{ $sitelastmod := slice }}
{{ range (where site.RegularPages.ByLastmod.Reverse "Type" "in" site.Params.Sections4) }}
    {{ if ne .Lastmod .Date }}
        {{ $sitelastmod = $sitelastmod | append . }}
    {{ end }}
{{ end }}

{{ range first 2 $sitelastmod }}
    <div>
        <a href="{{ .Permalink }}"target="_blank">
            <div class="recommendation-card scale" style="background-image: url({{ .Params.img }})"></div>
        </a>
    </div>
{{ end }}

{{ range first 1 (shuffle ( site.Menus.top)) }}
    <div>
        <a href="{{ .Page.Permalink }}"  target="_blank">
            <div class="recommendation-card scale" style="background-image: url({{ .Page.Params.img }})"></div>
        </a>
    </div>
{{ end }}

當然,你先要在全站配置文件中加上:

1
2
[params]
  Sections4 = ["exam","gallery","net","read"]  

其他作者

同理,還有其他作者:

  1. 列出所有作者
  2. 篩選出不是「柯棋瀚」「柯棋瀚編」的作者
  3. 隨機列出這些作者及他們的文章
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{{ $author := slice }}
{{ range site.Taxonomies.author.ByCount }}
    {{ if ne .Page.Title  ["柯棋瀚"] ["柯棋瀚編"] }}
        {{ $author = $author | append . }}
    {{ end }}
{{ end }}
{{ range $author  | shuffle  }}
    <a href="{{ .Page.RelPermalink }}">{{ .Page.Title }}</a>
    {{ range .Pages  | shuffle }}
        <li><a href="{{ .Permalink }}">{{ .Title }}</a></li>
    {{ end }}
{{ end }}

過去與未來的的本周

文章頁面下的「過去的本周」,簡單粗暴用了査表法。.Unix 語法見 https://gohugo.io/functions/unix/,是從 1970-01-01 開始累加的秒數。

我這當然不是準確的「本周」,我算的是向前後加減三天。一天 86,400s,一年 315,360s,一閏年 316,224s。我將弟 4、8 年設爲閏年。于是思路很簡單了:

 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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
{{ $1date := sub .Date.Unix 31276800  }}
  {{ $2date := sub .Date.Unix 31795200 }}
  {{ $3date := sub .Date.Unix 62812800 }}
  {{ $4date := sub .Date.Unix  63331200 }}
  {{ $5date := sub .Date.Unix 94348800 }}
  {{ $6date := sub .Date.Unix  94867200 }}
  {{ $7date := sub .Date.Unix 125971200 }}
  {{ $8date := sub .Date.Unix 126489600 }}
  {{ $9date := sub .Date.Unix 157507200 }}
  {{ $10date := sub .Date.Unix 158025600 }}
  {{ $11date := sub .Date.Unix 189043200 }}
  {{ $12date := sub .Date.Unix 189561600 }}
  {{ $13date := sub .Date.Unix 220579200 }}
  {{ $14date := sub .Date.Unix  221097600 }}
  {{ $15date := sub .Date.Unix 252201600 }}
  {{ $16date := sub .Date.Unix  252720000 }}
  {{ $21date := add .Date.Unix 31276800  }}
  {{ $22date := add .Date.Unix 31795200 }}
  {{ $23date := add .Date.Unix 62812800 }}
  {{ $24date := add .Date.Unix  63331200 }}
  {{ $25date := add .Date.Unix 94348800 }}
  {{ $26date := add .Date.Unix  94867200 }}
  {{ $27date := add .Date.Unix 125971200 }}
  {{ $28date := add .Date.Unix 126489600 }}
  {{ $29date := add .Date.Unix 157507200 }}
  {{ $30date := add .Date.Unix 158025600 }}
  {{ $31date := add .Date.Unix 189043200 }}
  {{ $32date := add .Date.Unix 189561600 }}
  {{ $33date := add .Date.Unix 220579200 }}
  {{ $34date := add .Date.Unix  221097600 }}
  {{ $35date := add .Date.Unix 252201600 }}
  {{ $36date := add .Date.Unix  252720000 }}
  <h2>過去與未來的本周</h2>
  <div class="recommend a1">
  {{ range  (where site.RegularPages.ByDate "Type" "post") }}
  {{ $currentdate := .Date.Unix }}
  {{ if and (ge $currentdate $2date) (le $currentdate $1date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $4date) (le $currentdate $3date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $6date) (le $currentdate $5date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $8date) (le $currentdate $7date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $10date) (le $currentdate $9date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $12date) (le $currentdate $11date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $14date) (le $currentdate $13date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $16date) (le $currentdate $15date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $21date) (le $currentdate $22date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $23date) (le $currentdate $24date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $25date) (le $currentdate $26date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $27date) (le $currentdate $28date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $29date) (le $currentdate $30date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $31date) (le $currentdate $32date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $33date) (le $currentdate $34date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ else if and (ge $currentdate $35date) (le $currentdate $36date) }}
  <div><a href="{{ .RelPermalink }}">{{- .Title | safeHTML | markdownify -}}</a> <time class="des-base des-des a1">{{  .Date.Format "2006-01-02" }}</time></div>
  {{ end }}
  {{ end }}
  </div>

三級難度

分類

主葉上「分類」的目的是讓新讀者快速瞭解網誌所有文章類型,所以我想在每個分類下面生成兩項最近發布和兩項隨機推薦。同時,分類後面有「赫赫金鑰」和「資源」兩個系列,需要把它們排除了。大槩思路如下:

  1. 隨機排列所有分類
  2. 生成兩項最近發布
  3. 隨機生成兩項系列不是「赫赫金鑰」和「資源」的項目

具體思路見代碼塊中的註釋。

 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
35
36
37
38
39
40
41
42
43
44
45
46
47
<!--  1、生成所有系列不是赫赫金鑰|資源|的文章。 -->
{{ $series := slice }}
{{ $1series := slice }}
{{ $2series := slice }}
{{ range site.Taxonomies.series.赫赫金鑰 }}
    {{ $1series = $1series | append .Page }}
{{ end }}
{{ range site.Taxonomies.series.資源 }}
    {{ $2series = $2series | append .Page }}
{{ end }}
{{ with (where site.RegularPages "Type" "post") }}
    {{ $series = . | complement $1series $2series }}
{{ end }}
<!--  2、隨機排列所有分類 -->
{{ $allCate := where site.Taxonomies.category "Type" "post" }}
{{ range $allCate.ByCount  | shuffle }}
    {{ $first2 := slice }}
    {{ $thisCateinSeries := slice }}
    {{ $end := slice }}
    {{ $thisCate := slice }}
<!-- 3、生成兩項最近發布  -->    
    {{ range first 2 .Pages }}
        {{ $first2 = $first2 | append . }}
    {{ end }}
<!-- 4、生成 3 和 1 的交集,卽在最近兩項中排除系列是赫赫金鑰|資源|的  -->    
    {{ $First2inSeries :=  intersect $series $first2  }}
<!-- 5、生成這個分類下所有文章  -->    
    {{ range .Pages | shuffle }}
        {{ $thisCate = $thisCate | append . }}
    {{ end }}
<!-- 6、生成 5 和 1 的交集,卽在這個分類所有文章中排除系列是赫赫金鑰|資源|的 -->    
    {{ $thisCateinSeries := intersect $thisCate $series }}
<!-- 7、生成 6 和 4 的補集,卽在這個分類所有文章中排除系列是赫赫金鑰|資源|的,以及最近兩項  -->    
    {{ $end := $thisCateinSeries | complement $First2inSeries  }}
    <ol>
<!-- 8、結果  -->         
        <h2><a href="{{ .Page.Permalink }}">{{ .Page.Title | safeHTML  }}</a></h2>
        <div class="des-base" style="margin-top:.5em;text-align:left">最近發布</div>
        {{ range $first2 }}
            <div><a href="{{ .Permalink }}">{{ .Title | safeHTML  }}</a></div>
        {{ end }}
        <div>隨機推薦</div>
        {{ range first 2 $end | shuffle }}
            <div><a href="{{ .Permalink }}">{{ .Title | safeHTML  }}</a></div>
        {{ end }}
    </ol>
{{ end }}

您可能喜歡

以下是各文章下面的推薦。

是從 ops.tips 那移植過來的,非常感謝。(安利一句,這網站挺好看的)進行了三處改進:

  1. 他只算了 tags,我加上了 categoriesseriesnotes 不列入計算
  2. 加權計算,系列|的權重比 [分類] #標籤 髙
  3. 根據相關文章篇數,實行梯度強弱相關度

首先看第二點。本站的情況是,如果兩篇文章的系列相同,那關聯度是最高的,我們可以據此設置 加權,系列占 4,分類、標籤占 3。有如下可能:

分類 3系列 4標籤 3總分
0000
0013
0026
0039
0104
0117
01210
01313
1003
1016
1029
10312
1107
11110
11213
11316

0,3,4,6,7,9,10,12,13,16 10 種情況。我們設置 3 4 6 7 9 10 13 7 檔。

第三點,如果一個系列篇數很多,超過了 10 篇,那推薦裏面全是這箇系列的,其他一些相關但關聯度弱一些的文章就不會出現。爲改進這個問題,我們可以用強弱相關度相結合的方法。分三種情況。

  1. 相關篇數少於 10:直接順序排列前 10 篇。
  2. 相關篇數 11–20:順序排列前 5 篇;弟 6–10 篇隨機選取 2 篇;弟 11–20 篇隨機選取 3 篇
  3. 相關篇數多於 21:順序排列前 5 篇;弟 6–20 篇隨機選取 3 篇;弟 21–30 篇隨機選取 2 篇

思路如下:

  1. 列出本文章之外的所有文章
  2. 加權計算本文章和其他文章的索引重合度
  3. 按索引重合度進行排序
  4. 分別生成前 5 項、6–10 項、11–20 項、6–20 項、21–30 項
  5. 根據不同情況,進行隨機選取。
  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
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
{{ $current := . }}
{{ $articles := where (where site.Pages ".Kind" "eq" "page" ) ".Title" "!=" $current.Title }}
{{ $3relevant := slice }}
{{ $4relevant := slice }}
{{ $6relevant := slice }}
{{ $7relevant := slice }}
{{ $9relevant := slice }}
{{ $10relevant := slice }}
{{ $13relevant := slice }}
{{ $recommend := slice }}
{{ $5recommend := slice }}
{{ $10recommend := slice }}
{{ $20recommend := slice }}
{{ $30recommend := slice }}
{{ $6to10recommend := slice }}
{{ $6to20recommend := slice }}
{{ $11to20recommend := slice }}
{{ $21to30recommend := slice }}
<!-- 加權計算索引重合度 -->
{{ range $idx, $article := $articles }}
    {{ $1intersection := len (intersect $article.Params.series $current.Params.series) }}
    {{ $1weighted := mul 4 $1intersection }}
    {{ $2intersection := len (intersect $article.Params.category $current.Params.category) }}
    {{ $2weighted := mul 3 $2intersection }}
    {{ $3intersection := len (intersect $article.Params.tag $current.Params.tag) }}
    {{ $3weighted := mul 3 $3intersection }}
    {{ $4weighted  := add $1weighted $2weighted }}
    {{ $5weighted  := add $3weighted $4weighted }}
    {{ if (ge $5weighted 13) }}
        {{ $13relevant = $13relevant | append $article }}
        {{ else if (ge $5weighted 10) }}
            {{ $10relevant = $10relevant | append $article }}
        {{ else if (eq $5weighted 9) }}
            {{ $9relevant = $9relevant | append $article }}
        {{ else if (eq $5weighted 7) }}
            {{ $7relevant = $7relevant | append $article }}
        {{ else if (eq $5weighted 6) }}
            {{ $6relevant = $6relevant | append $article }}
        {{ else if (eq $5weighted 4) }}
            {{ $4relevant = $4relevant | append $article }}
        {{ else if (eq $5weighted 3) }}
            {{ $3relevant = $3relevant | append $article }}
        {{ end }}
{{ end }}
<!-- 據索引重合度排列相關文章 -->
{{ range $13relevant }}
    {{ $recommend = $recommend | append . }}
{{ end }}
{{ range $10relevant }}
    {{ $recommend = $recommend | append . }}
{{ end }}
{{ range $9relevant }}
    {{ $recommend = $recommend | append . }}
{{ end }}
{{ range $7relevant }}
    {{ $recommend = $recommend | append . }}
{{ end }}
{{ range $6relevant }}
    {{ $recommend = $recommend | append . }}
{{ end }}
{{ range $4relevant }}
    {{ $recommend = $recommend | append . }}
{{ end }}
{{ range $3relevant }}
    {{ $recommend = $recommend | append . }}
{{ end }}
<!-- 列出數量區間 -->
{{- range shuffle (first 5 $recommend) -}}
    {{ $5recommend = $5recommend | append . }}
{{ end }}
{{- range shuffle (first 10 $recommend) -}}
    {{ $10recommend = $10recommend | append . }}
{{ end }}
{{ range shuffle (first 20 $recommend)  }}
    {{ $20recommend = $20recommend | append . }}
{{ end }}
{{ range shuffle (first 30 $recommend) }}
    {{ $30recommend = $30recommend | append . }}
{{ end }}
{{ $6to10recommend = $10recommend | complement  $5recommend | shuffle }}
{{ $6to20recommend = $20recommend | complement  $5recommend | shuffle }}
{{ $11to20recommend = $20recommend | complement  $10recommend | shuffle }}
{{ $21to30recommend = $30recommend | complement  $20recommend | shuffle }}
<!-- 根據相關文章篇數進行條件判斷 -->
{{ if ge (len $recommend) 21 }}
    <ul>
    <div>強相關</div>
    {{- range first 5 $recommend -}}
        <li><a href="{{ .Permalink }}">{{- .Title | safeHTML | markdownify -}}</a></li>
    {{ end }}
    <div>隨機次強相關</div>
    {{- range first 3 $6to20recommend -}}
        <li><a href="{{ .Permalink }}">{{- .Title | safeHTML | markdownify -}}</a></li>
    {{ end }}
    <div>隨機弱相關</div>
    {{- range first 2  $21to30recommend  -}}
        <li><a href="{{ .Permalink }}">{{- .Title | safeHTML | markdownify -}}</a></li>
    {{ end }}
    </ul>
        {{ else if ge (len $recommend) 11 }}
        <ul>
        <div>強相關</div>
        {{- range first 5 $recommend -}}
            <li><a href="{{ .Permalink }}">{{- .Title | safeHTML | markdownify -}}</a></li>
        {{ end }}
        <div>隨機次強相關</div>
        {{- range first 2 $6to10recommend -}}
            <li><a href="{{ .Permalink }}">{{- .Title | safeHTML | markdownify -}}</a></li>
        {{ end }}
        <div>隨機弱相關</div>
        {{- range first 3 $11to20recommend -}}
            <li><a href="{{ .Permalink }}">{{- .Title | safeHTML | markdownify -}}</a></li>
        {{ end }}
        </ul>
            {{ else if le (len $recommend) 10 }}
            <ul>
            <div>強相關</div>
            {{- range first 10 $recommend -}}
                <li><a href="{{ .Permalink }}">{{- .Title | safeHTML | markdownify -}}</a></li>
            {{ end }}
            </ul>
{{ end }}

蒙文通的經史觀——經學抉原讀後(附摘錄) 爲例。未加權:

  • 錢穆經學通論摘錄
  • 陳壁生諸書摘錄
  • 周予同諸篇摘錄
  • 北京讀經說記述要
  • 梁啓超中國近三百年學術史述要
  • 鄭玄地位的升降——禮是鄭學讀後
  • 蔗糖消費的社會性——甜與權力讀後
  • 維柯與康德的史學思想——新科學讀後
  • 霍布斯鮑姆筆下的蘇聯模式──極端的年代讀後
  • 公羊傳齊襄復讎事詮釋史

加權之後:

  • 錢穆經學通論摘錄
  • 陳壁生諸書摘錄
  • 周予同諸篇摘錄
  • 北京讀經說記述要
  • 梁啓超中國近三百年學術史述要
  • 鄭玄地位的升降——禮是鄭學讀後
  • 蔗糖消費的社會性——甜與權力讀後
  • 維柯與康德的史學思想——新科學讀後
  • 霍布斯鮑姆筆下的蘇聯模式──極端的年代讀後
  • 艾因哈德筆下的査理大帝——査理大帝傳讀後

區別不大。只有最後一項不一樣,被換成了讀書筆記。再加入了強弱相關度之後,後 5 項:

  • 蔗糖消費的社會性——甜與權力讀後
  • 于水山古琴練習曲集指要
  • 保罗·芮恩施平民政治的基本原理述要
  • 雷次宗略注喪服經傳疏議
  • 資源|文史類網路學術資源

出現了不是讀書|系列的內容。效果不錯。

走之前去髙 雄走一走 爲例,分類:[生活],系列:立言記|,標籤:#臺灣。直接列出重合度前十:

  • 在輔仁大學交換是怎樣的體驗?
  • 臺灣的幾箇孔廟
  • 2018 二〇一八
  • 我❤府城──府城客運
  • 故宮和蘆洲
  • 星爸星媽的天空
  • 基 kee 隆 lung
  • 動物園狂發照片
  • 兩次遊行
  • 臺灣ㄟ大學隨拍

都是立言記|的內容。結合了強弱相關度之後的後 5 項:

  • 樂山大佛的石窟
  • 動物園狂發照片
  • 星爸星媽的天空
  • 一些㒳厈詞彙、讀音對照
  • 臺灣訪琴記

效果不錯。

沒有喜歡的?這裏呢

在此基礎上,我們可以有代表性地生成與此不相關的文章:

  1. 列出所有分類,每個分類隨機產生一項文章
  2. 生成所有不是本文章、分類系列有重合的文章,及其他 section 的文章
  3. 生成 1 和 2 的交集
  4. 在這一交集中隨機產生 5 項文章
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{{ $categories := slice }}
{{ range site.Taxonomies.category.ByCount }}
    {{ with .Pages | shuffle }}
        {{ $cate := . }}
        {{ range first 1 $cate }}
            {{ $categories =  $categories | append  . }}
        {{ end }}
    {{ end }}
{{ end }}
{{ $current := slice }}
{{ $current = $current | append . }}
{{ $other := site.RegularPages |  complement $current $recommendedArticles (where site.RegularPages "Type" "gallery") (where site.RegularPages "Type" "pin") (where site.RegularPages "Type" "xuekan") | shuffle }}
{{ $others := intersect  $categories  $other }}
<ul>
    {{  range first 5 $others | shuffle }}
        <li><a href="{{ .Permalink }}">{{- .Title -}}</a></li>
    {{ end }}
</ul>

隨機推薦下面一行有個坑,如果直接寫成這樣:

{{ range site.Taxonomies.category.ByCount }}
    {{ range first 1 .Pages | shuffle }}  
        {{ $categories =  $categories | append  . }}
    {{ end }}
{{ end }}

是不能隨機的,產生的都是各分類中發布時間最近的一項文章。所以我用了迂迴的方法。

推廣

如果配合 GitHub Actions,定時重新生成,那這些隨機的推薦可以讓靜態網頁變成半動態網頁,豈不美哉!

案:本站已實現 定時生成