Halo自定义插件开发,拓展网站功能
给 Halo 博客增加一个官方没有的功能,最稳妥的方式就是自己写一个插件。
本文面向零基础用户,讲清楚 Halo 自定义插件开发的完整流程:从环境准备、项目搭建、代码编写,到本地调试、打包安装和线上验证,跟着做就能把功能挂到自己的网站上。
开发前需要准备什么
Halo 插件本质是一个 Java 项目,最终打包成 Jar 文件放到 plugins 目录加载。
开始之前,确认下面几项已经就绪:
- Halo 版本:建议使用 Halo 2.x,插件机制基于 Spring Boot 和 PF4J,不同版本 API 可能有差异,以你实际运行的版本为准。
- JDK:安装 JDK 17 或更高版本,终端执行
java -version确认输出正常。 - 构建工具:推荐 Gradle,Halo 官方插件模板默认使用它。
- 开发工具:IntelliJ IDEA 社区版即可,方便导入 Gradle 项目。
- Halo 运行环境:本地用 Docker 跑一个测试实例最省事,命令如下:
docker run -d --name halo-test -p 8090:8090 \
-v ~/halo-test:/root/.halo2 \
halohub/halo:2.20
启动后访问 http://你的IP:8090 完成初始化,后台地址通常是 /console。
从模板创建插件项目
不要从空项目手写,直接使用官方插件模板能省去大量配置。
- 打开 Halo 插件模板仓库(以官方实际地址为准),点击
Use this template生成自己的仓库,或直接下载 ZIP 解压。 - 用 IDEA 打开项目根目录,等待 Gradle 依赖下载完成。
- 找到
src/main/resources/plugin.yaml,修改基础信息:
apiVersion: plugin.halo.run/v1alpha1
kind: Plugin
metadata:
name: my-plugin
spec:
enabled: true
requires: ">=2.0.0"
author:
name: yourname
logo: logo.png
displayName: "我的自定义插件"
description: "演示如何拓展网站功能"
version: 1.0.0
requires 字段声明兼容的 Halo 版本范围,写错会导致插件无法启用。
编写第一个功能:自定义 API 接口
下面实现一个简单功能:提供一个接口,返回当前网站的文章总数。
在 src/main/java 下新建包,例如 com.example.myplugin,创建控制器类:
package com.example.myplugin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import run.halo.app.extension.ListOptions;
import run.halo.app.extension.ReactiveExtensionClient;
import reactor.core.publisher.Mono;
@RestController
@RequestMapping("/apis/my-plugin.example.com/v1alpha1")
public class PostCountController {
private final ReactiveExtensionClient client;
public PostCountController(ReactiveExtensionClient client) {
this.client = client;
}
@GetMapping("/post-count")
public Mono getPostCount() {
return client.list(Post.class, ListOptions.builder().build(), null)
.count();
}
}
注意 Halo 2.x 使用响应式编程模型,返回类型用 Mono 或 Flux,不要用阻塞式写法,否则接口会卡住。
本地调试与打包安装
代码写完后,先在本地验证再上线。
- 在项目根目录执行构建:
./gradlew build
构建成功后在 build/libs/ 下会生成 my-plugin-1.0.0.jar。
- 把 Jar 文件上传到 Halo 的插件目录。如果用 Docker 部署,路径是映射出来的
~/halo-test/plugins/;如果用宝塔面板,通常在/www/wwwroot/halo/plugins/。 - 重启 Halo 容器或服务:
docker restart halo-test
- 登录 Halo 后台,进入“插件”页面,应该能看到“我的自定义插件”,状态为已启用。
- 验证接口是否生效,在浏览器或终端访问:
curl http://你的IP:8090/apis/my-plugin.example.com/v1alpha1/post-count
返回一个数字就说明插件已经正常工作。
容易踩坑的几个地方
- 插件无法启用:检查
plugin.yaml里的requires版本范围是否包含当前 Halo 版本,以及metadata.name是否只包含小写字母和短横线。 - 接口返回 404:确认
@RequestMapping路径没有和其他插件冲突,Halo 插件 API 建议使用反向域名格式。 - 修改代码后不生效:每次修改 Java 代码都需要重新执行
./gradlew build并替换 Jar,Halo 热加载能力有限,不要指望保存即生效。 - 打包后缺少依赖:模板默认会把依赖打进 Jar,如果手动改了 Gradle 配置,注意不要遗漏
runtimeClasspath相关设置。
上线前检查与后续拓展
插件在本地跑通后,上线前建议做三件事:确认生产 Halo 版本与开发环境一致;
备份 plugins 目录和数据库;
先在测试站点启用观察一天,再推到正式站点。
后续想拓展更复杂的功能,可以继续研究 Halo 的 ExtensionClient 操作自定义模型、通过 @Component 注册监听器响应文章发布事件,或者开发后台管理界面。
插件开发的核心思路就是:声明元数据、编写 Spring Bean、打包成 Jar 放入插件目录。
掌握这个循环,Halo 自定义插件开发就不再是门槛。
常见疑问
没有 Java 基础能开发 Halo 插件吗?
需要至少能看懂 Java 类和注解,完全零基础建议先补 Spring Boot 入门,否则调试会非常吃力。
插件会不会影响 Halo 升级?
会。
Halo 大版本升级时插件 API 可能变化,升级前查看插件是否有兼容新版本的发布,或者先备份再升级。
开发好的插件能分享给别人吗?
可以。
打包出的 Jar 文件别人放到自己的 plugins 目录也能用,但要注意声明正确的兼容版本范围,避免对方环境报错。