From 8c9d6f7b66ee64ce71a1873895d96f2e55c1bc4c Mon Sep 17 00:00:00 2001 From: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> Date: Sat, 27 Apr 2024 11:03:57 +0100 Subject: [PATCH] Custom HTML support #355 (#1129) * test * settings * version --- README.md | 3 +- build.gradle | 2 +- .../software/SPDF/config/AppConfig.java | 16 +++++++ .../config/FileFallbackTemplateResolver.java | 48 +++++++++++++++++++ .../SPDF/model/ApplicationProperties.java | 9 ++++ src/main/resources/settings.yml.template | 3 +- 6 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 src/main/java/stirling/software/SPDF/config/FileFallbackTemplateResolver.java diff --git a/README.md b/README.md index 3e22e201..a9d871df 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ Stirling PDF allows easy customization of the app. Includes things like - Custom application name -- Custom slogans, icons, images css etc (via file overrides) (Does not currently support html) +- Custom slogans, icons, HTML, images CSS etc (via file overrides) There are two options for this, either using the generated settings file ``settings.yml`` This file is located in the ``/configs`` directory and follows standard YAML formatting @@ -229,6 +229,7 @@ system: customStaticFilePath: '/customFiles/static/' # Directory path for custom static files showUpdate: true # see when a new update is available showUpdateOnlyAdmin: false # Only admins can see when a new update is available, depending on showUpdate it must be set to 'true' + customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template html files #ui: # appName: exampleAppName # Application's visible name diff --git a/build.gradle b/build.gradle index 0cb4d653..899fc0e8 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ plugins { import com.github.jk1.license.render.* group = 'stirling.software' -version = '0.23.0' +version = '0.23.1' sourceCompatibility = '17' repositories { diff --git a/src/main/java/stirling/software/SPDF/config/AppConfig.java b/src/main/java/stirling/software/SPDF/config/AppConfig.java index d239969f..16618e1e 100644 --- a/src/main/java/stirling/software/SPDF/config/AppConfig.java +++ b/src/main/java/stirling/software/SPDF/config/AppConfig.java @@ -7,18 +7,34 @@ import java.util.Properties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.thymeleaf.spring6.SpringTemplateEngine; import stirling.software.SPDF.model.ApplicationProperties; @Configuration +@Lazy public class AppConfig { @Autowired ApplicationProperties applicationProperties; + @Bean + @ConditionalOnProperty( + name = "system.customHTMLFiles", + havingValue = "true", + matchIfMissing = false) + public SpringTemplateEngine templateEngine(ResourceLoader resourceLoader) { + SpringTemplateEngine templateEngine = new SpringTemplateEngine(); + templateEngine.addTemplateResolver(new FileFallbackTemplateResolver(resourceLoader)); + return templateEngine; + } + @Bean(name = "loginEnabled") public boolean loginEnabled() { return applicationProperties.getSecurity().getEnableLogin(); diff --git a/src/main/java/stirling/software/SPDF/config/FileFallbackTemplateResolver.java b/src/main/java/stirling/software/SPDF/config/FileFallbackTemplateResolver.java new file mode 100644 index 00000000..10ea9488 --- /dev/null +++ b/src/main/java/stirling/software/SPDF/config/FileFallbackTemplateResolver.java @@ -0,0 +1,48 @@ +package stirling.software.SPDF.config; + +import java.io.IOException; +import java.util.Map; + +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.thymeleaf.IEngineConfiguration; +import org.thymeleaf.templateresolver.AbstractConfigurableTemplateResolver; +import org.thymeleaf.templateresource.ClassLoaderTemplateResource; +import org.thymeleaf.templateresource.FileTemplateResource; +import org.thymeleaf.templateresource.ITemplateResource; + +public class FileFallbackTemplateResolver extends AbstractConfigurableTemplateResolver { + + private final ResourceLoader resourceLoader; + + public FileFallbackTemplateResolver(ResourceLoader resourceLoader) { + super(); + this.resourceLoader = resourceLoader; + setSuffix(".html"); + } + + // Note this does not work in local IDE, Prod jar only. + @Override + protected ITemplateResource computeTemplateResource( + IEngineConfiguration configuration, + String ownerTemplate, + String template, + String resourceName, + String characterEncoding, + Map templateResolutionAttributes) { + Resource resource = + resourceLoader.getResource("file:./customFiles/templates/" + resourceName); + try { + if (resource.exists() && resource.isReadable()) { + return new FileTemplateResource(resource.getFile().getPath(), characterEncoding); + } + } catch (IOException e) { + + } + + return new ClassLoaderTemplateResource( + Thread.currentThread().getContextClassLoader(), + "classpath:/templates/" + resourceName, + characterEncoding); + } +} diff --git a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java index 1a2aeaec..c4a88fb3 100644 --- a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java +++ b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java @@ -212,6 +212,15 @@ public class ApplicationProperties { private Integer maxFileSize; private boolean showUpdate; private Boolean showUpdateOnlyAdmin; + private boolean customHTMLFiles; + + public boolean isCustomHTMLFiles() { + return customHTMLFiles; + } + + public void setCustomHTMLFiles(boolean customHTMLFiles) { + this.customHTMLFiles = customHTMLFiles; + } public boolean getShowUpdateOnlyAdmin() { return showUpdateOnlyAdmin; diff --git a/src/main/resources/settings.yml.template b/src/main/resources/settings.yml.template index b3d6e954..db9f9cd1 100644 --- a/src/main/resources/settings.yml.template +++ b/src/main/resources/settings.yml.template @@ -14,7 +14,8 @@ system: enableAlphaFunctionality: false # Set to enable functionality which might need more testing before it fully goes live (This feature might make no changes) showUpdate: true # see when a new update is available showUpdateOnlyAdmin: false # Only admins can see when a new update is available, depending on showUpdate it must be set to 'true' - + customHTMLFiles: false # Enable to have files placed in /customFiles/templates override the existing template html files + #ui: # appName: exampleAppName # Application's visible name # homeDescription: I am a description # Short description or tagline shown on homepage.