Hugo博客添加豆瓣观影页面
通过 GitHub doumark-action 保存豆瓣观影数据,并给 Hugo 博客添加豆瓣观影页面。

前言

Hexohexo-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.csvbook.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---

添加后就可以在配置文件中添加一个菜单页面来指向海报墙,最终效果可以访问 👉 观影页面

参考


最后修改于 2024-08-19