New extension "Thymesheet" : CSS for Thymeleaf

classic Classic list List threaded Threaded
12 messages Options
4dz
Reply | Threaded
Open this post in threaded view
|

New extension "Thymesheet" : CSS for Thymeleaf

4dz
We've been using Thymeleaf on a few projects recently.
One afternoon one of my team said out loud, "you know, the natural next step for Thymeleaf is to take all the attributes out of the HTML and put them into a CSS file"

We've done just that, and called it Thymesheet.

Thymesheet makes natural templating even more natural as you do not have to modify the HTML at all!

Optionally you may add a <link rel="thymesheet" href="file.tss"/>

Or you can specify thymesheet files in a properties file.

So essentially you write CSS3 selectors and assign th-each, th-text, etc attributes in much the same way as CSS styles. If you want, you can mix traditional Thymeleaf with Thymesheet.

This extension is compatible with custom dialects, Spring, Tiles etc and is currently based on Thymeleaf 2.1 beta 2.

There is a Spring MVC demo project available.

The jars are not yet uploaded to a Maven repo, and there are a few outstanding pieces of functionality we'd like to add - this is effectively a beta right now.

Check it out, let me know what you think!

http://connect-group.github.io/thymesheet/
4dz
Reply | Threaded
Open this post in threaded view
|

Re: New extension "Thymesheet" : CSS for Thymeleaf

4dz
Some example "Thymesheet"

table > thead > tr th:first-child {
    th-text: "#{msgs.headers.name}"
}

table > thead > tr th:nth-child(2) {
    th-text: "#{msgs.headers.price}"
}

table > tbody > tr:first-child {
    th-each:"prod : ${allProducts}";
}

table > tbody > tr:not(:first-child) {
    th-remove:"all";
}

table > tbody > tr > td:first-child {
    th-text: "${prod.name}"
}

table > tbody > tr > td:nth-child(2) {
    th-text: "${#numbers.formatDecimal(prod.price,1,2)}"
}
Reply | Threaded
Open this post in threaded view
|

Re: New extension "Thymesheet" : CSS for Thymeleaf

Zemi
Administrator
Wow, I think a similar idea (detached templates) is in the roadmap for the version 3. With a completely different syntax, of course, but the same idea.

Sure this would add some real experience to that idea.

I'll give it a try.

Regards,
   Zemi

Reply | Threaded
Open this post in threaded view
|

Re: New extension "Thymesheet" : CSS for Thymeleaf

danielfernandez
Administrator
In reply to this post by 4dz
Wow, this is very interesting. Congratulations!

I like your idea of using CSS selectors as a way to specify the nodes on which attributes should be applied. From a quick look at your code, you seem to be using a decorator on the template parser in order to apply the extra attributes to each element, which is IMHO the correct way of doing this.

So well done! If you send me an email with a one-paragraph description, I'll be happy to add a link to Thymesheet from http://www.thymeleaf.org/ecosystem.html


By the way: Thymesheet is in fact quite similar to something we plan to implement for 3.0 (it was for 2.1 initially, but we delayed it): "decoupled/detached templates": https://github.com/thymeleaf/thymeleaf/issues/47 Nevertheless, our idea was to use DOM Selectors instead of CSS selectors, which is the main reason why we improved DOM Selectors in 2.1 ( http://www.thymeleaf.org/whatsnew21.html#doms )

Regards,
Daniel.
Reply | Threaded
Open this post in threaded view
|

Re: New extension "Thymesheet" : CSS for Thymeleaf

sunil0791
Nice.. Very Interesting..
4dz
Reply | Threaded
Open this post in threaded view
|

Re: New extension "Thymesheet" : CSS for Thymeleaf

4dz
In reply to this post by danielfernandez
It is very similar to the "detached" issue you mention!
It's all opensource so anything useful, feel free to copy/fork/etc.

For the CSS selector I modified https://github.com/chrsan/css-selectors to use the Thymeleaf DOM.

The original Thymeleaf parsers do the work of converting from XML/HTML to the Thymeleaf DOM.

They are decorated so that once the DoM is built, a ThymesheetPreprocessor reads any TSS files and applies the selectors. It then adds attributes to the Thymeleaf DOM.

Then it's all handled by Thymeleaf - DOM cached, dialects can be applied, etc.

It's also possible to inject th:block elements.
Reply | Threaded
Open this post in threaded view
|

Re: New extension "Thymesheet" : CSS for Thymeleaf

Emanuel
Administrator
In reply to this post by 4dz
+1 :)

Question: I see you've used an existing CSS parser library for the CSS selector matching.  Did you ever come across any CSS libraries that let you do nested CSS selectors like when writing SASS or LESS?  It's probably my favourite feature of those CSS pre-processor libraries, and I never write 'normal' CSS any more now that I can do nesting.

I'm just curious because, if it's possible to plug that kind of parser/library in there, then OMG I'd be totally sold.

Also, the project name is pretty cool; I could never think of any play on the word 'thyme' when coming up with my own Thymeleaf projects.
4dz
Reply | Threaded
Open this post in threaded view
|

Re: New extension "Thymesheet" : CSS for Thymeleaf

4dz
The parser doesn't support SASS style nesting. But it's probably a good candidate for rewrite partly as it's LGPL and everything else Thymeleaf is Apache2 or compatible. I should think the nesting part would be easy enough. I doubt there'd be much need for mixins! That said if you wanted to you might be able to use SASS to generate these files? Haven't tried it though! One possible use for this CSS syntax is re-use but again possibly limited. For example say you want to show the same list of links at the top & bottom of the page; you could write the logic just once.
    .links { th-each: "link : ${links}"; }
    .links li:first-child a { th-href: ${link.href}; th-text: ${link.text}; }
Then anywhere on the page you put HTML with those classes, you get the logic added. Eg.
<ul class=links>
<li><a href=page.html>link to page</a></li>
</ul>

Main page body
...
...

<ul class=links>
<li><a href=page.html>link to page</a></li>
</ul>

4dz
Reply | Threaded
Open this post in threaded view
|

Re: New extension "Thymesheet" : CSS for Thymeleaf

4dz
I don't have access to a computer for a few days but will see if SASS lets you use non-valid CSS properties.
If it does then it would be possible to use SASS in the same way as SASS->CSS compilation.

But native support without the need for a precompiler would be nice!
Reply | Threaded
Open this post in threaded view
|

Re: New extension "Thymesheet" : CSS for Thymeleaf

thymus.js
In reply to this post by 4dz
Nice! I was thinking of doing a similar thing in http://ugate.github.io/thymus/
4dz
Reply | Threaded
Open this post in threaded view
|

Re: New extension "Thymesheet" : CSS for Thymeleaf

4dz
Now that Thymeleaf 2.1.0 is released, I've also release Thymesheet (on Git, and in Maven).

"Thymesheet is an extension for Thymeleaf which allows you to move attributes such as th:if, th:text etc, into an external CSS3 file.  This means that absolutely no Java/server logic is embedded in the HTML at all - taking natural templating one step further! Compatible with Tiles, Spring, Conditional Comments, and any Thymeleaf dialect"

http://connect-group.github.io/thymesheet/

Just like the core Thymeleaf, there is also a Spring integration project; and an example project to see how it all works.  These are referenced from the github site above.

I hope you like it!

4dz
Reply | Threaded
Open this post in threaded view
|

Re: New extension "Thymesheet" : CSS for Thymeleaf

4dz
In reply to this post by Emanuel
Hi Emanuel

This morning I did a quick test with SASS, and it works perfectly.  You can use standard SASS, or add SASS to a maven build.

	<groupId>org.jasig.maven</groupId>
	<artifactId>sass-maven-plugin</artifactId>
	<version>1.1.1</version>

This is a great idea as it means you can use mixins!

As an example, on a project I'm working on we have a Java Bean called LinkBean.  In essence this is basically,

    public interface LinkBean {
        String getHref();
        String getText();
        String getClass();
    }

In Thymeleaf you could then write something like,

     <a th:href="${link.href}" th:text="${link.text}" th:class="${link.class}">LINK</a>

In my project I created a dialect/processor to make this a bit less verbose, and then the html becomes e.g.

     <a th:link="${link}">LINK</a>

Of course I had to write a bit of Java code for the :link.

With SASS and Thymesheet, you can create a mixin instead of coding a custom processor!

    @mixin link-bean($link) {
	th-object: $link;
        th-href: "*{href}";
        th-class: "*{class}";
        th-text: "*{text}";
    }

    a.link {
        @include link-bean("${linkBean}");
    }


    .slideshow {
        th-remove: "all-but-first";

        .call-to-action a {
            th-each: "cta : ${slideshow.ctas}";
            @include link-bean("${cta.linkBean}");
        }
    }