Adding "syntactical sugar" utility methods

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Adding "syntactical sugar" utility methods

Rich MacDonald
New user here. I am finding myself wanting to add some convenient syntax for a repetitive task. I am building the html style attribute with a set of variables. My code is something like:

<div th:fragment='build_style_example'
        th:with="
                _width = 'width:' + (${width} ? '200px'),
                _height = ${height} ? |;height:${height}| : ~{},
                _style = ${_span_width} + ';' + ${_span_height}
        "
        <span th:style='${_style}'>
</div>

Use the value of ${width} or a default value of '200px'. If height is not provided, skip it.

This works fine. I am using local variables to build the string because I can break the computation into readable steps.

I will use this pattern very often. So I would like to shorten this to something like:

<div th:fragment='build_style_example'

        th:with="
                _style = ${#extras.attrs(
                        #extras.attr('width', ${width}, '200px'),
                        #extras.attr('length', ${length})
                )}
        "
        <span th:style='${_style}'>       
       
</div>

For those who don't see much improvement, I get it. Bear with me, as that isn't the point. Maybe a better example would be adding a simple new Strings method such as: "${!#strings.concatWithSeparator(${list}, ';')}"

So what are my options:

1) Define a new Dialect and Processor.
2) Hack the code to add new methods to the Strings class.
3) Define a set of templates that perform these functions.

I am too noob to do #1, but will get there eventually. So an example of doing this would be very helpful.

Let's pretend I never mentioned #2. :-)

How about #3? I can do this, but I don't see it shortening the amount of syntax. Whatever I save will be made up for with the series of "th:replace="buildAttr(width', ${width}, '200px')" code.

With #3, I have a noob question: I'd write the template inside the new element, such as:

<div th:fragment='buildAttr(attrName, attrValue, defaultValue)'
        'attrName' + ':' + (${attrValue} ? 'defaultValue')
</div>

but want the content and not the element. Having to append 'content()' to all my client code causes bloat. Would this be an appropriate usage of th:include?

TIA.