FIT2CLOUD
主题漫游 的图标

主题漫游

382
111

告别一个站只能穿一套衣服的烦恼,多款主题随手切换、各有舞台;今天宠这个,明天宠那个,让每个主题都能雨露均沾。

主题漫游

主题漫游是一个面向 Halo 2.25+ 的多主题访客切换插件。站长可以把已安装主题与对应菜单绑定后开放给访客;每位访客只改变自己的页面渲染,不会启用或停用 Halo 的全局主题,也不会影响其他访客。

告别一个站只能穿一套衣服的烦恼。今天宠这个,明天宠那个,让安装过的主题都能雨露均沾。

主要能力

  • 自动读取 Halo 中已经安装的主题和菜单,无需手工新增主题数据。
  • 每套主题都能绑定自己的菜单,并决定是否开放给访客。
  • 支持为主题自动识别内置模板和自定义页面模板,并按一级、二级导航进行编排。
  • 访客可以自由切换站长准备的多套主题,不再只能看到一种风格,也让安装的每套主题都有机会派上用场。
  • 每位访客的选择独立保存,不会改变 Halo 当前启用的全局主题,也不会影响其他访客。
  • 切换后保留当前真实页面路径,并支持多种平滑切换动画。

效果演示

主题漫游效果演示

群聊讨论:

主题漫游群聊讨论

安装与使用

  1. 安装并启动插件。
  2. 在 Console 左侧进入“主题漫游”。
  3. 根据需要为主题选择 Halo 菜单,或编排主题自己的导航结构。
  4. 打开需要向访客展示的主题。
  5. 在“漫游配置”中设置记忆时间、开放范围、入口位置和切换动画。

如果没有任何主题处于“前台开放”状态,插件不会向站点页面注入切换入口。

主题接入

插件不要求主题进行适配,默认会自动注入完整的主题切换入口。主题需要指定入口位置时,可以提供一个稳定锚点:

<div data-theme-roaming-anchor></div>

如果希望完全使用主题自己的按钮,只需添加 data-theme-roaming-open。插件检测到自定义按钮后,不会重复显示默认入口:

<button type="button" data-theme-roaming-open>切换主题</button>

自定义默认按钮

主题可以通过 CSS 变量调整默认入口的尺寸、圆角、颜色、背景、边框和阴影:

[data-theme-roaming-anchor] {
  --tr-trigger-size: 36px;
  --tr-trigger-embedded-size: 36px;
  --tr-trigger-radius: 12px;
  --tr-trigger-color: #be185d;
  --tr-trigger-background: #fdf2f8;
  --tr-trigger-border: #fbcfe8;
  --tr-trigger-shadow: none;
  --tr-trigger-hover-color: #db2777;
  --tr-trigger-hover-background: #fce7f3;
  --tr-trigger-hover-border: #f472b6;
  --tr-trigger-hover-shadow: none;
  --tr-trigger-icon-size: 17px;
}

需要进一步控制时,可以通过 Shadow Parts 修改插件内部元素:

#theme-roaming-root::part(trigger) {
  transition: transform 160ms ease;
}

#theme-roaming-root::part(trigger):hover {
  transform: translateY(-1px);
}

JavaScript 接口

前台接口为 window.ThemeRoaming,提供以下方法:

  • open():打开主题面板。
  • close():关闭主题面板。
  • toggle():切换面板状态。
  • refresh():重新读取开放主题。
  • select(themeName):切换到指定主题。
  • getState():读取当前主题漫游状态。
  • mount(anchor):把入口挂载到指定元素。
  • setAppearance(options):动态设置默认入口样式。

调用前应判断接口是否存在:

window.ThemeRoaming?.open();

动态设置入口样式:

window.ThemeRoaming?.setAppearance({
  size: "36px",
  radius: "12px",
  color: "#be185d",
  background: "#fdf2f8",
  border: "#fbcfe8",
  shadow: "none"
});

插件会派发 theme-roaming:catalogtheme-roaming:statechangetheme-roaming:before-switchtheme-roaming:error 事件,主题可以按需监听。

数据与菜单接口

开放主题目录:

GET /apis/roaming.serenity/v1alpha1/catalog

Thymeleaf 可以通过 themeRoamingFinder.getCatalog() 获取当前主题和开放主题列表。

菜单绑定和自定义导航建议使用 themeRoamingMenuFinder。未安装插件时必须保留 Halo 原生 menuFinder 回退:

${themeRoamingMenuFinder != null
  ? themeRoamingMenuFinder.getForTheme(theme.metadata.name).menuItems
  : menuFinder.getPrimary().menuItems}

开发与构建

插件版本仅在 gradle.propertiespluginVersion 中维护,插件元数据和 JAR 文件名会在构建时自动同步。

.\gradlew clean build

构建包含 Console 前端、Java 编译和单元测试,产物位于 build/libs/

兼容性

  • Halo:>= 2.25.0
  • Java:21

Halo 升级后建议重新执行完整构建,并验证首页、列表页、文章页、主题静态资源、菜单绑定和自定义导航。

源码与反馈


讨论(0)

这是一个开源应用,我们推荐优先在开源仓库中提交 issue,以便开发者更好地接收和跟进问题。

去提交 issue