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:
Ludy
2026-01-21 22:58:29 +01:00
committed by GitHub
parent b58efaf388
commit 80cba55459
135 changed files with 11 additions and 18244 deletions

View File

@@ -8,7 +8,7 @@ Stirling-PDF is a robust, locally hosted, web-based PDF manipulation tool. This
Stirling-PDF is built using:
- Spring Boot + Thymeleaf
- Spring Boot
- PDFBox
- LibreOffice
- qpdf
@@ -94,7 +94,6 @@ Stirling-PDF/
│ │ │ ├── css/
│ │ │ ├── js/
│ │ │ └── pdfjs/
│ │ └── templates/
│ └── test/
│ └── java/
│ └── stirling/
@@ -242,7 +241,6 @@ For quick iterations and development of Java backend, JavaScript, and UI compone
- RESTful API endpoints
- JavaScript functionality
- User interface components and styling
- Thymeleaf templates
To run Stirling-PDF locally:
@@ -333,61 +331,6 @@ Remember to test your changes thoroughly to ensure they don't break any existing
## Code examples
### Overview of Thymeleaf
Thymeleaf is a server-side Java HTML template engine. It is used in Stirling-PDF to render dynamic web pages. Thymeleaf integrates heavily with Spring Boot.
### Thymeleaf overview
In Stirling-PDF, Thymeleaf is used to create HTML templates that are rendered on the server side. These templates are located in the `app/core/src/main/resources/templates` directory. Thymeleaf templates use a combination of HTML and special Thymeleaf attributes to dynamically generate content.
Some examples of this are:
```html
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
```
or
```html
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
```
Where it uses the `th:block`, `th:` indicating it's a special Thymeleaf element to be used server-side in generating the HTML, and block being the actual element type.
In this case, we are inserting the `navbar` entry within the `fragments/navbar.html` fragment into the `th:block` element.
They can be more complex, such as:
```html
<th:block th:insert="~{fragments/common :: head(title=#{pageExtracter.title}, header=#{pageExtracter.header})}"></th:block>
```
Which is the same as above but passes the parameters title and header into the fragment `common.html` to be used in its HTML generation.
Thymeleaf can also be used to loop through objects or pass things from the Java side into the HTML side.
```java
@GetMapping
public String newFeaturePage(Model model) {
model.addAttribute("exampleData", exampleData);
return "new-feature";
}
```
In the above example, if exampleData is a list of plain java objects of class Person and within it, you had id, name, age, etc. You can reference it like so
```html
<tbody>
<!-- Use th:each to iterate over the list -->
<tr th:each="person : ${exampleData}">
<td th:text="${person.id}"></td>
<td th:text="${person.name}"></td>
<td th:text="${person.age}"></td>
<td th:text="${person.email}"></td>
</tr>
</tbody>
```
This would generate n entries of tr for each person in exampleData
### Adding a New Feature to the Backend (API)
1. **Create a New Controller:**
@@ -412,7 +355,7 @@ This would generate n entries of tr for each person in exampleData
@GetMapping
@Operation(summary = "New Feature", description = "This is a new feature endpoint.")
public String newFeature() {
return "NewFeatureResponse"; // This refers to the NewFeatureResponse.html template presenting the user with the generated html from that file when they navigate to /api/v1/new-feature
return "NewFeatureResponse";
}
}
```
@@ -467,91 +410,6 @@ This would generate n entries of tr for each person in exampleData
}
```
### Adding a New Feature to the Frontend (UI)
1. **Create a New Thymeleaf Template:**
- Create a new HTML file in the `app/core/src/main/resources/templates` directory.
- Use Thymeleaf attributes to dynamically generate content.
- Use `extract-page.html` as a base example for the HTML template, which is useful to ensure importing of the general layout, navbar, and footer.
```html
<!DOCTYPE html>
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
<head>
<th:block th:insert="~{fragments/common :: head(title=#{newFeature.title}, header=#{newFeature.header})}"></th:block>
</head>
<body>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<span class="material-symbols-rounded tool-header-icon organize">upload</span>
<span class="tool-header-text" th:text="#{newFeature.header}"></span>
</div>
<form th:action="@{'/api/v1/new-feature'}" method="post" enctype="multipart/form-data">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
<input type="hidden" id="customMode" name="customMode" value="">
<div class="mb-3">
<label for="featureInput" th:text="#{newFeature.prompt}"></label>
<input type="text" class="form-control" id="featureInput" name="featureInput" th:placeholder="#{newFeature.placeholder}" required>
</div>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{newFeature.submit}"></button>
</form>
</div>
</div>
</div>
</div>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
</body>
</html>
```
2. **Create a New Controller for the UI:**
- Create a new Java class in the `app/core/src/main/java/stirling/software/SPDF/controller/ui` directory.
- Annotate the class with `@Controller` and `@RequestMapping` to define the UI endpoint.
```java
package stirling.software.SPDF.controller.ui;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import stirling.software.SPDF.service.NewFeatureService;
@Controller
@RequestMapping("/new-feature")
public class NewFeatureUIController {
@Autowired
private NewFeatureService newFeatureService;
@GetMapping
public String newFeaturePage(Model model) {
model.addAttribute("newFeatureData", newFeatureService.getNewFeatureData());
return "new-feature";
}
}
```
3. **Update the Navigation Bar:**
- Add a link to the new feature page in the navigation bar.
- Update the `app/core/src/main/resources/templates/fragments/navbar.html` file.
```html
<li class="nav-item">
<a class="nav-link" th:href="@{'/new-feature'}">New Feature</a>
</li>
```
## Adding New Translations to Existing Language Files in Stirling-PDF
When adding a new feature or modifying existing ones in Stirling-PDF, you'll need to add new translation entries to the existing language files. Here's a step-by-step guide:
@@ -581,15 +439,4 @@ pdfSplitter.input.pages=Enter page numbers to split
Add these entries to the default GB language file and any others you wish, translating the values as appropriate for each language.
### 3. Use Translations in Thymeleaf Templates
In your Thymeleaf templates, use the `#{key}` syntax to reference the new translations:
```html
<h1 th:text="#{pdfSplitter.title}">PDF Splitter</h1>
<p th:text="#{pdfSplitter.description}">Split your PDF into multiple documents</p>
<input type="text" th:placeholder="#{pdfSplitter.input.pages}">
<button th:text="#{pdfSplitter.button.split}">Split PDF</button>
```
Remember, never hard-code text in your templates or Java code. Always use translation keys to ensure proper localization.