通过 GitHub doumark-action 保存豆瓣观影数据,并给 Hugo 博客添加豆瓣观影页面。
Hexo
有 hexo-douban 项目,可以添加观影数据到页面,更换 Hugo
后也想添加一个观影页面,查找资料后发现有一个 doumark-action
项目可以将观影数据保存为本地文件,然后可以通过 Hugo 的函数获取数据,再前端展示,前面的文章中已经添加了豆瓣条目的短代码,这篇文章再补充两个,一个是近期观影的短代码,另外是添加一个海报墙页面。
最终实现的样式布局参考了一些博主的文章和仓库代码:
保存本地数据#
由于豆瓣 API
的限制,之前的一些在线获取数据方式已经失效了,可以通过在线爬取标记的数据到本地,然后操作本地的数据文件,再前端展示数据。
用到的项目是 doumark-action。
首先在博客仓库的根目录新建一个 Workflow
,新建 .github/workflows/douban.yml
文件,在其中写入自己想要保存的数据,影音、书籍,也可以保存到 Notion
,项目有详细的说明,这里贴一下我的配置,其中将 id
改为自己的豆瓣 ID
。
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
| # .github/workflows/douban.yml
name: douban
on:
schedule:
- cron: "30 * * * *"
workflow_dispatch:
jobs:
douban:
name: Douban mark data sync
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: movie
uses: lizheming/doumark-action@master
with:
id: 222317686
type: movie
format: csv
dir: ./doubanSync/douban
- name: book
uses: lizheming/doumark-action@master
with:
id: 222317686
type: book
format: csv
dir: ./doubanSync/douban
- name: Commit
uses: EndBug/add-and-commit@v8
with:
message: 'chore: update douban data'
add: './doubanSync/douban'
|
我这里将数据存放的目录改为了博客 ~/data
目录之外的地方,使用博客根目录下的 data
目录一直报错,发现之前也有人出现同类型的错误,更改目录后就正常了。
之后可以在仓库手动执行一下 action
,完成后会在 ~/doubanSync/douban/
生成 movie.csv
和 book.csv
,这就是用到的数据文件。
近期观影短代码#
要添加短代码需要在 ~/layouts/shortcodes/
目录下新建短代码模板文件,这里为 recent-douban.html
,在其中添加模板元素:
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
| {{ $type := .Get "type" }}
{{ $count := .Get "count" | default 4 }}
{{ $count = add $count 1 }}
{{ $items := slice }}
{{ if eq $type "movies" }}
{{ $items = getCSV "," "doubanSync/douban/movie.csv" }}
{{ else if eq $type "books" }}
{{ $items = getCSV "," "doubanSync/douban/book.csv" }}
{{ end }}
<div class="recent-items">
{{ range $idx, $item := first $count $items }}
{{ if ne $idx 0 }}
{{ $rating := float (index $item 6) }}
<div class="recent-item">
<div class="recent-item-cover">
<img class="avatar" src="{{ index $item 3 }}" referrer-policy="no-referrer" loading="lazy" alt="{{ index $item 9 }}" title="{{ index $item 1 }}" width="150" height="220">
</div>
<div class="recent-douban-rating">
<div class="rating">
<span class="allstardark">
<span class="allstarlight" style="width:{{ mul 10 $rating }}%"></span>
</span>
<span class="rating_nums">{{ $rating }}</span>
</div>
</div>
<div class="recent-item-title">
<a rel="noreferrer" href="{{ index $item 5 }}" target="_blank">{{ index $item 1 }}</a>
</div>
</div>
{{ end }}
{{ end }}
</div>
|
然后添加一下样式代码,这里和之前的文章保持一致,添加到 shortcodes.scss
中:
1
2
3
4
5
6
7
8
9
| .recent-items {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin: 15px;
}
.recent-items .recent-item, .recent-items .recent-item img {
margin-bottom: 10px;
}
|
之前的豆瓣条目短代码样式文件已经添加了评分星级的样式 allstarlight
,所以这里不添加,如果之前没添加过的话需要添加相关的样式,在之前的文章可以找到。
使用方法如下:
1
2
| {\{< recent-douban type="movies" count=8 >}\}
{\{< recent-douban type="books" >}\}
|
默认展示四条数据,可以通过 count
参数指定显示的数量。
预览:
观影页面#
添加一个海报墙页面展示所有的观影信息,默认展示 18
条信息。
首先在 ~/lauouts/_default/
文件夹下新建模板文件,这里为 posterwall.html
,然后在其中添加页面元素:
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
| {{ define "main" }}
<div class="post-list-container post-list-container-shadow">
<div class="post-item-wrapper post-item-wrapper-no-hover">
<div class="post-item post-item-no-gaps">
<div class="post-item-info-wrapper">
<div class="post-item-title post-item-title-small">
{{.Title}}
<div class="posterwall-description">
{{ .Params.description | markdownify }}
</div>
<div class="movie-wall">
{{ $items := getCSV "," "doubanSync/douban/movie.csv" }}
{{ range $idx, $item := $items }}
{{ if ne $idx 0 }}
{{ $rating := float (index $item 6) }}
<div class="movie-item" style="display: none;">
<div class="movie-cover">
<img src="{{ index $item 3 }}" alt="{{ index $item 1 }}" loading="lazy" width="200" referrer-policy="no-referrer">
<div class="movie-info">
<div class="movie-title"><a rel="noreferrer" href="{{ index $item 5 }}" target="_blank">{{ index $item 1 }}</a></div>
<div class="movie-rating">
<div class="rating">
<span class="allstardark">
<span class="allstarlight" style="width:{{ mul 10 $rating }}%"></span>
</span>
<span class="rating_nums">{{ index $item 6 }}</span>
</div>
</div>
<div class="movie-card">{{ index $item 12 }}</div>
<div class="movie-comment">{{ index $item 9 }}</div>
</div>
</div>
</div>
{{ end }}
{{ end }}
</div>
<button id="loadMore">加载更多</button>
</div>
</div>
</div>
</div>
</div>
<script>
let visibleMovies = 18;
const movieItems = document.querySelectorAll('.movie-item');
const loadMoreButton = document.getElementById('loadMore');
function updateVisibility() {
movieItems.forEach((movie, idx) => {
movie.style.display = idx < visibleMovies ? 'block' : 'none';
});
if (visibleMovies >= movieItems.length) {
loadMoreButton.style.display = 'none';
}
}
loadMoreButton.addEventListener('click', () => {
visibleMovies += 18;
updateVisibility();
});
updateVisibility();
</script>
{{ end }}
|
代码中包括了页面元素和加载更多数据的 js
代码,并且在页面标题下添加了一个页面描述,方便在 markdown 文件中更改描述信息,也便于调整样式。同样页面中评分星级的命名 allstarlight
也是与之前豆瓣条目短代码一致,方便一起调整。
完成后在
custom.scss
中添加样式代码:
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
| // 电影海报墙样式
.posterwall-description {
margin: 10px;
text-align: center;
}
.movie-wall {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 3px;
padding: 3px;
}
.movie-item {
width: 100%;
margin-bottom: 0;
}
.movie-cover {
position: relative;
overflow: hidden;
aspect-ratio: 2 / 3;
}
.movie-cover img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.3s ease;
}
.movie-info {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.8);
color: #fff;
padding: 10px;
opacity: 0;
transition: opacity 0.3s ease;
overflow: auto;
display: flex;
flex-direction: column;
justify-content: center;
}
.movie-cover:hover img {
transform: scale(1.1);
}
.movie-cover:hover .movie-info {
opacity: 1;
}
#loadMore {
display: block;
margin: 20px auto;
padding: 10px 20px;
background-color: lighten($color-accent,0.1);
color: white;
border: none;
cursor: pointer;
}
#loadMore:hover {
background-color: gray;
}
.movie-info .movie-rating {
display: flex;
align-items: center;
margin-top: 3px;
margin-bottom: 3px;
}
.movie-info .movie-rating .rating .rating_nums {
font-size: 1.0em;
color: #fff;
}
.movie-info .movie-card {
margin: 5px 0;
font-size: 0.7em;
color: #fff;
}
.movie-info .movie-comment {
margin: 5px 0;
font-size: 0.7em;
color: #fff;
}
|
在 content
目录下创建一个 posterwall.md
文件,Front Matter
信息填写如下,标题可描述可以自由更改:
1
2
3
4
5
| ---
title: 海报墙
layout: "posterwall"
description: "这里是我已观看电影的海报墙,数据来源于豆瓣。"
---
|
添加后就可以在配置文件中添加一个菜单页面来指向海报墙,最终效果可以访问 👉 观影页面