generated from halo-dev/plugin-starter
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: completed the initial version design for the moments feature. (#2)
#### What type of PR is this? /kind feature #### Which issue(s) this PR fixes: Fixes halo-dev/halo#2930 #### What this PR does / why we need it: 瞬间插件初版功能设计。 Console 端: 1. 增加了“瞬间”管理页面。用户将可以通过 Console 创建瞬间。 2. 支持瞬间内容添加图片,视频。 3. 支持使用富文本编辑器。 主题端: 1. 新增了 `/moments` 及 `/moments/page/{page}` 路由,需使用 `moments.html` 页面,分页数量在插件设置中进行修改。 2. 增加了 `momentFinder`。 #### how to test it? 1. 测试 Console 端瞬间基本逻辑是否正确。包括 a. 新增一个瞬间内容,查看是否能够刷新列表且内容是否正确,图片或视频是否存在,可见性是否支持。 b. 双击已经存在的瞬间内容,查看是否能够修改,且修改后的数据是否正确。 c. 删除一个瞬间内容,查看能否被成功删除。 d. 使用搜索框,查看对应的瞬间内容能否被搜索到。 e. 查看分页数据是否符合逻辑。 2. 测试主题端 `moments.html` 是否存在 `moments` 数据,以及分页是否正常。 3. 测试主题端 `momentFinder` 是否正确读取到数据,分页是否正常。 可测试插件包:[plugin-moments-1.0.0-plain.jar.zip](https://github.com/halo-sigs/plugin-moments/files/11110429/plugin-moments-1.0.0-plain.jar.zip) #### Does this PR introduce a user-facing change? ```release-note 增加瞬间插件,为主题端提供 `/moments` 路由 ```
- Loading branch information
Showing
54 changed files
with
5,947 additions
and
837 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,253 @@ | ||
# plugin-moments | ||
|
||
Halo 2.0 的瞬间管理插件(WIP)。 | ||
Halo 2.0 的瞬间管理插件, 支持在 Console 进行管理以及为主题端提供 `/moments` 页面路由。 | ||
|
||
## 使用方式 | ||
|
||
1. 在 [Releases](https://github.com/halo-sigs/plugin-moments/releases) 下载最新的 JAR 文件。 | ||
2. 在 Halo 后台的插件管理上传 JAR 文件进行安装。 | ||
|
||
> 需要注意的是,此插件需要主题提供模板(moments.html)才能访问 `/moments`。 | ||
## 主题适配 | ||
|
||
目前此插件为主题端提供了 `/moments` 路由,模板为 `moments.html`,也提供了 [Finder API](https://docs.halo.run/developer-guide/theme/finder-apis),可以将瞬间列表渲染到任何地方。 | ||
|
||
## 开发环境 | ||
|
||
```bash | ||
git clone [email protected]:halo-sigs/plugin-moments.git | ||
|
||
# 或者当你 fork 之后 | ||
|
||
git clone [email protected]:{your_github_id}/plugin-moments.git | ||
``` | ||
|
||
```bash | ||
cd path/to/plugin-moments | ||
``` | ||
|
||
```bash | ||
# macOS / Linux | ||
./gradlew pnpmInstall | ||
|
||
# Windows | ||
./gradlew.bat pnpmInstall | ||
``` | ||
|
||
```bash | ||
# macOS / Linux | ||
./gradlew build | ||
|
||
# Windows | ||
./gradlew.bat build | ||
``` | ||
|
||
修改 Halo 配置文件: | ||
|
||
```yaml | ||
halo: | ||
plugin: | ||
runtime-mode: development | ||
classes-directories: | ||
- "build/classes" | ||
- "build/resources" | ||
lib-directories: | ||
- "libs" | ||
fixedPluginPath: | ||
- "/path/to/plugin-moments" | ||
``` | ||
### 模板变量 | ||
#### 路由信息 | ||
- 模板路径:/templates/moments.html | ||
- 访问路径:/moments | ||
#### 变量 | ||
moments | ||
##### 变量类型 | ||
[#UrlContextListResult\<MomentVo>](#urlcontextlistresult-momentvo) | ||
##### 示例 | ||
```html | ||
<div> | ||
<ul> | ||
<li th:each="moment : ${moments.items}" th:with="content=${moment.spec.content}"> | ||
<div th:if="${not #strings.isEmpty(content.html)}" th:utext="${content.html}"></div> | ||
<th:block th:if="${not #lists.isEmpty(content.medium)}" th:each="momentItem : ${content.medium}"> | ||
<img th:if="${momentItem.type.name == 'PHOTO'}" th:src="${momentItem.url}" /> | ||
<video th:if="${momentItem.type.name == 'VIDEO'}" th:src="${momentItem.url}"></video> | ||
</th:block> | ||
</li> | ||
</ul> | ||
<div th:if="${moments.hasPrevious() || moments.hasNext()}"> | ||
<a th:href="@{${moments.prevUrl}}"> | ||
<span>上一页</span> | ||
</a> | ||
<span th:text="${moments.page}"></span> | ||
<a th:href="@{${moments.nextUrl}}"> | ||
<span>下一页</span> | ||
</a> | ||
</div> | ||
</div> | ||
``` | ||
|
||
### Finder API | ||
|
||
#### listAll() | ||
|
||
##### 描述 | ||
|
||
获取全部瞬间内容。 | ||
|
||
##### 参数 | ||
|
||
无 | ||
|
||
##### 返回值 | ||
|
||
List<[#MomentVo](#momentvo)> | ||
|
||
##### 示例 | ||
|
||
```html | ||
<ul> | ||
<li th:each="moment : ${momentFinder.listAll()}" th:with="content = ${moment.spec.content}"> | ||
<div th:if="${not #strings.isEmpty(content.html)}" th:utext="${content.html}"></div> | ||
<th:block th:if="${not #lists.isEmpty(content.medium)}" th:each="momentItem : ${content.medium}"> | ||
<img th:if="${momentItem.type.name == 'PHOTO'}" th:src="${momentItem.url}" /> | ||
<video th:if="${momentItem.type.name == 'VIDEO'}" th:src="${momentItem.url}"></video> | ||
</th:block> | ||
</li> | ||
</ul> | ||
``` | ||
|
||
#### list(page, size) | ||
|
||
##### 描述 | ||
|
||
根据分页参数获取瞬间列表。 | ||
|
||
##### 参数 | ||
|
||
1. `page: int` - 分页页码,从 1 开始 | ||
2. `size: int` - 分页条数 | ||
|
||
##### 返回值 | ||
|
||
[ListResult\<MomentVo>](#listresult-momentvo) | ||
|
||
##### 示例 | ||
|
||
```html | ||
<th:block th:with="moments = ${momentFinder.list(1, 10)}"> | ||
<ul> | ||
<li th:each="moment : ${moments.items}" th:with="content = ${moment.spec.content}"> | ||
<div th:if="${not #strings.isEmpty(content.html)}" th:utext="${content.html}"></div> | ||
<th:block th:if="${not #lists.isEmpty(content.medium)}" th:each="momentItem : ${content.medium}"> | ||
<img th:if="${momentItem.type.name == 'PHOTO'}" th:src="${momentItem.url}" /> | ||
<video th:if="${momentItem.type.name == 'VIDEO'}" th:src="${momentItem.url}"></video> | ||
</th:block> | ||
</li> | ||
</ul> | ||
<div> | ||
<span th:text="${moments.page}"></span> | ||
</div> | ||
</th:block> | ||
``` | ||
|
||
### 类型定义 | ||
|
||
#### MomentVo | ||
|
||
```json | ||
{ | ||
"metadata": { | ||
"name": "string", // 唯一标识 | ||
"labels": { | ||
"additionalProp1": "string" | ||
}, | ||
"annotations": { | ||
"additionalProp1": "string" | ||
}, | ||
"creationTimestamp": "2022-11-20T13:06:38.512Z", // 创建时间 | ||
}, | ||
"spec": { | ||
"content": { | ||
"raw": "string", // 原始内容,一般用于编辑器使用 | ||
"html": "string", // HTML 内容,用于主题端进行最终渲染的内容 | ||
"medium": [ // 媒体内容 | ||
{ | ||
"type": "#MomentMediaType", // 类型 | ||
"url": "string", // 链接 | ||
"originType": "string", // 原始类型,例如:image/jpeg | ||
} | ||
] | ||
}, | ||
"releaseTime": "string", // 发布时间 | ||
"visible": "PUBLIC", // 可见性 | ||
"owner": "string", // 所属用户 | ||
}, | ||
"owner": { | ||
"name": "string", // 用户名 | ||
"avatar": "string", // 头像 | ||
"bio": "string", // 描述 | ||
"displayName": "string", // 显示名称 | ||
}, | ||
"stats": { | ||
"upvote": 0, // 点赞数 | ||
"totalComment": 0, // 评论数 | ||
"approvedComment": 0, // 审核通过的评论数 | ||
} | ||
} | ||
``` | ||
|
||
#### MomentMediaType | ||
|
||
```java | ||
enum Target { | ||
PHOTO, // 图片 | ||
VIDEO, // 视频 | ||
POST; // 文章 | ||
} | ||
``` | ||
|
||
#### ListResult<MomentVo> | ||
|
||
```json | ||
{ | ||
"page": 0, // 当前页码 | ||
"size": 0, // 每页条数 | ||
"total": 0, // 总条数 | ||
"items": "List<#MomentVo>", // 瞬间列表数据 | ||
"first": true, // 是否为第一页 | ||
"last": true, // 是否为最后一页 | ||
"hasNext": true, // 是否有下一页 | ||
"hasPrevious": true, // 是否有上一页 | ||
"totalPages": 0 // 总页数 | ||
} | ||
``` | ||
|
||
#### UrlContextListResult<MomentVo> | ||
|
||
```json | ||
{ | ||
"page": 0, // 当前页码 | ||
"size": 0, // 每页条数 | ||
"total": 0, // 总条数 | ||
"items": "List<#MomentVo>", // 瞬间列表数据 | ||
"first": true, // 是否为第一页 | ||
"last": true, // 是否为最后一页 | ||
"hasNext": true, // 是否有下一页 | ||
"hasPrevious": true, // 是否有上一页 | ||
"totalPages": 0, // 总页数 | ||
"prevUrl": "string", // 上一页链接 | ||
"nextUrl": "string" // 下一页链接 | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
VITE_API_URL= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.