diff --git a/settings.gradle b/settings.gradle index ec477b15e51..99be5be8335 100644 --- a/settings.gradle +++ b/settings.gradle @@ -87,6 +87,7 @@ include "spring-boot-project:spring-boot-test" include "spring-boot-project:spring-boot-test-autoconfigure" include "spring-boot-project:spring-boot-test-integration-tests" include "spring-boot-project:spring-boot-testcontainers" +include "spring-boot-project:spring-boot-thymeleaf" include "spring-boot-project:spring-boot-tomcat" include "spring-boot-project:spring-boot-tools:spring-boot-antlib" include "spring-boot-project:spring-boot-tools:spring-boot-autoconfigure-processor" diff --git a/spring-boot-project/spring-boot-autoconfigure-all/build.gradle b/spring-boot-project/spring-boot-autoconfigure-all/build.gradle index a3d62c10c3a..ca814044a92 100644 --- a/spring-boot-project/spring-boot-autoconfigure-all/build.gradle +++ b/spring-boot-project/spring-boot-autoconfigure-all/build.gradle @@ -103,10 +103,8 @@ dependencies { optional("org.apiguardian:apiguardian-api") optional("org.eclipse.angus:angus-mail") optional("com.github.ben-manes.caffeine:caffeine") - optional("com.github.mxab.thymeleaf.extras:thymeleaf-extras-data-attribute") optional("com.sendgrid:sendgrid-java") optional("com.zaxxer:HikariCP") - optional("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect") optional("org.aspectj:aspectjweaver") optional("org.cache2k:cache2k-spring") optional("org.eclipse.jetty.ee10:jetty-ee10-webapp") @@ -204,9 +202,6 @@ dependencies { exclude group: "org.eclipse.jetty", module: "jetty-servlet" exclude group: "jakarta.mail", module: "jakarta.mail-api" } - optional("org.thymeleaf:thymeleaf") - optional("org.thymeleaf:thymeleaf-spring6") - optional("org.thymeleaf.extras:thymeleaf-extras-springsecurity6") optional("redis.clients:jedis") testImplementation(project(":spring-boot-project:spring-boot-freemarker")) @@ -215,6 +210,7 @@ dependencies { testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) testImplementation(project(":spring-boot-project:spring-boot-undertow")) testImplementation(project(":spring-boot-project:spring-boot-mustache")) + testImplementation(project(":spring-boot-project:spring-boot-thymeleaf")) testImplementation(testFixtures(project(":spring-boot-project:spring-boot"))) testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) testImplementation("ch.qos.logback:logback-classic") diff --git a/spring-boot-project/spring-boot-autoconfigure-all/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-autoconfigure-all/src/main/resources/META-INF/additional-spring-configuration-metadata.json index f54663d0582..96e2f0b4c67 100644 --- a/spring-boot-project/spring-boot-autoconfigure-all/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-autoconfigure-all/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -1257,33 +1257,6 @@ "level": "warning" } }, - { - "name": "spring.thymeleaf.prefix", - "defaultValue": "classpath:/templates/" - }, - { - "name": "spring.thymeleaf.reactive.media-types", - "defaultValue": [ - "text/html", - "application/xhtml+xml", - "application/xml", - "text/xml", - "application/rss+xml", - "application/atom+xml", - "application/javascript", - "application/ecmascript", - "text/javascript", - "text/ecmascript", - "application/json", - "text/css", - "text/plain", - "text/event-stream" - ] - }, - { - "name": "spring.thymeleaf.suffix", - "defaultValue": ".html" - }, { "name": "spring.webflux.hiddenmethod.filter.enabled", "type": "java.lang.Boolean", diff --git a/spring-boot-project/spring-boot-autoconfigure-all/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-autoconfigure-all/src/main/resources/META-INF/spring.factories index d3f25c52ee0..6dba5441877 100644 --- a/spring-boot-project/spring-boot-autoconfigure-all/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-autoconfigure-all/src/main/resources/META-INF/spring.factories @@ -8,7 +8,6 @@ org.springframework.boot.autoconfigure.data.redis.RedisUrlSyntaxFailureAnalyzer # Template Availability Providers org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\ -org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\ org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider # Depends on Database Initialization Detectors diff --git a/spring-boot-project/spring-boot-autoconfigure-all/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-autoconfigure-all/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 08ac2d4917e..231a5e9f4d5 100644 --- a/spring-boot-project/spring-boot-autoconfigure-all/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-boot-project/spring-boot-autoconfigure-all/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -70,7 +70,6 @@ org.springframework.boot.autoconfigure.security.oauth2.server.servlet.OAuth2Auth org.springframework.boot.autoconfigure.security.oauth2.server.servlet.OAuth2AuthorizationServerJwtAutoConfiguration org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration org.springframework.boot.autoconfigure.session.SessionAutoConfiguration -org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure-all/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure-all/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java index c73184dc2d6..6ea6d8d5ade 100644 --- a/spring-boot-project/spring-boot-autoconfigure-all/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure-all/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WelcomePageIntegrationTests.java @@ -22,11 +22,11 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.thymeleaf.autoconfigure.ThymeleafAutoConfiguration; import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 82daa4cd98e..3bbad27574c 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -2065,6 +2065,7 @@ bom { "spring-boot-test", "spring-boot-test-autoconfigure", "spring-boot-testcontainers", + "spring-boot-thymeleaf", "spring-boot-tomcat", "spring-boot-tx", "spring-boot-undertow", diff --git a/spring-boot-project/spring-boot-docs/build.gradle b/spring-boot-project/spring-boot-docs/build.gradle index e3e53c74539..a8b48d4a380 100644 --- a/spring-boot-project/spring-boot-docs/build.gradle +++ b/spring-boot-project/spring-boot-docs/build.gradle @@ -95,6 +95,7 @@ dependencies { autoConfiguration(project(path: ":spring-boot-project:spring-boot-reactor-netty", configuration: "autoConfigurationMetadata")) autoConfiguration(project(path: ":spring-boot-project:spring-boot-rsocket", configuration: "autoConfigurationMetadata")) autoConfiguration(project(path: ":spring-boot-project:spring-boot-testcontainers", configuration: "autoConfigurationMetadata")) + autoConfiguration(project(path: ":spring-boot-project:spring-boot-thymeleaf", configuration: "autoConfigurationMetadata")) autoConfiguration(project(path: ":spring-boot-project:spring-boot-tomcat", configuration: "autoConfigurationMetadata")) autoConfiguration(project(path: ":spring-boot-project:spring-boot-tx", configuration: "autoConfigurationMetadata")) autoConfiguration(project(path: ":spring-boot-project:spring-boot-undertow", configuration: "autoConfigurationMetadata")) @@ -139,6 +140,7 @@ dependencies { configurationProperties(project(path: ":spring-boot-project:spring-boot-rsocket", configuration: "configurationPropertiesMetadata")) configurationProperties(project(path: ":spring-boot-project:spring-boot-test-autoconfigure", configuration: "configurationPropertiesMetadata")) configurationProperties(project(path: ":spring-boot-project:spring-boot-testcontainers", configuration: "configurationPropertiesMetadata")) + configurationProperties(project(path: ":spring-boot-project:spring-boot-thymeleaf", configuration: "configurationPropertiesMetadata")) configurationProperties(project(path: ":spring-boot-project:spring-boot-tomcat", configuration: "configurationPropertiesMetadata")) configurationProperties(project(path: ":spring-boot-project:spring-boot-tx", configuration: "configurationPropertiesMetadata")) configurationProperties(project(path: ":spring-boot-project:spring-boot-undertow", configuration: "configurationPropertiesMetadata")) diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-thymeleaf/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-thymeleaf/build.gradle index efc231b011a..bad14a90196 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-thymeleaf/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-thymeleaf/build.gradle @@ -6,5 +6,5 @@ description = "Starter for building MVC web applications using Thymeleaf views" dependencies { api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.thymeleaf:thymeleaf-spring6") + api(project(":spring-boot-project:spring-boot-thymeleaf")) } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/build.gradle b/spring-boot-project/spring-boot-test-autoconfigure/build.gradle index c11aa154701..efb55f18545 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-test-autoconfigure/build.gradle @@ -105,6 +105,7 @@ dependencies { testImplementation(project(":spring-boot-project:spring-boot-freemarker")) testImplementation(project(":spring-boot-project:spring-boot-mustache")) testImplementation(project(":spring-boot-project:spring-boot-testcontainers")) + testImplementation(project(":spring-boot-project:spring-boot-thymeleaf")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) testImplementation("ch.qos.logback:logback-classic") testImplementation("com.fasterxml.jackson.module:jackson-module-parameter-names") diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux.imports index 16ca12b1aa2..bd4fd18122d 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebFlux.imports @@ -3,7 +3,7 @@ org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration optional:org.springframework.boot.freemarker.autoconfigure.FreeMarkerAutoConfiguration org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration optional:org.springframework.boot.mustache.autoconfigure.MustacheAutoConfiguration -org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration +optional:org.springframework.boot.thymeleaf.autoconfigure.ThymeleafAutoConfiguration optional:org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc.imports b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc.imports index 5eaaaf56517..266e3acd29d 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc.imports +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc.imports @@ -6,7 +6,7 @@ org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration optional:org.springframework.boot.mustache.autoconfigure.MustacheAutoConfiguration org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration -org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration +optional:org.springframework.boot.thymeleaf.autoconfigure.ThymeleafAutoConfiguration optional:org.springframework.boot.groovy.template.autoconfigure.GroovyTemplateAutoConfiguration optional:org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/WebFluxTestAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/WebFluxTestAutoConfigurationIntegrationTests.java index 654430f0030..fb06e8b45fd 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/WebFluxTestAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/reactive/webclient/WebFluxTestAutoConfigurationIntegrationTests.java @@ -22,11 +22,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration; import org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration; import org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration; -import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration; import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration; import org.springframework.boot.freemarker.autoconfigure.FreeMarkerAutoConfiguration; import org.springframework.boot.mustache.autoconfigure.MustacheAutoConfiguration; import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.thymeleaf.autoconfigure.ThymeleafAutoConfiguration; import org.springframework.boot.validation.autoconfigure.ValidationAutoConfiguration; import org.springframework.context.ApplicationContext; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestAutoConfigurationIntegrationTests.java index 17194167242..78dc6236124 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestAutoConfigurationIntegrationTests.java @@ -22,11 +22,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration; import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; -import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration; import org.springframework.boot.freemarker.autoconfigure.FreeMarkerAutoConfiguration; import org.springframework.boot.groovy.template.autoconfigure.GroovyTemplateAutoConfiguration; import org.springframework.boot.mustache.autoconfigure.MustacheAutoConfiguration; +import org.springframework.boot.thymeleaf.autoconfigure.ThymeleafAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; diff --git a/spring-boot-project/spring-boot-thymeleaf/build.gradle b/spring-boot-project/spring-boot-thymeleaf/build.gradle new file mode 100644 index 00000000000..3ca64471493 --- /dev/null +++ b/spring-boot-project/spring-boot-thymeleaf/build.gradle @@ -0,0 +1,30 @@ +plugins { + id "java-library" + id "org.springframework.boot.auto-configuration" + id "org.springframework.boot.configuration-properties" + id "org.springframework.boot.deployed" + id "org.springframework.boot.optional-dependencies" +} + +description = "Spring Boot Thymeleaf" + +dependencies { + api(project(":spring-boot-project:spring-boot")) + api("org.thymeleaf:thymeleaf-spring6") + api("org.springframework:spring-web") + + optional(project(":spring-boot-project:spring-boot-autoconfigure")) + optional("org.springframework.security:spring-security-web") + optional("org.springframework:spring-webmvc") + optional("org.springframework:spring-webflux") + optional("org.thymeleaf:thymeleaf") + optional("org.thymeleaf.extras:thymeleaf-extras-springsecurity6") + optional("com.github.mxab.thymeleaf.extras:thymeleaf-extras-data-attribute") + optional("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect") + optional("jakarta.servlet:jakarta.servlet-api") + + testImplementation(project(":spring-boot-project:spring-boot-test")) + testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + + testRuntimeOnly("ch.qos.logback:logback-classic") +} diff --git a/spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/TemplateEngineConfigurations.java b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/TemplateEngineConfigurations.java similarity index 98% rename from spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/TemplateEngineConfigurations.java rename to spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/TemplateEngineConfigurations.java index 23de094eb33..d952c47281c 100644 --- a/spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/TemplateEngineConfigurations.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/TemplateEngineConfigurations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; import org.thymeleaf.ITemplateEngine; import org.thymeleaf.dialect.IDialect; diff --git a/spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafAutoConfiguration.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java rename to spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafAutoConfiguration.java index 92b6806392e..680d9e11132 100644 --- a/spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; import java.util.LinkedHashMap; @@ -40,12 +40,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingFilt import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.autoconfigure.template.TemplateLocation; -import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafProperties.Reactive; import org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.boot.thymeleaf.autoconfigure.ThymeleafProperties.Reactive; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; @@ -69,9 +67,10 @@ import org.springframework.web.servlet.view.AbstractCachingViewResolver; * @author Daniel Fernández * @author Kazuki Shimizu * @author Artsiom Yudovin - * @since 1.0.0 + * @since 4.0.0 */ -@AutoConfiguration(after = { WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class }) +@AutoConfiguration(afterName = { "org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration", + "org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration" }) @EnableConfigurationProperties(ThymeleafProperties.class) @ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class }) @Import({ TemplateEngineConfigurations.ReactiveTemplateEngineConfiguration.class, diff --git a/spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafProperties.java b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafProperties.java similarity index 99% rename from spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafProperties.java rename to spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafProperties.java index 277d9e9345c..3f6a86c2e37 100644 --- a/spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafProperties.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -32,7 +32,7 @@ import org.springframework.util.unit.DataSize; * @author Brian Clozel * @author Daniel Fernández * @author Kazuki Shimizu - * @since 1.2.0 + * @since 4.0.0 */ @ConfigurationProperties("spring.thymeleaf") public class ThymeleafProperties { diff --git a/spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafTemplateAvailabilityProvider.java b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafTemplateAvailabilityProvider.java similarity index 92% rename from spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafTemplateAvailabilityProvider.java rename to spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafTemplateAvailabilityProvider.java index d1906b67d41..6f59ae7529c 100644 --- a/spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafTemplateAvailabilityProvider.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafTemplateAvailabilityProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider; import org.springframework.core.env.Environment; @@ -27,7 +27,7 @@ import org.springframework.util.ClassUtils; * * @author Andy Wilkinson * @author Madhura Bhave - * @since 1.1.0 + * @since 4.0.0 */ public class ThymeleafTemplateAvailabilityProvider implements TemplateAvailabilityProvider { diff --git a/spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/package-info.java b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/package-info.java similarity index 84% rename from spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/package-info.java rename to spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/package-info.java index a31b16b82e3..68ef2bef563 100644 --- a/spring-boot-project/spring-boot-autoconfigure-all/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/package-info.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/java/org/springframework/boot/thymeleaf/autoconfigure/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,4 +17,4 @@ /** * Auto-configuration for Thymeleaf. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; diff --git a/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 00000000000..a252e02be27 --- /dev/null +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,37 @@ +{ + "groups": [], + "properties": [ + { + "name": "spring.thymeleaf.prefix", + "defaultValue": "classpath:/templates/" + }, + { + "name": "spring.thymeleaf.reactive.media-types", + "defaultValue": [ + "text/html", + "application/xhtml+xml", + "application/xml", + "text/xml", + "application/rss+xml", + "application/atom+xml", + "application/javascript", + "application/ecmascript", + "text/javascript", + "text/ecmascript", + "application/json", + "text/css", + "text/plain", + "text/event-stream" + ] + }, + { + "name": "spring.thymeleaf.suffix", + "defaultValue": ".html" + } + ], + "hints": [], + "ignored": { + "properties": [ + ] + } +} diff --git a/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000000..a0365b1889d --- /dev/null +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Template Availability Providers +org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\ +org.springframework.boot.thymeleaf.autoconfigure.ThymeleafTemplateAvailabilityProvider diff --git a/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000000..e1faae4a813 --- /dev/null +++ b/spring-boot-project/spring-boot-thymeleaf/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springframework.boot.thymeleaf.autoconfigure.ThymeleafAutoConfiguration diff --git a/spring-boot-project/spring-boot-autoconfigure-all/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java b/spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafReactiveAutoConfigurationTests.java similarity index 88% rename from spring-boot-project/spring-boot-autoconfigure-all/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java rename to spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafReactiveAutoConfigurationTests.java index dcc16694ea4..173436ee101 100644 --- a/spring-boot-project/spring-boot-autoconfigure-all/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafReactiveAutoConfigurationTests.java @@ -14,17 +14,21 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; -import java.io.File; +import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Collections; import java.util.Locale; import nz.net.ultraq.thymeleaf.layoutdialect.LayoutDialect; import nz.net.ultraq.thymeleaf.layoutdialect.decorators.strategies.GroupingStrategy; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.TempDir; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import org.thymeleaf.context.WebContext; @@ -42,7 +46,6 @@ import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.testsupport.BuildOutput; import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -61,12 +64,11 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Brian Clozel * @author Kazuki Shimizu * @author Stephane Nicoll + * @author Moritz Halbritter */ @ExtendWith(OutputCaptureExtension.class) class ThymeleafReactiveAutoConfigurationTests { - private final BuildOutput buildOutput = new BuildOutput(getClass()); - private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() .withConfiguration(AutoConfigurations.of(ThymeleafAutoConfiguration.class)); @@ -88,26 +90,27 @@ class ThymeleafReactiveAutoConfigurationTests { assertThat(resolver).isInstanceOf(SpringResourceTemplateResolver.class); assertThat(((SpringResourceTemplateResolver) resolver).getCharacterEncoding()).isEqualTo("UTF-16"); ThymeleafReactiveViewResolver views = context.getBean(ThymeleafReactiveViewResolver.class); - assertThat(views.getDefaultCharset().name()).isEqualTo("UTF-16"); + Assertions.assertThat(views.getDefaultCharset().name()).isEqualTo("UTF-16"); }); } @Test void defaultMediaTypes() { - this.contextRunner - .run((context) -> assertThat(context.getBean(ThymeleafReactiveViewResolver.class).getSupportedMediaTypes()) - .containsExactly(MediaType.TEXT_HTML, MediaType.APPLICATION_XHTML_XML, MediaType.APPLICATION_XML, - MediaType.TEXT_XML, MediaType.APPLICATION_RSS_XML, MediaType.APPLICATION_ATOM_XML, - new MediaType("application", "javascript"), new MediaType("application", "ecmascript"), - new MediaType("text", "javascript"), new MediaType("text", "ecmascript"), - MediaType.APPLICATION_JSON, new MediaType("text", "css"), MediaType.TEXT_PLAIN, - MediaType.TEXT_EVENT_STREAM)); + this.contextRunner.run((context) -> Assertions + .assertThat(context.getBean(ThymeleafReactiveViewResolver.class).getSupportedMediaTypes()) + .containsExactly(MediaType.TEXT_HTML, MediaType.APPLICATION_XHTML_XML, MediaType.APPLICATION_XML, + MediaType.TEXT_XML, MediaType.APPLICATION_RSS_XML, MediaType.APPLICATION_ATOM_XML, + new MediaType("application", "javascript"), new MediaType("application", "ecmascript"), + new MediaType("text", "javascript"), new MediaType("text", "ecmascript"), + MediaType.APPLICATION_JSON, new MediaType("text", "css"), MediaType.TEXT_PLAIN, + MediaType.TEXT_EVENT_STREAM)); } @Test void overrideMediaTypes() { this.contextRunner.withPropertyValues("spring.thymeleaf.reactive.media-types:text/html,text/plain") - .run((context) -> assertThat(context.getBean(ThymeleafReactiveViewResolver.class).getSupportedMediaTypes()) + .run((context) -> Assertions + .assertThat(context.getBean(ThymeleafReactiveViewResolver.class).getSupportedMediaTypes()) .containsExactly(MediaType.TEXT_HTML, MediaType.TEXT_PLAIN)); } @@ -183,9 +186,10 @@ class ThymeleafReactiveAutoConfigurationTests { } @Test - void templateLocationEmpty(CapturedOutput output) { - new File(this.buildOutput.getTestResourcesLocation(), "empty-templates/empty-directory").mkdirs(); - this.contextRunner.withPropertyValues("spring.thymeleaf.prefix:classpath:/empty-templates/empty-directory/") + void templateLocationEmpty(CapturedOutput output, @TempDir Path tempDir) throws IOException { + Path directory = tempDir.resolve("empty-templates/empty-directory").toAbsolutePath(); + Files.createDirectories(directory); + this.contextRunner.withPropertyValues("spring.thymeleaf.prefix:file:" + directory) .run((context) -> assertThat(output).doesNotContain("Cannot find template location")); } diff --git a/spring-boot-project/spring-boot-autoconfigure-all/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafServletAutoConfigurationTests.java b/spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafServletAutoConfigurationTests.java similarity index 96% rename from spring-boot-project/spring-boot-autoconfigure-all/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafServletAutoConfigurationTests.java rename to spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafServletAutoConfigurationTests.java index 03fc003dc8b..3abfa39cf37 100644 --- a/spring-boot-project/spring-boot-autoconfigure-all/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafServletAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafServletAutoConfigurationTests.java @@ -14,9 +14,11 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; -import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Collections; import java.util.EnumSet; import java.util.Locale; @@ -26,8 +28,10 @@ import jakarta.servlet.DispatcherType; import jakarta.servlet.ServletContext; import nz.net.ultraq.thymeleaf.layoutdialect.LayoutDialect; import nz.net.ultraq.thymeleaf.layoutdialect.decorators.strategies.GroupingStrategy; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.TempDir; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import org.thymeleaf.context.WebContext; @@ -45,7 +49,6 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.testsupport.BuildOutput; import org.springframework.boot.testsupport.classpath.resources.WithResource; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter; @@ -74,12 +77,11 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Brian Clozel * @author Kazuki Shimizu * @author Artsiom Yudovin + * @author Moritz Halbritter */ @ExtendWith(OutputCaptureExtension.class) class ThymeleafServletAutoConfigurationTests { - private final BuildOutput buildOutput = new BuildOutput(getClass()); - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() .withConfiguration(AutoConfigurations.of(ThymeleafAutoConfiguration.class)); @@ -179,9 +181,10 @@ class ThymeleafServletAutoConfigurationTests { } @Test - void templateLocationEmpty(CapturedOutput output) { - new File(this.buildOutput.getTestResourcesLocation(), "empty-templates/empty-directory").mkdirs(); - this.contextRunner.withPropertyValues("spring.thymeleaf.prefix:classpath:/empty-templates/empty-directory/") + void templateLocationEmpty(CapturedOutput output, @TempDir Path tempDir) throws IOException { + Path directory = tempDir.resolve("empty-templates/empty-directory").toAbsolutePath(); + Files.createDirectories(directory); + this.contextRunner.withPropertyValues("spring.thymeleaf.prefix:file:" + directory) .run((context) -> assertThat(output).doesNotContain("Cannot find template location")); } @@ -354,7 +357,7 @@ class ThymeleafServletAutoConfigurationTests { @Test void cachingCanBeDisabled() { this.contextRunner.withPropertyValues("spring.thymeleaf.cache:false").run((context) -> { - assertThat(context.getBean(ThymeleafViewResolver.class).isCache()).isFalse(); + Assertions.assertThat(context.getBean(ThymeleafViewResolver.class).isCache()).isFalse(); SpringResourceTemplateResolver templateResolver = context.getBean(SpringResourceTemplateResolver.class); assertThat(templateResolver.isCacheable()).isFalse(); }); diff --git a/spring-boot-project/spring-boot-autoconfigure-all/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafTemplateAvailabilityProviderTests.java b/spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafTemplateAvailabilityProviderTests.java similarity index 97% rename from spring-boot-project/spring-boot-autoconfigure-all/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafTemplateAvailabilityProviderTests.java rename to spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafTemplateAvailabilityProviderTests.java index 406dc9b104c..567f4bd6d34 100644 --- a/spring-boot-project/spring-boot-autoconfigure-all/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafTemplateAvailabilityProviderTests.java +++ b/spring-boot-project/spring-boot-thymeleaf/src/test/java/org/springframework/boot/thymeleaf/autoconfigure/ThymeleafTemplateAvailabilityProviderTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.autoconfigure.thymeleaf; +package org.springframework.boot.thymeleaf.autoconfigure; import org.junit.jupiter.api.Test;