Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
c77dd86
Update version
Serbroda Oct 17, 2017
4cff18d
Rename variables
Serbroda Oct 18, 2017
3f34d9a
Delete unused file
Serbroda Oct 18, 2017
e62ee8f
Add junit dependency
Serbroda Oct 18, 2017
a309585
Remove 'Web' from gitignore and add test classes and resources
Serbroda Oct 18, 2017
7728aa9
Add tests
Serbroda Oct 18, 2017
47db145
Remame file
Serbroda Oct 18, 2017
67ee080
Add html that doesn't contain a component
Serbroda Oct 18, 2017
4ad359f
Add named component
Serbroda Oct 18, 2017
8df3a5f
Add assertions
Serbroda Oct 18, 2017
91d08ff
Rename file
Serbroda Oct 18, 2017
cfbe8f1
Complete configuration
Serbroda Oct 18, 2017
3123ca0
Fix for test
Serbroda Oct 18, 2017
41b3764
Add component test
Serbroda Oct 18, 2017
e1989eb
Add assertions
Serbroda Oct 18, 2017
c560b3a
Make class abstract
Serbroda Oct 18, 2017
6e0dee7
Rename html files
Serbroda Oct 18, 2017
5444143
Rename files
Serbroda Oct 18, 2017
2c2e6ce
Add test
Serbroda Oct 18, 2017
fd8e469
Rename test
Serbroda Oct 18, 2017
fa14f1f
Add test
Serbroda Oct 18, 2017
0b32938
Remove spring specific methods
Serbroda Oct 18, 2017
8435536
Add OnceAttributeTest
Serbroda Oct 18, 2017
3a7178d
Fixed issue with "NullPointerException" after building into .jar.
pabsilva Mar 2, 2018
a2b0b59
Merge pull request #2 from DeadalusVIII/develop
Serbroda Mar 6, 2018
4f92520
Add quality gate badge to readme
Serbroda Mar 9, 2018
3d9ce89
Sonar: Remove unused import java.net.URL
Serbroda Mar 9, 2018
9c5c7c3
Sonar: Remove unused parameter 'recursively'
Serbroda Mar 9, 2018
ec7ac5c
Add comment
Serbroda Mar 12, 2018
578eae4
Add slf4j-api dependency
Serbroda Mar 12, 2018
c370453
Use slf4j logger instead of System.out.println to log error
Serbroda Mar 12, 2018
a1d213a
Sonar: Make return statement conditional
Serbroda Mar 12, 2018
701c261
Add possibility to register variables globally via parameter
Serbroda Oct 11, 2018
1adb83c
Replace keyword 'params' with 'tc:constructor'
Serbroda Oct 12, 2018
691f2f4
Rename varibale
Serbroda Oct 12, 2018
601432a
Fix tests
Serbroda Oct 12, 2018
c8c9429
Fix sonarcloud badge
Serbroda Oct 12, 2018
058cdf2
Refactor tests to use JUnit 5 and update Maven dependencies
Serbroda Mar 20, 2026
6c36ade
Update Thymeleaf component namespace to use GitHub URL
Serbroda Mar 20, 2026
e9f31bc
add spotless and format code
Serbroda Mar 20, 2026
e592f87
Refactor code to use modern Java features and improve error handling
Serbroda Mar 20, 2026
bf8b721
remove slf4j logging and throw new custom exceptions instead
Serbroda Mar 20, 2026
2117386
Add license information and contributing guidelines to project docume…
Serbroda Mar 20, 2026
cda8dfe
Update CI configuration and license badge links to reflect main branch
Serbroda Mar 20, 2026
ae5aed2
Update CI configuration to allow pushes from feature branches
Serbroda Mar 20, 2026
3b796f8
Merge branch 'main' into feature/update-2026
Serbroda Mar 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: CI

on:
push:
branches: [ main, 'feature/**' ]
pull_request:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: maven

- name: Build and test
run: ./mvnw clean verify

- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: target/surefire-reports/
13 changes: 0 additions & 13 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -198,17 +198,4 @@ buildNumber.properties
# Project-level settings
/.tgitconfig

### Web ###
*.asp
*.cer
*.csr
*.css
*.htm
*.html
*.js
*.jsp
*.php
*.rss
*.xhtml

# End of https://www.gitignore.io/api/web,git,java,maven,eclipse,tortoisegit,intellij+all,intellij+iml
2 changes: 1 addition & 1 deletion .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
22 changes: 0 additions & 22 deletions .travis.yml

This file was deleted.

52 changes: 40 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
Thymeleaf Component Dialect
===========================

[![Build Status](https://travis-ci.org/Serbroda/thymeleaf-component-dialect.svg?branch=develop)](https://travis-ci.org/Serbroda/thymeleaf-component-dialect)
[![CI](https://github.com/Serbroda/thymeleaf-component-dialect/actions/workflows/ci.yml/badge.svg)](https://github.com/Serbroda/thymeleaf-component-dialect/actions/workflows/ci.yml)
[![jitpack](https://jitpack.io/v/Serbroda/thymeleaf-component-dialect.svg)](https://jitpack.io/#Serbroda/thymeleaf-component-dialect)
[![license](https://img.shields.io/github/license/Serbroda/thymeleaf-component-dialect.svg)](https://github.com/Serbroda/thymeleaf-component-dialect/blob/master/LICENSE.txt)
[![license](https://img.shields.io/github/license/Serbroda/thymeleaf-component-dialect.svg)](https://github.com/Serbroda/thymeleaf-component-dialect/blob/main/LICENSE.txt)

A dialect for creating reusable Thymeleaf components, similar to React or Vue components.

A dialect for creating reusable thymeleaf components.
Requirements
------

- Java 17+
- Thymeleaf 3.1+

Installation
------

Add the jitpack repository.

```html
```xml
<repositories>
<repository>
<id>jitpack.io</id>
Expand All @@ -24,7 +29,7 @@ Add the jitpack repository.

Add the dependency (for all available versions see [https://jitpack.io/#Serbroda/thymeleaf-component-dialect](https://jitpack.io/#Serbroda/thymeleaf-component-dialect)).

```html
```xml
<dependency>
<groupId>com.github.Serbroda</groupId>
<artifactId>thymeleaf-component-dialect</artifactId>
Expand All @@ -47,8 +52,6 @@ public ComponentDialect componentDialect() {
Usage
-----

For detailed configurations have a look at the [demo project](https://github.com/Serbroda/thymeleaf-component-dialect-demo).

### Create a thymeleaf component

Thymeleaf components uses the standard `th:fragment` attribute to register components. Just create a fragment with a `<tc:content/>` tag which will be replaced with specific contents.
Expand All @@ -66,13 +69,13 @@ Thymeleaf components uses the standard `th:fragment` attribute to register compo

### Use the component

Add the namespace `xmlns:tc="http://www.morphbit.com/thymeleaf/component"` and use the component in your application.
Add the namespace `xmlns:tc="https://github.com/Serbroda/thymeleaf-component-dialect"` and use the component in your application.

```html
<!DOCTYPE html>
<html
xmlns:th="http://www.thymeleaf.org"
xmlns:tc="http://www.morphbit.com/thymeleaf/component">
xmlns:tc="https://github.com/Serbroda/thymeleaf-component-dialect">
<head>
</head>
<body>
Expand All @@ -92,10 +95,35 @@ Add the namespace `xmlns:tc="http://www.morphbit.com/thymeleaf/component"` and u
<b>A title</b>
</div>
<div class="panel-body">

<h1>Hello world</h1>
<p>This is my first thymeleaf component</p>

</div>
</div>
```
```

### The `tc:once` Attribute

Use `tc:once` to ensure an element (e.g. a script tag) is only rendered once, even if the component is used multiple times on the same page:

```html
<div th:fragment="my-widget">
<button>Click me</button>
<script tc:once="my-widget-script">
// This script will only be included once
</script>
</div>
```

Contributing
------

Contributions are welcome! Feel free to open an [issue](https://github.com/Serbroda/thymeleaf-component-dialect/issues) or submit a [pull request](https://github.com/Serbroda/thymeleaf-component-dialect/pulls).

Before submitting a PR, please make sure:
- All tests pass: `./mvnw clean verify`
- Code is formatted: `./mvnw spotless:apply`

License
------

This project is licensed under the [Apache License, Version 2.0](LICENSE.txt).
144 changes: 97 additions & 47 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,47 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>de.morphbit</groupId>
<artifactId>thymeleaf-component-dialect</artifactId>
<version>0.0.3-alpha</version>
<packaging>jar</packaging>

<name>thymeleaf-component-dialect</name>
<description>Thymeleaf Layout Dialect</description>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.7.RELEASE</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>de.morphbit</groupId>
<artifactId>thymeleaf-component-dialect</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>thymeleaf-component-dialect</name>
<description>A Thymeleaf dialect for creating reusable components</description>

<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.11.4</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.2</version>
</plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>2.44.3</version>
<configuration>
<java>
<eclipse>
<version>4.33</version>
</eclipse>
<removeUnusedImports/>
<importOrder/>
</java>
</configuration>
<executions>
<execution>
<id>spotless-check</id>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
18 changes: 8 additions & 10 deletions src/main/java/de/morphbit/thymeleaf/dialect/ComponentDialect.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,17 @@

package de.morphbit.thymeleaf.dialect;

import de.morphbit.thymeleaf.model.ThymeleafComponent;
import de.morphbit.thymeleaf.parser.IThymeleafComponentParser;
import de.morphbit.thymeleaf.processor.ComponentNamedElementProcessor;
import de.morphbit.thymeleaf.processor.OnceAttributeTagProcessor;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.thymeleaf.dialect.AbstractProcessorDialect;
import org.thymeleaf.processor.IProcessor;

import de.morphbit.thymeleaf.model.ThymeleafComponent;
import de.morphbit.thymeleaf.parser.IThymeleafComponentParser;
import de.morphbit.thymeleaf.processor.ComponentNamedElementProcessor;
import de.morphbit.thymeleaf.processor.OnceAttributeTagProcessor;

/**
* A dialect for creating reusable composite components with thymeleaf
*
Expand Down Expand Up @@ -73,14 +71,14 @@ public Set<IProcessor> getProcessors(String dialectPrefix) {

if (this.components != null) {
for (ThymeleafComponent comp : this.components) {
processors.add(new ComponentNamedElementProcessor(dialectPrefix,
comp.getName(), comp.getFragmentTemplate()));
processors.add(
new ComponentNamedElementProcessor(dialectPrefix, comp.getName(), comp.getFragmentTemplate()));
}
}

for (ThymeleafComponent comp : parseComponents()) {
processors.add(new ComponentNamedElementProcessor(dialectPrefix,
comp.getName(), comp.getFragmentTemplate()));
processors
.add(new ComponentNamedElementProcessor(dialectPrefix, comp.getName(), comp.getFragmentTemplate()));
}

return processors;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package de.morphbit.thymeleaf.exception;

public class ComponentDialectException extends RuntimeException {

public ComponentDialectException(String message) {
super(message);
}

public ComponentDialectException(String message, Throwable cause) {
super(message, cause);
}
}
Loading
Loading