Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
156 changes: 58 additions & 98 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,57 @@
Thymeleaf Component Dialect
===========================
<p align="center">
<img src="assets/logo.png" alt="Thymeleaf Component Dialect" width="120">
</p>

[![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/main/LICENSE.txt)
<h1 align="center">Thymeleaf Component Dialect</h1>

A dialect for creating reusable Thymeleaf components, similar to React or Vue components.
<p align="center">
<a href="https://github.com/Serbroda/thymeleaf-component-dialect/actions/workflows/ci.yml"><img src="https://github.com/Serbroda/thymeleaf-component-dialect/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
<a href="https://jitpack.io/#Serbroda/thymeleaf-component-dialect"><img src="https://jitpack.io/v/Serbroda/thymeleaf-component-dialect.svg" alt="jitpack"></a>
<a href="https://github.com/Serbroda/thymeleaf-component-dialect/blob/main/LICENSE.txt"><img src="https://img.shields.io/github/license/Serbroda/thymeleaf-component-dialect.svg" alt="license"></a>
</p>

Requirements
------
<p align="center">A dialect for creating reusable Thymeleaf components with named slots, similar to React or Vue components.</p>

- Java 17+
- Thymeleaf 3.1+
## Quick Example

Installation
------
**Define** a component (`templates/components/panel.html`):

Add the jitpack repository.
```html
<div th:fragment="panel(title)" class="card">
<div class="card-header"><b th:text="${title}"></b></div>
<div class="card-body"><tc:content></tc:content></div>
</div>
```

**Use** it in your template:

```html
<tc:panel tc:constructor="'My Title'">
<p>Hello world</p>
</tc:panel>
```

**Result:**

```html
<div class="card">
<div class="card-header"><b>My Title</b></div>
<div class="card-body"><p>Hello world</p></div>
</div>
```

## Features

- **Reusable Components** - Define with `th:fragment`, use with `<tc:*>` tags
- **[Named Slots](docs/named-slots.md)** - Multiple content areas per component
- **[Fallback Content](docs/named-slots.md#fallback-content)** - Default content when no slot is provided
- **[tc:once](docs/once-attribute.md)** - Deduplicate scripts and styles
- **[Attribute Replacement](docs/components.md#attribute-replacement)** - Dynamic placeholder values
- **Spring Boot Auto-Configuration** - Just add the dependency, no setup needed

## Installation

Requires **Java 17+** and **Thymeleaf 3.1+**.

```xml
<repositories>
Expand All @@ -25,108 +60,33 @@ Add the jitpack repository.
<url>https://jitpack.io</url>
</repository>
</repositories>
```

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

```xml
<dependency>
<groupId>com.github.Serbroda</groupId>
<artifactId>thymeleaf-component-dialect</artifactId>
<version>VERSION</version>
</dependency>
```

**With Spring Boot 3.x:** No configuration needed. The dialect is auto-configured and scans `templates/components/` for component fragments.

**Custom configuration:** To customize the component directory or register components manually, define your own `ComponentDialect` bean (the auto-configuration will back off):

```java
@Bean
public ComponentDialect componentDialect() {
ComponentDialect dialect = new ComponentDialect();
dialect.addParser(new StandardThymeleafComponentParser("templates/", ".html", "my-components"));
return dialect;
}
```
**Spring Boot 3.x:** No configuration needed - auto-configured out of the box.

**Without Spring Boot:** Register the dialect manually with your `TemplateEngine`.
See [Getting Started](docs/getting-started.md) for Gradle setup, custom configuration, and non-Spring Boot usage.

Usage
-----
## Documentation

### 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.

```html
<div th:fragment="panel" class="panel panel-primary">
<div class="panel-heading">
<b th:text="${title != null ? title : ''}"></b>
</div>
<div class="panel-body">
<tc:content></tc:content>
</div>
</div>
```

### Use the component

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="https://github.com/Serbroda/thymeleaf-component-dialect">
<head>
</head>
<body>
<tc:panel title="'A title'">
<h1>Hello world</h1>
<p>This is my first thymeleaf component</p>
</tc:panel>
</body>
</html>
```

### The result will be

```html
<div class="panel panel-primary">
<div class="panel-heading">
<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>
```
- [Getting Started](docs/getting-started.md) - Installation and setup
- [Components](docs/components.md) - Defining and using components
- [Named Slots](docs/named-slots.md) - Multi-slot content projection
- [tc:once Attribute](docs/once-attribute.md) - Deduplicate scripts and styles

Contributing
------
## 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
------
## License

This project is licensed under the [Apache License, Version 2.0](LICENSE.txt).
This project is licensed under the [Apache License, Version 2.0](LICENSE.txt).
Binary file added assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading