diff --git a/src/main/java/run/halo/app/theme/dialect/GlobalHeadInjectionProcessor.java b/src/main/java/run/halo/app/theme/dialect/GlobalHeadInjectionProcessor.java index 2b6e16427..4016ef983 100644 --- a/src/main/java/run/halo/app/theme/dialect/GlobalHeadInjectionProcessor.java +++ b/src/main/java/run/halo/app/theme/dialect/GlobalHeadInjectionProcessor.java @@ -9,6 +9,7 @@ import org.thymeleaf.processor.element.AbstractElementModelProcessor; import org.thymeleaf.processor.element.IElementModelStructureHandler; import org.thymeleaf.spring6.context.SpringContextUtils; import org.thymeleaf.templatemode.TemplateMode; +import run.halo.app.plugin.ExtensionComponentsFinder; /** * Global head injection processor. @@ -50,10 +51,6 @@ public class GlobalHeadInjectionProcessor extends AbstractElementModelProcessor structureHandler.setLocalVariable(PROCESS_FLAG, true); // handle tag - /* - * Obtain the Spring application context. - */ - final ApplicationContext appCtx = SpringContextUtils.getApplicationContext(context); /* * Create the DOM structure that will be substituting our custom tag. @@ -65,7 +62,8 @@ public class GlobalHeadInjectionProcessor extends AbstractElementModelProcessor // apply processors to modelToInsert Collection templateHeadProcessors = - getTemplateHeadProcessors(appCtx); + getTemplateHeadProcessors(context); + for (TemplateHeadProcessor processor : templateHeadProcessors) { processor.process(context, modelToInsert, structureHandler) .block(); @@ -75,8 +73,10 @@ public class GlobalHeadInjectionProcessor extends AbstractElementModelProcessor model.insertModel(model.size() - 1, modelToInsert); } - private Collection getTemplateHeadProcessors(ApplicationContext ctx) { - return ctx.getBeansOfType(TemplateHeadProcessor.class) - .values(); + private Collection getTemplateHeadProcessors(ITemplateContext context) { + ApplicationContext appCtx = SpringContextUtils.getApplicationContext(context); + ExtensionComponentsFinder componentsFinder = + appCtx.getBean(ExtensionComponentsFinder.class); + return componentsFinder.getExtensions(TemplateHeadProcessor.class); } } diff --git a/src/main/java/run/halo/app/theme/dialect/TemplateHeadProcessor.java b/src/main/java/run/halo/app/theme/dialect/TemplateHeadProcessor.java index 6f8312561..7a167176a 100644 --- a/src/main/java/run/halo/app/theme/dialect/TemplateHeadProcessor.java +++ b/src/main/java/run/halo/app/theme/dialect/TemplateHeadProcessor.java @@ -1,5 +1,6 @@ package run.halo.app.theme.dialect; +import org.pf4j.ExtensionPoint; import org.thymeleaf.context.ITemplateContext; import org.thymeleaf.model.IModel; import org.thymeleaf.processor.element.IElementModelStructureHandler; @@ -12,7 +13,7 @@ import reactor.core.publisher.Mono; * @since 2.0.0 */ @FunctionalInterface -public interface TemplateHeadProcessor { +public interface TemplateHeadProcessor extends ExtensionPoint { Mono process(ITemplateContext context, IModel model, IElementModelStructureHandler structureHandler); 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 74c219dfc..3b858bedb 100644 --- a/src/test/java/run/halo/app/theme/dialect/HaloProcessorDialectTest.java +++ b/src/test/java/run/halo/app/theme/dialect/HaloProcessorDialectTest.java @@ -30,6 +30,7 @@ import run.halo.app.core.extension.Post; import run.halo.app.extension.Metadata; import run.halo.app.infra.SystemConfigurableEnvironmentFetcher; import run.halo.app.infra.SystemSetting; +import run.halo.app.plugin.ExtensionComponentsFinder; import run.halo.app.theme.DefaultTemplateEnum; import run.halo.app.theme.finders.PostFinder; import run.halo.app.theme.finders.vo.PostVo; @@ -57,6 +58,9 @@ class HaloProcessorDialectTest { @Mock private SystemConfigurableEnvironmentFetcher fetcher; + @Mock + private ExtensionComponentsFinder extensionComponentsFinder; + private TemplateEngine templateEngine; @BeforeEach @@ -70,7 +74,7 @@ class HaloProcessorDialectTest { map.put("postTemplateHeadProcessor", new PostTemplateHeadProcessor(postFinder)); map.put("templateGlobalHeadProcessor", new TemplateGlobalHeadProcessor(fetcher)); map.put("faviconHeadProcessor", new DefaultFaviconHeadProcessor(fetcher)); - lenient().when(applicationContext.getBeansOfType(TemplateHeadProcessor.class)) + lenient().when(applicationContext.getBeansOfType(eq(TemplateHeadProcessor.class))) .thenReturn(map); SystemSetting.CodeInjection codeInjection = new SystemSetting.CodeInjection(); @@ -80,8 +84,14 @@ class HaloProcessorDialectTest { when(fetcher.fetch(eq(SystemSetting.CodeInjection.GROUP), eq(SystemSetting.CodeInjection.class))).thenReturn(Mono.just(codeInjection)); - when(applicationContext.getBean(SystemConfigurableEnvironmentFetcher.class)) + when(applicationContext.getBean(eq(SystemConfigurableEnvironmentFetcher.class))) .thenReturn(fetcher); + + when(applicationContext.getBean(eq(ExtensionComponentsFinder.class))) + .thenReturn(extensionComponentsFinder); + + when(extensionComponentsFinder.getExtensions(eq(TemplateHeadProcessor.class))) + .thenReturn(new ArrayList<>(map.values())); } @Test