本文介绍通过 NeoDB API 和 Shortcode 在 Hugo 中创建观影页面的方法。
NeoDB 致力于为联邦宇宙居民提供一个自由开放互联的书籍、电影、音乐和游戏收藏评论空间。
– NeoDB
什么是 NeoDB
NeoDB
NeoDB 是一个去中心化的开源的社区平台,支持书籍、电影、剧集、播客、游戏、演出等多种类型的收藏。
相比于国内的豆瓣,NeoDB
- 不存在审查制度,也没有广告。
- 外文书和冷门内容收录更全面。
- 数据可方便地从豆瓣导入,也可导出。
通过 API 获取 NeoDB 数据
NeoDB 提供了开放的 API,可以通过 API 获取用户的书影音记录。
该 API 的用法
- URL 为
https://neodb.social/api/me/shelf
- 需要 Bearer Token
- 指定 Path Variable
type
为 wishlist
, progress
, complete
中的一个
- (可选) 指定 Query Param
category
为 book
, movie
, tv
, podcast
, music
, game
, performance
中的一个
- (可选) 指定 Query Param
page
为页码
例如 https://neodb.social/api/me/shelf/complete?category=book&page=1
获取 Access Token 的方法:NeoDB Developer#How to authorize, 也可以生成 Test Access Token 用于测试。
为了方便使用、封装 TOKEN 信息,我们可以将获取 API 独立部署成一个 Cloudflare Worker。
- 在 Cloudflare Workers 中创建一个新的 Worker
- 设置环境变量
NEODB_TOKEN
,值为刚刚获取的 Access Token
worker.js
内容如下:
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
|
const myBearer = NEODB_TOKEN; // Assuming 'NEODB_TOKEN' is set in your Cloudflare Worker's environment variables
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
try {
console.log(myBearer)
const url = new URL(request.url);
const category = url.pathname.substring(1);
// Optionally, handle query parameters (e.g., page number)
const page = url.searchParams.get('page') || '1';
// Available values : wishlist, progress, complete
const type = url.searchParams.get('type') || 'complete';
let dbApiUrl = `https://neodb.social/api/me/shelf/${type}?category=${category}&page=${page}`;
const response = await fetch(dbApiUrl, {
method: 'get',
headers: {
'Accept': 'application/json',
'Authorization': `Bearer ${myBearer}`
}
});
// Check if the response from the API is OK (status code 200-299)
if (!response.ok) {
throw new Error(`API returned status ${response.status}`);
}
// Optionally, modify or just forward the API's response
const data = await response.json();
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' },
status: response.status
});
} catch (error) {
// Handle any errors that occurred during the fetch
return new Response(error.message, { status: 500 });
}
}
|
通过 Hugo Shortcode 将数据整合到 Hugo 中
在 /layouts/shortcodes
中创建 neodb.html
,注意替换你的 Cloudflare Worker URL:
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
|
<!--Available categories: book, movie, tv, podcast, music, game, performance-->
{{ $category := .Get 0 }}
<!--Available types: wishlist, progress, complete-->
{{ $type := .Get 1 }}
{{ if eq $type "" }}
{{ $type = "complete" }}
{{ end }}
{{ $url := printf "https://your-worker-url/%s?type=%s" $category $type }}
{{ $json := getJSON $url}}
<div class="item-gallery">
{{ range $value := first 10 $json.data }}
{{ $item := $value.item }}
<div class="item-card">
<a class="item-card-upper" href="{{ $item.id }}" target="_blank" rel="noreferrer">
<img class="item-cover" src="{{ .item.cover_image_url }}" alt="{{ .item.display_title }}">
</a>
{{ if .item.rating }}
<div class="rate">
<span><b>{{ .item.rating }}</b>🌟</span>
<br>
<span class="rating-count"> {{.item.rating_count}}人评分</span>
</div>
{{ else}}
<div class="rate">
<span>暂无🌟</span>
<br>
<span class="rating-count"> {{.item.rating_count}}人评分</span>
</div>
{{ end }}
<h3 class="item-title">{{ .item.display_title }}</h3>
</div>
{{ end }}
</div>
<style>
.item-gallery {
display: flex;
padding: 0 1rem;
overflow-x: scroll;
align-items: baseline;
}
.item-card {
display: flex;
flex-direction: column;
flex: 0 0 17%;
margin: 0 0.5rem 1rem;
border-radius: 5px;
transition: transform 0.2s;
width: 8rem;
}
.item-card:hover {
transform: translateY(-5px);
}
.rate {
text-align: center;
}
.rating-count {
font-size: 0.8rem;
color: grey;
}
.item-cover {
width: 100%;
min-height: 3rem;
border: 2px solid transparent;
}
.item-title {
font-size: 1rem;
text-align: center;
margin: 0;
}
</style>
|
然后,在页面中使用 shortcode 引用即可:
1
2
3
4
5
6
7
8
9
|
(去除下列 shortcodes 中的 `\`)
## 想读的书
\{\{< neodb book wishlist>\}\}
## 读过的书
\{\{< neodb book complete>\}\}
|
效果示例