#### What type of PR is this?
/kind feature
/area core
/milestone 2.7.x
#### What this PR does / why we need it:
支持通过 ExternalUrlSupplier 获取 externalUrl 配置
#### Which issue(s) this PR fixes:
Fixes#4149
#### Does this PR introduce a user-facing change?
```release-note
支持通过 ExternalUrlSupplier 获取 externalUrl 配置
```
#### What type of PR is this?
/kind feature
/milestone 2.7.x
/area core
/area theme
#### What this PR does / why we need it:
主题端支持获取最新评论
可能存在的问题:
主题端如果想展示评论所属的具体的主体比如 Moment 可能不好展示
how to test it?
通过 list 方法获取评论看排序和数据是否正确
```html
<p th:each="result : ${commentFinder.list(null,1,10)}">
<span th:text="${result.spec.raw}"></span>
-> <span th:text="${#temporals.format(result.spec.creationTime, 'yyyy-MM-dd HH:mm:ss')}"></span>
-> <span th:text="${result.spec.subjectRef}"></span>
</p>
```
#### Which issue(s) this PR fixes:
Fixes#4088
#### Does this PR introduce a user-facing change?
```release-note
主题端支持获取最新评论
```
#### What type of PR is this?
/kind feature
/milestone 2.7.x
/area core
#### What this PR does / why we need it:
为主题端的文章和自定义页面内容添加扩展点
插件可以通过实现扩展点来干预文章和自定义页面的内容显示,如修改内容的 html 结构,改变特定样式等
使用方式参考:[docs/extension-points/content.md](9b2b9f1837)
#### Which issue(s) this PR fixes:
Fixes#4003
#### Does this PR introduce a user-facing change?
```release-note
为主题端的文章和自定义页面内容添加扩展点
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.7.x
#### What this PR does / why we need it:
修复文章页 HTML Meta 标签重复问题
see #4049 for more details.
#### Which issue(s) this PR fixes:
Fixes#4049
#### Does this PR introduce a user-facing change?
```release-note
修复文章页 Meta Description 标签重复问题
```
#### What type of PR is this?
/kind feature
/area core
#### What this PR does / why we need it:
This PR adds dependency [spring-boot-starter-cache](https://docs.spring.io/spring-boot/docs/current/reference/html/io.html#io.caching) as cache framework and [caffeine](https://github.com/ben-manes/caffeine/wiki) as cache implementation to cache template rendering result.
By default, we disable the cache feature. If you want to enable it, please try to configure properties like this:
```yaml
halo:
cache:
disabled: false
```
#### Which issue(s) this PR fixes:
Fixes#2827
#### Special notes for your reviewer:
1. Start Halo
2. Browse any page twice
3. See the difference in request times
#### Does this PR introduce a user-facing change?
```release-note
支持模板渲染结果缓存
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.7.x
/kind api-change
#### What this PR does / why we need it:
统一主题和插件描述文件的部分字段
1. 统一网站字段为 homepage,将主题的 website 标记为过时并兼容为 homepage
2. 主题添加 license 字段
3. 插件添加 repo
#### Which issue(s) this PR fixes:
Fixes#4011
#### Does this PR introduce a user-facing change?
```release-note
统一主题和插件描述文件的部分字段
```
#### What type of PR is this?
/kind feature
/area core
#### What this PR does / why we need it:
This PR introduces https://github.com/resilience4j/resilience4j to archive the feature. The login endpoint has limited login failures at a rate of 3 per minute.
See https://github.com/halo-dev/halo/issues/4044 for more.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/4044
#### Special notes for your reviewer:
1. Start Halo.
2. Try to login with incorrect credential 4 times
3. Check the response.
#### Does this PR introduce a user-facing change?
```release-note
增加登录失败次数限制功能
```
#### What type of PR is this?
/kind improvement
/kind bug
/area core
/area plugin
/milestone 2.6.x
#### What this PR does / why we need it:
修复插件重启后 MainClass 对象缓存未清除的问题
how to test it?
下载此插件:
[plugin-starter-1.0.0-SNAPSHOT.jar.zip](https://github.com/halo-dev/halo/files/11620847/plugin-starter-1.0.0-SNAPSHOT.jar.zip)
安装并启动插件,会看到类似如下日志:
```
测试从 [/var/folders/1z/3hlt62691tx63dxx6y0mryw00000gn/T/halo-plugin3709893537121269748.txt] 文件读取内容
插件启动成功!
```
修改日志中给出的文件的内容后 reload 插件会看到`插件启动成功!` 后会跟随最新的文件内容则表示 MainClass 是最新的状态没有缓存。
#### Which issue(s) this PR fixes:
Fixes#4016
#### Does this PR introduce a user-facing change?
```release-note
修复插件重启后 MainClass 对象缓存未清除的问题
```
#### What type of PR is this?
/kind improvement
/area core
#### What this PR does / why we need it:
Replace R2DBC MySQL driver to io.asyncer:r2dbc-mysql. See https://github.com/halo-dev/halo/issues/3804 for more.
Please note that there will be an error like below when starting up Halo on MacOS:
```java
2023-05-09T14:24:45.161+08:00 ERROR 4668 --- [ restartedMain] i.n.r.d.DnsServerAddressStreamProviders : Unable to load io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider, fallback to system defaults. This may result in incorrect DNS resolutions on MacOS. Check whether you have a dependency on 'io.netty:netty-resolver-dns-native-macos'. Use DEBUG level to see the full stack: java.lang.UnsatisfiedLinkError: failed to load the required native library
```
After manual test, I haven't found any problems caused by the error. And this only occurs on MacOS when developing.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/3804
#### Special notes for your reviewer:
Steps to test:
1. Start up a MySQL server, e.g.:
```bash
docker run -it --rm --name halodb -p 3306:3306 -e MYSQL_ROOT_PASSWORD=openmysql -e MYSQL_DATABASE=halo mysql:8
```
3. Start Halo with mysql profile active
```bash
make -C console dev
./gradlew bootRun --args="--spring.profiles.active=dev,mysql --halo.plugin.runtime-mode=deployment"
```
5. Check the functionality of Halo
#### Does this PR introduce a user-facing change?
```release-note
替换 R2DBC MySQL 驱动为:io.asyncer:r2dbc-mysql
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.6.x
#### What this PR does / why we need it:
This PR fixes the problem of deleting failed plugins for a long time by replacing older delayed entry in reconciler queue.
#### Does this PR introduce a user-facing change?
```release-note
修复长时间删除失败的插件问题
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.6.x
#### What this PR does / why we need it:
Sort properties before building.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/3944
#### Special notes for your reviewer:
Try to generate api client several times.
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind bug
/kind improvement
/area core
#### What this PR does / why we need it:
This PR refactors post reconciler to reduce post updates and refines post events.
Previously, we need 3 - 4 updates per reconciliation, but now we only need 1. And all events collected in reconciler will be fired after updating post.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/3121
#### Special notes for your reviewer:
0. Install search plugin
1. Create a public post and publish it
2. Search posts
3. Try to make the post private
4. Search posts
5. Try to make the post public
6. Search posts
7. Try to delete the post
8. Search posts
9. Try to recover the post
10. Search posts
#### Does this PR introduce a user-facing change?
```release-note
修复依然能搜索到已删除文章的问题
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.5.x
#### What this PR does / why we need it:
优化插件的升级流程
how to test it?
1. 测试正常的插件升级是否正常
2. 测试插件升级失败后插件是否会被卸载的问题
3. 测试没有 version 的插件安装是否能成功
4. 在插件目录不会多出一个名为 `{升级插件名称}-null.jar` 的文件
#### Which issue(s) this PR fixes:
Fixes#3839
#### Does this PR introduce a user-facing
```release-note
优化插件的升级流程
```
#### What type of PR is this?
/kind feature
/area core
/milestone 2.5.x
/kind api-change
#### What this PR does / why we need it:
为客户端提供一套 APIs
#### Which issue(s) this PR fixes:
Fixes#3661
#### Does this PR introduce a user-facing change?
```release-note
为访客端提供一套完整的 API
```
#### What type of PR is this?
/kind improvement
/kind api-change
/area core
/milestone 2.5.x
#### What this PR does / why we need it:
Add property `halo.use-absolute-permalink`(default is `false`) to control permalink generation. Leave `halo.external-url` as `null` by default.
Meanwhile, I enhanced `ExternalUrlSupplier#getURL` to get URL from not only properties but only http request.
#### How to use it?
```yaml
halo:
use-absolute-permalink: false
```
Or:
```yaml
halo:
external-url: https://halo.run/
use-absolute-permalink: false
```
Or:
```yaml
halo:
external-url: https://halo.run/
use-absolute-permalink: true
```
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/3762
#### Special notes for your reviewer:
#### Does this PR introduce a user-facing change?
```release-note
新增是否生成相对地址的配置
```
#### What type of PR is this?
/kind feature
/area core
#### What this PR does / why we need it:
Use Gradle plugin `maven-publish` to publish Halo modules(`platform.application`, `platform.plugin` and `api`) to Maven central repository.
```bash
# Try to publish to Maven local repository.
./gradlew publish
# Really publish to Maven central repository.
./gradlew -Prelease publish -PossrhUsername=username -PossrhPassword=password
```
Note that currently we only support manually publishing.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/2730
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind feature
/area core
/area plugin
#### What this PR does / why we need it:
This PR refactor AttachmentEndpoint by extracting `upload`, `delete`, `getPremalink` and `getSharedURL` logic in the endpoint into AttachmentService. Meanwhile, I expose the service to plugin, so that we can use the service in plugin conveniently.
#### Special notes for your reviewer:
Please confirm that those changes won't influence existing attachment features.
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind bug
/area core
#### What this PR does / why we need it:
- Use the class loader belonging to the parameter type when creating a generic class.
- Use full qualified class name when generating a generic class.
Before testing, you have to set property `springdoc.cache.disabled` to `true`.
#### Which issue(s) this PR fixes:
Fixes#3728
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind cleanup
/area core
#### What this PR does / why we need it:
Move common classes related to theme into api module.
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind feature
/milestone 2.4.x
/area core
#### What this PR does / why we need it:
提供 ReactiveSettingFetcher 供插件获取配置
此 PR 基于原有的阻塞的 SettingFetcher 逻辑挪到 DefaultReactiveSettingFetcher 中并将阻塞的实现用 Reactive 得代理,不需要测试,单元测试过了即可。
可以尝试在插件中依赖注入 ReactiveSettingFetcher 看是否能正确注入
#### Which issue(s) this PR fixes:
Fixes#3620
#### Does this PR introduce a user-facing change?
```release-note
提供 ReactiveSettingFetcher 供插件获取配置
```
#### What type of PR is this?
/kind feature
/milestone 2.4.x
/area core
#### What this PR does / why we need it:
支持聚合多个角色到一个角色
see #3560 for more details.
how to test it?
创建一个测试角色和和一个 RoleBinding 将此角色的绑定到其他角色,在不修改用户权限的情况下,用户将拥有新创建的测试角色的权限。
#### Which issue(s) this PR fixes:
Fixes#3560
#### Does this PR introduce a user-facing change?
```release-note
支持聚合多个角色到一个角色
```
#### What type of PR is this?
/kind feature
/milestone 2.4.x
/area core
#### What this PR does / why we need it:
提供 Secret 自定义模型用于存储敏感数据
例如:密码、token 等
参考自: https://kubernetes.io/docs/concepts/configuration/secret
#### Which issue(s) this PR fixes:
Fixes#3267
#### Does this PR introduce a user-facing change?
```release-note
提供 Secret 自定义模型用于存储敏感数据
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.4.x
/kind api-change
#### What this PR does / why we need it:
修复未审核过的回复包含在了评论的回复数量中的问题
此改动需要评论组件修改回复数量取值为 `status.visibleReplyCount`
how to test it?
1. 创建评论,并在评论下回复
2. 评论的所有回复被计数在 `status.replyCount` 中
3. 而 `status.visibleReplyCount` 数量不包含 `spec.hiden=true` 或 `spec.approved = false` 的
#### Which issue(s) this PR fixes:
Fixes#3165
#### Does this PR introduce a user-facing change?
```release-note
修复未审核过的回复包含在了评论的回复数量中的问题
```
#### What type of PR is this?
/kind improvement
/area console
#### What this PR does / why we need it:
隐藏个人资料中未启用的认证方式。
#### Which issue(s) this PR fixes:
Fixes#3556
#### Special notes for your reviewer:
测试方式:
1. 安装 OAuth 2 插件:https://github.com/halo-sigs/plugin-oauth2/pull/3
2. 再不做任何配置的情况下,访问已登录用户的个人资料页面,检查是否列出了认证方式。
3. 配置某个认证方式并开启,再检查是否列出了已启用的认证方式。
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind cleanup
/area core
#### What this PR does / why we need it:
This PR totally refactor project structure for a better plugin development. Now we can maintain and publish api and platform modules at Halo application side, which will be references by plugins.
Currently, we can execute command `./gradlew clean publish` to publish api and platform modules into **local** Maven repository, so that we can refer these dependencies (`run.halo.tools.platform:plugin:2.4.0-SNAPSHOT` and `run.halo.app:api:2.4.0-SNAPSHOT`) in plugin projects.
I will make another pull request to publish api library and platforms into Maven central repository.
**Modules explanation**:
- API module contains common classes which might be used by plugins.
- Plugin Platform module contains dependency declarations of other plugin API modules.
- Application Platform module contains dependency declarations application module might uses.
If we want to build application only(exclude check and jar), we have to execute the command below:
```bash
./gradlew clean :application:build -x :application:check -x :application:jar
```
The executable Jar will be generated at folder `application/build/libs/`.
If we want to build a Docker image, we could execute the command below:
```bash
docker build -t johnniang/halo:project-structure .
# Test the Docker image
docker run -it --rm -p8090:8090 johnniang/halo:project-structure
```
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/2730
#### Special notes for your reviewer:
#### Does this PR introduce a user-facing change?
```release-note
重构项目结构
```