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