1.7.1原版

This commit is contained in:
2026-07-18 15:20:48 +08:00
commit 8b7190ae69
53 changed files with 7962 additions and 0 deletions
@@ -0,0 +1,59 @@
package run.halo.search.widget;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.*;
import reactor.core.publisher.Mono;
import run.halo.app.search.SearchOption;
import run.halo.app.search.SearchResult;
import run.halo.app.search.SearchService;
import java.util.List;
import java.util.Map;
@Component
public class SearchView {
private final SearchService searchService;
public SearchView(SearchService searchService) {
this.searchService = searchService;
}
@Bean
RouterFunction<ServerResponse> searchView() {
return RouterFunctions.route()
.GET("/search", RequestPredicates.accept(MediaType.TEXT_HTML), this::performSearch)
.build();
}
private Mono<ServerResponse> performSearch(ServerRequest serverRequest) {
int limit = serverRequest.queryParam("limit")
.map(Integer::parseInt)
.orElse(10);
var keyword = serverRequest.queryParam("keyword").orElse("");
Mono<SearchResult> result;
if (keyword.isBlank()) {
var searchResult = new SearchResult();
searchResult.setTotal(0L);
searchResult.setLimit(limit);
searchResult.setProcessingTimeMillis(0);
searchResult.setHits(List.of());
result = Mono.just(searchResult);
} else {
var includeTypes = serverRequest.queryParams().get("includeTypes");
var option = new SearchOption();
option.setKeyword(keyword);
option.setLimit(limit);
option.setFilterExposed(true);
option.setFilterPublished(true);
option.setFilterRecycled(false);
option.setIncludeTypes(includeTypes);
result = searchService.search(option);
}
return ServerResponse.ok().render("search", Map.of(
"searchResult", result
));
}
}
@@ -0,0 +1,43 @@
package run.halo.search.widget;
import java.util.Properties;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.util.PropertyPlaceholderHelper;
import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.model.IModel;
import org.thymeleaf.model.IModelFactory;
import org.thymeleaf.processor.element.IElementModelStructureHandler;
import reactor.core.publisher.Mono;
import run.halo.app.plugin.PluginContext;
import run.halo.app.theme.dialect.TemplateHeadProcessor;
@Component
@RequiredArgsConstructor
public class SearchWidgetHeadProcessor implements TemplateHeadProcessor {
static final PropertyPlaceholderHelper PROPERTY_PLACEHOLDER_HELPER = new PropertyPlaceholderHelper("${", "}");
private final PluginContext pluginContext;
@Override
public Mono<Void> process(ITemplateContext context, IModel model,
IElementModelStructureHandler structureHandler) {
final IModelFactory modelFactory = context.getModelFactory();
model.add(modelFactory.createText(searchWidgetScript()));
return Mono.empty();
}
private String searchWidgetScript() {
final Properties properties = new Properties();
properties.setProperty("version", pluginContext.getVersion());
return PROPERTY_PLACEHOLDER_HELPER.replacePlaceholders("""
<!-- PluginSearchWidget start -->
<script src="/plugins/PluginSearchWidget/assets/static/search-widget.iife.js?version=${version}" defer></script>
<link rel="stylesheet" href="/plugins/PluginSearchWidget/assets/static/style.css?version=${version}" />
<!-- PluginSearchWidget end -->
""", properties);
}
}
@@ -0,0 +1,24 @@
package run.halo.search.widget;
import org.springframework.stereotype.Component;
import run.halo.app.plugin.BasePlugin;
import run.halo.app.plugin.PluginContext;
/**
* @author ryanwang
*/
@Component
public class SearchWidgetPlugin extends BasePlugin {
public SearchWidgetPlugin(PluginContext pluginContext) {
super(pluginContext);
}
@Override
public void start() {
}
@Override
public void stop() {
}
}
@@ -0,0 +1,8 @@
apiVersion: plugin.halo.run/v1alpha1
kind: ReverseProxy
metadata:
name: reverse-proxy-template
rules:
- path: /static/**
file:
directory: static
+1
View File
@@ -0,0 +1 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class=""><rect id="r4" width="512" height="512" x="0" y="0" rx="0" fill="url(#r5)" stroke="#FFFFFF" stroke-width="0" stroke-opacity="100%" paint-order="stroke"></rect><clipPath id="clip"><use xlink:href="#r4"></use></clipPath><defs><linearGradient id="r5" gradientUnits="userSpaceOnUse" gradientTransform="rotate(45)" style="transform-origin: center center;"><stop stop-color="#91EAE4"></stop><stop offset="1" stop-color="#7F7FD5"></stop></linearGradient><radialGradient id="r6" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(256) rotate(90) scale(512)"><stop stop-color="white"></stop><stop offset="1" stop-color="white" stop-opacity="0"></stop></radialGradient></defs><svg xmlns="http://www.w3.org/2000/svg" width="352" height="352" viewBox="0 0 24 24" x="80" y="80" alignment-baseline="middle" style="color: rgb(255, 255, 255);"><path fill="currentColor" d="M11 2c4.968 0 9 4.032 9 9s-4.032 9-9 9s-9-4.032-9-9s4.032-9 9-9Zm0 16c3.867 0 7-3.133 7-7s-3.133-7-7-7s-7 3.133-7 7s3.133 7 7 7Zm8.485.071l2.829 2.828l-1.415 1.415l-2.828-2.829l1.414-1.414Z"></path></svg></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+23
View File
@@ -0,0 +1,23 @@
apiVersion: plugin.halo.run/v1alpha1
kind: Plugin
metadata:
name: PluginSearchWidget
annotations:
# Add supports for Halo App Store
# https://halo.run/store/apps/app-DlacW
"store.halo.run/app-id": "app-DlacW"
spec:
enabled: true
requires: ">=2.17.0"
author:
name: Halo
website: https://github.com/halo-dev
logo: logo.svg
homepage: https://www.halo.run/store/apps/app-DlacW
repo: https://github.com/halo-dev/plugin-search-widget
issues: https://github.com/halo-dev/plugin-search-widget/issues
displayName: "搜索组件"
description: "为 Halo 2.0 提供统一的搜索组件,方便主题端使用。"
license:
- name: "GPL-3.0"
url: "https://github.com/halo-dev/plugin-search-widget/blob/main/LICENSE"