edbf78f236
- Halo Plugin 后端(Java/Gradle),含 DarkModePlugin 主类和测试 - Vue 3 + TypeScript 前端 UI,包含主题切换组件和设置页面 - 暗色模式 CSS 变量和覆盖样式(布局/编辑器/表单/滚动条等) - 设计文档和调查文档 - Halo 插件/主题开发 Agent Skills Co-Authored-By: Claude <noreply@anthropic.com>
5.4 KiB
5.4 KiB
DevTools (run.halo.plugin.devtools)
A Gradle plugin for streamlined plugin development. Requires Docker.
Quick Commands
| Command | Purpose |
|---|---|
./gradlew haloServer |
Start Halo in Docker with plugin loaded in dev mode |
./gradlew reload |
Reload plugin changes without restarting Halo |
./gradlew watch |
Auto-reload on file changes |
./gradlew build |
Build plugin JAR (includes frontend build) |
./gradlew generateApiClient |
Generate TypeScript API client from OpenAPI |
./gradlew generateRoleTemplates |
Generate role template YAML from OpenAPI |
build.gradle Setup
plugins {
id 'java'
id "io.freefair.lombok" version "8.13"
id "run.halo.plugin.devtools" version "0.6.0"
}
group = 'com.example.myplugin'
repositories {
mavenCentral()
}
dependencies {
implementation platform('run.halo.tools.platform:plugin:2.22.0')
compileOnly 'run.halo.app:api'
testImplementation 'run.halo.app:api'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
test {
useJUnitPlatform()
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
tasks.withType(JavaCompile).configureEach {
options.encoding = "UTF-8"
options.release = 21
}
// UI build integration (if UI is in a separate subproject)
tasks.register('processUiResources', Copy) {
from project(':ui').layout.buildDirectory.dir('dist')
into layout.buildDirectory.dir('resources/main/console')
dependsOn project(':ui').tasks.named('assemble')
shouldRunAfter tasks.named('processResources')
}
tasks.named('classes') {
dependsOn tasks.named('processUiResources')
}
halo {
version = '2.22'
superAdminUsername = 'admin'
superAdminPassword = 'admin'
port = 8090
// debug = true
// debugPort = 5005
// suspend = true
externalUrl = 'http://localhost:8090'
}
halo {} Block Options
| Option | Description | Default |
|---|---|---|
version |
Halo Docker image version | '2.9.1' |
superAdminUsername |
Auto-created admin username | 'admin' |
superAdminPassword |
Auto-created admin password | 'admin' |
port |
Halo server port | 8090 |
externalUrl |
External access URL | 'http://localhost:8090' |
debug |
Enable JDWP debug | false |
debugPort |
JDWP port | auto-assigned |
suspend |
Suspend on startup until debugger connects | false |
docker.url |
Docker daemon URL | unix:///var/run/docker.sock (Mac/Linux) |
docker.apiVersion |
Docker API version | '1.42' |
Watch Configuration
haloPlugin {
watchDomains {
consoleSource {
files files('ui/src/')
// exclude '**/node_modules/**'
}
}
}
Generate API Client
Requires OpenAPI grouping configuration in build.gradle:
haloPlugin {
openApi {
groupingRules {
extensionApis {
displayName = 'Extension API for MyPlugin'
pathsToMatch = ['/apis/my-plugin.halo.run/v1alpha1/**']
}
}
groupedApiMappings = [
'/v3/api-docs/extensionApis': 'extensionApis.json'
]
generator {
outputDir = file("${projectDir}/ui/src/api/generated")
additionalProperties = [
useES6: true,
useSingleRequestParameter: true,
withSeparateModelsAndApi: true,
apiPackage: "api",
modelPackage: "models"
]
typeMappings = [
set: "Array"
]
}
}
}
Usage in TypeScript:
import { axiosInstance } from "@halo-dev/api-client";
import { MyResourceV1alpha1Api } from "./api/generated";
const api = new MyResourceV1alpha1Api(undefined, "", axiosInstance);
const { data } = await api.listMyResources({});
Generate Role Templates
After configuring OpenApi grouping, run:
./gradlew generateRoleTemplates
Generates roleTemplates.yaml in the workplace/ directory. Review and customize before adding to src/main/resources/extensions/.
Custom Halo Config
Place workplace/config/application.yaml to override Halo defaults:
logging:
level:
run.halo.app: DEBUG