mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-02-17 13:52:14 +01:00
refactor: remove legacy Thymeleaf web UI controllers and templates (#5406)
# Description of Changes This pull request completes the removal of Thymeleaf template engine support and documentation from the Stirling-PDF codebase and developer guides, reflecting the project's full migration to a React-based frontend. It removes all references to Thymeleaf in code, configuration, and documentation, and updates guides to focus exclusively on the React SPA architecture. This streamlines the codebase and clarifies the development workflow for contributors. **Codebase cleanup: Thymeleaf removal** - Removed all commented-out Thymeleaf dependencies and related configuration beans from `build.gradle` and `AppConfig.java` (`app/common/build.gradle`, `app/common/src/main/java/stirling/software/common/configuration/AppConfig.java`) [[1]](diffhunk://#diff-2a1a21726f33b05d16451237c68d6df91a5f4a58419d839715f3f1538a9a14aeL32) [[2]](diffhunk://#diff-70792df9a0ab5675ded888c9eb8e2815c780d7b39f4bda8cf2da51d1b336899aL67-L76). - Fully commented out (as a precursor to future deletion) the `FileFallbackTemplateResolver` and `InputStreamTemplateResource` classes, which were only used for Thymeleaf template resolution (`app/common/src/main/java/stirling/software/common/configuration/FileFallbackTemplateResolver.java`, `app/common/src/main/java/stirling/software/common/model/InputStreamTemplateResource.java`) [[1]](diffhunk://#diff-e2bc7614074316b972355cb7dda47b98f75b00eb6b2ca4f143a680ab2803dcd8L1-L49) [[2]](diffhunk://#diff-ab10ee12d8de8fb77759e931170373d388bde04bad6d0e42a0ab674355ef7ef3L1-L40). **Documentation updates: React-only focus** - Removed all instructions and references to migrating or developing with Thymeleaf templates in `DeveloperGuide.md` and `ADDING_TOOLS.md`, including detailed Thymeleaf usage examples, migration steps, and translation key usage in templates [[1]](diffhunk://#diff-ccd22fcbec8148152c8c77b85fbfe2633a6707b5ad50c2ef88fa87e2c47ea88fL5-R5) [[2]](diffhunk://#diff-ccd22fcbec8148152c8c77b85fbfe2633a6707b5ad50c2ef88fa87e2c47ea88fL41-L43) [[3]](diffhunk://#diff-ccd22fcbec8148152c8c77b85fbfe2633a6707b5ad50c2ef88fa87e2c47ea88fL103-L105) [[4]](diffhunk://#diff-ccd22fcbec8148152c8c77b85fbfe2633a6707b5ad50c2ef88fa87e2c47ea88fL157) [[5]](diffhunk://#diff-ccd22fcbec8148152c8c77b85fbfe2633a6707b5ad50c2ef88fa87e2c47ea88fL312) [[6]](diffhunk://#diff-ccd22fcbec8148152c8c77b85fbfe2633a6707b5ad50c2ef88fa87e2c47ea88fL404-R396) [[7]](diffhunk://#diff-ccd22fcbec8148152c8c77b85fbfe2633a6707b5ad50c2ef88fa87e2c47ea88fL451-L505) [[8]](diffhunk://#diff-ccd22fcbec8148152c8c77b85fbfe2633a6707b5ad50c2ef88fa87e2c47ea88fL530-R467) [[9]](diffhunk://#diff-ccd22fcbec8148152c8c77b85fbfe2633a6707b5ad50c2ef88fa87e2c47ea88fL585-L669) [[10]](diffhunk://#diff-ccd22fcbec8148152c8c77b85fbfe2633a6707b5ad50c2ef88fa87e2c47ea88fL699-L709) [[11]](diffhunk://#diff-e2f8148ea620602b7761e8ee24afeac1c577476630528e210fe0b22e950016ddL3-R3) [[12]](diffhunk://#diff-e2f8148ea620602b7761e8ee24afeac1c577476630528e210fe0b22e950016ddL267-R267). - Updated architecture descriptions in `CLAUDE.md` to reflect that the frontend is now exclusively a React SPA and that Thymeleaf templates have been fully replaced [[1]](diffhunk://#diff-6ebdb617a8104a7756d0cf36578ab01103dc9f07e4dc6feb751296b9c402faf7L131-R132) [[2]](diffhunk://#diff-6ebdb617a8104a7756d0cf36578ab01103dc9f07e4dc6feb751296b9c402faf7L143-L144). **Labeler configuration update** - Removed labeler rules for files related to the old Thymeleaf-based web controllers and UI directories, as these are now obsolete (`.github/labeler-config-srvaroa.yml`). These changes ensure the codebase and documentation are consistent with the new React-only frontend approach, reducing maintenance overhead and potential confusion for contributors. --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### Translations (if applicable) - [ ] I ran [`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details.
This commit is contained in:
@@ -29,7 +29,6 @@ spotless {
|
||||
dependencies {
|
||||
api 'org.springframework.boot:spring-boot-starter-web'
|
||||
api 'org.springframework.boot:spring-boot-starter-aop'
|
||||
// api 'org.springframework.boot:spring-boot-starter-thymeleaf' // Deprecated - UI moved to React frontend
|
||||
api 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1'
|
||||
api 'com.fathzer:javaluator:3.0.6'
|
||||
api 'com.posthog.java:posthog:1.2.0'
|
||||
|
||||
@@ -64,16 +64,6 @@ public class AppConfig {
|
||||
return v2Enabled;
|
||||
}
|
||||
|
||||
/* Commented out Thymeleaf template engine bean - to be removed when frontend migration is complete
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "system.customHTMLFiles", havingValue = "true")
|
||||
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().isEnableLogin();
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package stirling.software.common.configuration;
|
||||
|
||||
/* Commented out entire FileFallbackTemplateResolver class - Thymeleaf dependency removed
|
||||
* This class will be removed when frontend migration to React is complete
|
||||
|
||||
|
||||
@Slf4j
|
||||
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<String, Object> templateResolutionAttributes) {
|
||||
Resource resource =
|
||||
resourceLoader.getResource(
|
||||
"file:" + InstallationPathConfig.getTemplatesPath() + resourceName);
|
||||
try {
|
||||
if (resource.exists() && resource.isReadable()) {
|
||||
return new FileTemplateResource(resource.getFile().getPath(), characterEncoding);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Log the exception to help with debugging issues loading external templates
|
||||
log.warn("Unable to read template '{}' from file system", resourceName, e);
|
||||
}
|
||||
|
||||
InputStream inputStream =
|
||||
Thread.currentThread()
|
||||
.getContextClassLoader()
|
||||
.getResourceAsStream("templates/" + resourceName);
|
||||
if (inputStream != null) {
|
||||
return new InputStreamTemplateResource(inputStream, "UTF-8");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -1,40 +0,0 @@
|
||||
package stirling.software.common.model;
|
||||
|
||||
/* Commented out entire InputStreamTemplateResource class - Thymeleaf dependency removed
|
||||
* This class will be removed when frontend migration to React is complete
|
||||
|
||||
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public class InputStreamTemplateResource implements ITemplateResource {
|
||||
private final InputStream inputStream;
|
||||
private final String characterEncoding;
|
||||
|
||||
@Override
|
||||
public Reader reader() throws IOException {
|
||||
return new InputStreamReader(inputStream, characterEncoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITemplateResource relative(String relativeLocation) {
|
||||
// Implement logic for relative resources, if needed
|
||||
throw new UnsupportedOperationException("Relative resources not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "InputStream resource [Stream]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseName() {
|
||||
return "streamResource";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return inputStream != null;
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -1,88 +0,0 @@
|
||||
package stirling.software.common.model;
|
||||
|
||||
/* Commented out - InputStreamTemplateResource class removed with Thymeleaf migration
|
||||
* This test will be removed when frontend migration to React is complete
|
||||
|
||||
|
||||
public class InputStreamTemplateResourceTest {
|
||||
|
||||
@Test
|
||||
void gettersReturnProvidedFields() {
|
||||
byte[] data = {1, 2, 3};
|
||||
InputStream is = new ByteArrayInputStream(data);
|
||||
String encoding = "UTF-8";
|
||||
InputStreamTemplateResource resource = new InputStreamTemplateResource(is, encoding);
|
||||
|
||||
assertSame(is, resource.getInputStream());
|
||||
assertEquals(encoding, resource.getCharacterEncoding());
|
||||
}
|
||||
|
||||
@Test
|
||||
void fieldsAreFinal() throws NoSuchFieldException {
|
||||
Field inputStreamField = InputStreamTemplateResource.class.getDeclaredField("inputStream");
|
||||
Field characterEncodingField =
|
||||
InputStreamTemplateResource.class.getDeclaredField("characterEncoding");
|
||||
|
||||
assertTrue(Modifier.isFinal(inputStreamField.getModifiers()));
|
||||
assertTrue(Modifier.isFinal(characterEncodingField.getModifiers()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void noSetterMethodsPresent() {
|
||||
long setterCount =
|
||||
Arrays.stream(InputStreamTemplateResource.class.getDeclaredMethods())
|
||||
.filter(method -> method.getName().startsWith("set"))
|
||||
.count();
|
||||
|
||||
assertEquals(0, setterCount, "InputStreamTemplateResource should not have setter methods");
|
||||
}
|
||||
|
||||
@Test
|
||||
void readerReturnsCorrectContent() throws Exception {
|
||||
String content = "Hello, world!";
|
||||
InputStream is = new ByteArrayInputStream(content.getBytes("UTF-8"));
|
||||
InputStreamTemplateResource resource = new InputStreamTemplateResource(is, "UTF-8");
|
||||
|
||||
try (Reader reader = resource.reader()) {
|
||||
char[] buffer = new char[content.length()];
|
||||
int read = reader.read(buffer);
|
||||
assertEquals(content.length(), read);
|
||||
assertEquals(content, new String(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void relativeThrowsUnsupportedOperationException() {
|
||||
InputStream is = new ByteArrayInputStream(new byte[0]);
|
||||
InputStreamTemplateResource resource = new InputStreamTemplateResource(is, "UTF-8");
|
||||
assertThrows(UnsupportedOperationException.class, () -> resource.relative("other"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDescriptionReturnsExpectedString() {
|
||||
InputStream is = new ByteArrayInputStream(new byte[0]);
|
||||
InputStreamTemplateResource resource = new InputStreamTemplateResource(is, "UTF-8");
|
||||
assertEquals("InputStream resource [Stream]", resource.getDescription());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBaseNameReturnsExpectedString() {
|
||||
InputStream is = new ByteArrayInputStream(new byte[0]);
|
||||
InputStreamTemplateResource resource = new InputStreamTemplateResource(is, "UTF-8");
|
||||
assertEquals("streamResource", resource.getBaseName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void existsReturnsTrueWhenInputStreamNotNull() {
|
||||
InputStream is = new ByteArrayInputStream(new byte[0]);
|
||||
InputStreamTemplateResource resource = new InputStreamTemplateResource(is, "UTF-8");
|
||||
assertTrue(resource.exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
void existsReturnsFalseWhenInputStreamIsNull() {
|
||||
InputStreamTemplateResource resource = new InputStreamTemplateResource(null, "UTF-8");
|
||||
assertFalse(resource.exists());
|
||||
}
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user