diff --git a/src/main/java/run/halo/app/theme/dialect/DefaultFaviconHeadProcessor.java b/src/main/java/run/halo/app/theme/dialect/DefaultFaviconHeadProcessor.java new file mode 100644 index 000000000..d8986ea64 --- /dev/null +++ b/src/main/java/run/halo/app/theme/dialect/DefaultFaviconHeadProcessor.java @@ -0,0 +1,46 @@ +package run.halo.app.theme.dialect; + +import lombok.AllArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; +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.infra.SystemConfigurableEnvironmentFetcher; +import run.halo.app.infra.SystemSetting; + +/** + * Theme template head tag snippet injection processor for favicon. + * + * @author guqing + * @since 2.0.0 + */ +@Component +@AllArgsConstructor +public class DefaultFaviconHeadProcessor implements TemplateHeadProcessor { + + private final SystemConfigurableEnvironmentFetcher fetcher; + + @Override + public Mono process(ITemplateContext context, IModel model, + IElementModelStructureHandler structureHandler) { + return fetchBasicSetting() + .filter(basic -> StringUtils.isNotBlank(basic.getFavicon())) + .map(basic -> { + IModelFactory modelFactory = context.getModelFactory(); + model.add(modelFactory.createText(faviconSnippet(basic.getFavicon()))); + return model; + }) + .then(); + } + + private String faviconSnippet(String favicon) { + return String.format("\n", favicon); + } + + private Mono fetchBasicSetting() { + return fetcher.fetch(SystemSetting.Basic.GROUP, SystemSetting.Basic.class); + } +} diff --git a/src/test/java/run/halo/app/theme/dialect/HaloProcessorDialectTest.java b/src/test/java/run/halo/app/theme/dialect/HaloProcessorDialectTest.java index ee5960739..74c219dfc 100644 --- a/src/test/java/run/halo/app/theme/dialect/HaloProcessorDialectTest.java +++ b/src/test/java/run/halo/app/theme/dialect/HaloProcessorDialectTest.java @@ -69,6 +69,7 @@ class HaloProcessorDialectTest { Map map = new HashMap<>(); map.put("postTemplateHeadProcessor", new PostTemplateHeadProcessor(postFinder)); map.put("templateGlobalHeadProcessor", new TemplateGlobalHeadProcessor(fetcher)); + map.put("faviconHeadProcessor", new DefaultFaviconHeadProcessor(fetcher)); lenient().when(applicationContext.getBeansOfType(TemplateHeadProcessor.class)) .thenReturn(map); @@ -85,6 +86,11 @@ class HaloProcessorDialectTest { @Test void globalHeadAndFooterProcessors() { + SystemSetting.Basic basic = new SystemSetting.Basic(); + basic.setFavicon("favicon.ico"); + when(fetcher.fetch(eq(SystemSetting.Basic.GROUP), + eq(SystemSetting.Basic.class))).thenReturn(Mono.just(basic)); + Context context = getContext(); String result = templateEngine.process("index", context); @@ -95,6 +101,7 @@ class HaloProcessorDialectTest { Index +

index

@@ -124,6 +131,11 @@ class HaloProcessorDialectTest { .metadata(metadata).build(); when(postFinder.getByName(eq("fake-post"))).thenReturn(postVo); + SystemSetting.Basic basic = new SystemSetting.Basic(); + basic.setFavicon(null); + when(fetcher.fetch(eq(SystemSetting.Basic.GROUP), + eq(SystemSetting.Basic.class))).thenReturn(Mono.just(basic)); + String result = templateEngine.process("post", context); assertThat(result).isEqualTo("""