From 7327e09d2a5cb4dcb631d639147262a7aa82c416 Mon Sep 17 00:00:00 2001 From: Developer Date: Wed, 15 Apr 2026 10:04:38 +0800 Subject: [PATCH] fix: resolve issue #47 - Thymeleaf 3.1.4+ bean reference restriction - Add cssColors model attribute to UiController with pre-computed RGB values - Update variables.css template to use cssColors instead of @cssColorUtils bean reference - Add SpringStandardDialect bean configuration for compatibility This fixes the TemplateProcessingException caused by Thymeleaf 3.1.4.RELEASE which forbids bean references (@cssColorUtils) in CSS templates. --- .../src/main/frontend/public/variables.css | 24 +++++++++---------- .../AdminServerUiAutoConfiguration.java | 8 +++++++ .../admin/server/ui/web/UiController.java | 23 +++++++++++++++++- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/spring-boot-admin-server-ui/src/main/frontend/public/variables.css b/spring-boot-admin-server-ui/src/main/frontend/public/variables.css index 7af08003e3d..f4f4df81821 100644 --- a/spring-boot-admin-server-ui/src/main/frontend/public/variables.css +++ b/spring-boot-admin-server-ui/src/main/frontend/public/variables.css @@ -1,17 +1,17 @@ :root { - --main-50: /*[(${@cssColorUtils.hexToRgb(uiSettings.theme.palette.getShade50())})]*/ #e8fbef; - --main-100: /*[(${@cssColorUtils.hexToRgb(uiSettings.theme.palette.getShade100())})]*/ #d0f7df; - --main-200: /*[(${@cssColorUtils.hexToRgb(uiSettings.theme.palette.getShade200())})]*/ #a1efbd; - --main-300: /*[(${@cssColorUtils.hexToRgb(uiSettings.theme.palette.getShade300())})]*/ #71e69c; - --main-400: /*[(${@cssColorUtils.hexToRgb(uiSettings.theme.palette.getShade400())})]*/ #41de7b; - --main-500: /*[(${@cssColorUtils.hexToRgb(uiSettings.theme.palette.getShade500())})]*/ #22c55e; - --main-600: /*[(${@cssColorUtils.hexToRgb(uiSettings.theme.palette.getShade600())})]*/ #1a9547; - --main-700: /*[(${@cssColorUtils.hexToRgb(uiSettings.theme.palette.getShade700())})]*/ #116530; - --main-800: /*[(${@cssColorUtils.hexToRgb(uiSettings.theme.palette.getShade800())})]*/ #09351a; - --main-900: /*[(${@cssColorUtils.hexToRgb(uiSettings.theme.palette.getShade900())})]*/ #010603; + --main-50: /*[(${cssColors.shade50Rgb})]*/ #e8fbef; + --main-100: /*[(${cssColors.shade100Rgb})]*/ #d0f7df; + --main-200: /*[(${cssColors.shade200Rgb})]*/ #a1efbd; + --main-300: /*[(${cssColors.shade300Rgb})]*/ #71e69c; + --main-400: /*[(${cssColors.shade400Rgb})]*/ #41de7b; + --main-500: /*[(${cssColors.shade500Rgb})]*/ #22c55e; + --main-600: /*[(${cssColors.shade600Rgb})]*/ #1a9547; + --main-700: /*[(${cssColors.shade700Rgb})]*/ #116530; + --main-800: /*[(${cssColors.shade800Rgb})]*/ #09351a; + --main-900: /*[(${cssColors.shade900Rgb})]*/ #010603; - --bg-color-start: /*[(${uiSettings.theme.palette.getShade300()})]*/ #71e69c; - --bg-color-stop: /*[(${uiSettings.theme.palette.getShade700()})]*/ #09351a; + --bg-color-start: /*[(${uiSettings.theme.palette.shade300})]*/ #71e69c; + --bg-color-stop: /*[(${uiSettings.theme.palette.shade700})]*/ #09351a; } .bg-color-start { diff --git a/spring-boot-admin-server-ui/src/main/java/de/codecentric/boot/admin/server/ui/config/AdminServerUiAutoConfiguration.java b/spring-boot-admin-server-ui/src/main/java/de/codecentric/boot/admin/server/ui/config/AdminServerUiAutoConfiguration.java index c71a20e3f55..0bc6265ef83 100644 --- a/spring-boot-admin-server-ui/src/main/java/de/codecentric/boot/admin/server/ui/config/AdminServerUiAutoConfiguration.java +++ b/spring-boot-admin-server-ui/src/main/java/de/codecentric/boot/admin/server/ui/config/AdminServerUiAutoConfiguration.java @@ -38,6 +38,7 @@ import org.springframework.http.MediaType; import org.springframework.web.reactive.config.WebFluxConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.thymeleaf.spring6.dialect.SpringStandardDialect; import org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver; import org.thymeleaf.templatemode.TemplateMode; @@ -95,6 +96,13 @@ public CssColorUtils cssColorUtils() { return new CssColorUtils(); } + @Bean + public SpringStandardDialect springStandardDialect() { + SpringStandardDialect dialect = new SpringStandardDialect(); + dialect.setEnableSpringELCompiler(true); + return dialect; + } + @Bean @ConditionalOnMissingBean public UiController homeUiController(UiExtensions uiExtensions) throws IOException { diff --git a/spring-boot-admin-server-ui/src/main/java/de/codecentric/boot/admin/server/ui/web/UiController.java b/spring-boot-admin-server-ui/src/main/java/de/codecentric/boot/admin/server/ui/web/UiController.java index de409ec6306..3dcc7665e8a 100644 --- a/spring-boot-admin-server-ui/src/main/java/de/codecentric/boot/admin/server/ui/web/UiController.java +++ b/spring-boot-admin-server-ui/src/main/java/de/codecentric/boot/admin/server/ui/web/UiController.java @@ -33,6 +33,7 @@ import de.codecentric.boot.admin.server.ui.config.AdminServerUiProperties.PollTimer; import de.codecentric.boot.admin.server.ui.config.AdminServerUiProperties.UiTheme; +import de.codecentric.boot.admin.server.ui.config.CssColorUtils; import de.codecentric.boot.admin.server.ui.extensions.UiExtension; import de.codecentric.boot.admin.server.ui.extensions.UiExtensions; import de.codecentric.boot.admin.server.web.AdminController; @@ -50,10 +51,13 @@ public class UiController { private final Settings uiSettings; - public UiController(String publicUrl, UiExtensions uiExtensions, Settings uiSettings) { + private final CssColorUtils cssColorUtils; + + public UiController(String publicUrl, UiExtensions uiExtensions, Settings uiSettings, CssColorUtils cssColorUtils) { this.publicUrl = publicUrl; this.uiExtensions = uiExtensions; this.uiSettings = uiSettings; + this.cssColorUtils = cssColorUtils; } @ModelAttribute(value = "baseUrl", binding = false) @@ -97,6 +101,23 @@ public Map getUser(@Nullable Principal principal) { return emptyMap(); } + @ModelAttribute(value = "cssColors", binding = false) + public Map getCssColors() { + var palette = uiSettings.getTheme().getPalette(); + return Map.of( + "shade50Rgb", cssColorUtils.hexToRgb(palette.getShade50()), + "shade100Rgb", cssColorUtils.hexToRgb(palette.getShade100()), + "shade200Rgb", cssColorUtils.hexToRgb(palette.getShade200()), + "shade300Rgb", cssColorUtils.hexToRgb(palette.getShade300()), + "shade400Rgb", cssColorUtils.hexToRgb(palette.getShade400()), + "shade500Rgb", cssColorUtils.hexToRgb(palette.getShade500()), + "shade600Rgb", cssColorUtils.hexToRgb(palette.getShade600()), + "shade700Rgb", cssColorUtils.hexToRgb(palette.getShade700()), + "shade800Rgb", cssColorUtils.hexToRgb(palette.getShade800()), + "shade900Rgb", cssColorUtils.hexToRgb(palette.getShade900()) + ); + } + @GetMapping(path = "/", produces = MediaType.TEXT_HTML_VALUE) @RegisterReflectionForBinding(String.class) public String index() {