Skip to content

Latest commit

 

History

History
136 lines (93 loc) · 4.01 KB

README.md

File metadata and controls

136 lines (93 loc) · 4.01 KB

Comptus

License Open Issues Build Status

Comptus is a Thymeleaf dialect for creating reuseable & encapsulated view components.

Like ViewComponents or Angular components Comptus uses real Java classes to represent a component. Each time a component is used anywhere a new instance of this class ist created and a component template is rendered based upon this instance.

Getting started

All you have to do is registering Comptus is your Spring Boot Application by doing something like this:

@SpringBootApplication
public class ThymeleafComptusApplication {

    @Bean
    public ComptusDialect comptusDialect() {
         return new ComptusDialect("com.name.of.your.compontents.package");
    }
}

Defining a component

A comptus component consists of two parts, a java class which extends com.innoq.comptus.core.Component and a HTML template.

E.g. a Button component would be based upon the following class:

package com.name.of.your.compontents.package;

public class Button extends com.innoq.comptus.core.Component {
    public Button(ComponentContext context) {
        super(context);
    }
}

There also needs to be a Thymeleaf template which is rendered each time the component is used.

The Button's template should be placed under /resources/templates/components/button.html and could look like this:

<button class="my-button">
    <co:slot />
</button>

Using components

Now you can use <co:button /> everywhere in your thymeleaf templates like this:

<div>
    <co:button>Click me!</co:button>
</div>

This will produce the following HTML:

<div>
    <button class="my-button">
        Click me!
    </button>
</div>

Methods and attributes

Now let's think about providing data to your component from the outside. Maybe we want to style a button based upon it's "styling" like <co:button styling="cta">Click me!</co:button>.

You can access these attributes for your component e.g. inside of your Button's constructor:

private String styling;

public Button(ComponentContext context) {
    super(context);
    styling = stringAttribute("styling").orElse(null);
}

Now we'll have to use this information to render different HTML in our component template. This could be done by making the instance variable styling a public field.

But this could also be done by providing methods in your component's class:

public String getClassNames() {
    return "my-button %s".formatted("cta".equals(styling) ? "primary" : "default");
}

and calling this method from your component template:

<button th:class="${this.classNames}">
    <co:slot />
</button>

Complex attributes

The th: attribute based approach doesn't work when you want to pass other objects from your view model to your component. So <co:my-component th:my-data="${mySpecialPOJO}" /> won't work since th:* would convert everything toString() at the end and all your component would see is a String.

So Comptus also defines the co:* attributes on all <co:*> elements like:

<co:my-component co:my-data="${mySpecialPOJO}" />

Now you can access your object inside your component using:

MySpecialPOJO myData = attribute("my-data", MySpecialPOJO.class).orElse(null);

Slots

TBD (see src/test/resources/templates/slots.html)

Context

TBD (see src/test/resources/templates/context.html)

License

comptus is Open Source software released under the Apache 2.0 license.