edbf78f236
- Halo Plugin 后端(Java/Gradle),含 DarkModePlugin 主类和测试 - Vue 3 + TypeScript 前端 UI,包含主题切换组件和设置页面 - 暗色模式 CSS 变量和覆盖样式(布局/编辑器/表单/滚动条等) - 设计文档和调查文档 - Halo 插件/主题开发 Agent Skills Co-Authored-By: Claude <noreply@anthropic.com>
4.5 KiB
4.5 KiB
Search Integration
Integrate custom extensions with Halo's built-in search engine.
Source: HaloDocument | HaloDocumentsProvider | SearchEngine
HaloDocumentsProvider
Implement this extension point to make your custom Extension searchable.
@Component
public class MyDocumentProvider implements HaloDocumentsProvider {
private final ReactiveExtensionClient client;
public MyDocumentProvider(ReactiveExtensionClient client) {
this.client = client;
}
@Override
public Flux<HaloDocument> fetchAll() {
return client.listAll(MyExtension.class, new ListOptions(), Sort.unsorted())
.filter(ext -> ext.getMetadata().getDeletionTimestamp() == null)
.map(this::convertToDocument);
}
@Override
public String getType() {
return "myextension.mygroup.halo.run";
}
private HaloDocument convertToDocument(MyExtension ext) {
var doc = new HaloDocument();
doc.setId(ext.getMetadata().getName());
doc.setMetadataName(ext.getMetadata().getName());
doc.setTitle(ext.getSpec().getTitle());
doc.setDescription(ext.getSpec().getDescription());
doc.setContent(stripHtml(ext.getSpec().getContent()));
doc.setOwnerName(ext.getSpec().getOwner());
doc.setCreationTimestamp(ext.getMetadata().getCreationTimestamp());
doc.setUpdateTimestamp(ext.getMetadata().getCreationTimestamp());
doc.setPermalink("/my-extensions/" + ext.getSpec().getSlug());
doc.setType(getType());
doc.setPublished(true);
doc.setRecycled(false);
doc.setExposed(true);
return doc;
}
}
Search Events
Publish events to add/remove documents from the search index:
// Add or update documents
applicationEventPublisher.publishEvent(
new HaloDocumentAddRequestEvent(this, List.of(haloDoc)));
// Delete documents by ID
applicationEventPublisher.publishEvent(
new HaloDocumentDeleteRequestEvent(this, List.of("doc-id-1", "doc-id-2")));
// Rebuild entire index (e.g., on plugin config change)
applicationEventPublisher.publishEvent(
new HaloDocumentRebuildRequestEvent(this));
SearchEngine (Replacing Default)
To replace Halo's default search engine (e.g., with Meilisearch):
@Component
public class MeilisearchEngine implements SearchEngine {
@Override
public boolean available() {
return meilisearchClient != null && meilisearchClient.isHealthy();
}
@Override
public void addOrUpdate(Iterable<HaloDocument> docs) {
// Batch index documents
}
@Override
public void deleteDocument(Iterable<String> ids) {
// Batch delete by ID
}
@Override
public void deleteAll() {
// Clear index
}
@Override
public SearchResult search(SearchOption option) {
// Execute search query
}
}
HaloDocument Fields
| Field | Description | Required |
|---|---|---|
id |
Global unique document ID | Yes |
metadataName |
Extension metadata name | Yes |
title |
Document title | Yes |
content |
Plain text content (no HTML) | Yes |
description |
Short description | No |
permalink |
URL path | Yes |
type |
Document type identifier | Yes |
ownerName |
Owner metadata name | Yes |
categories |
Category metadata names | No |
tags |
Tag metadata names | No |
published |
Whether published | Yes |
recycled |
Whether in recycle bin | Yes |
exposed |
Whether publicly visible | Yes |
creationTimestamp / updateTimestamp |
Timestamps | Yes |