2

I'm looking to do something like the following. Is this possible or is there a workaround?

myFragment.html

<div th:fragment="myContent(someObject)">
  Some popover strings with some business logic
  <span th:text="${someObject.property}">[object property]</span>
</div>

myTemplate.html

<!-- how would I correct this so that the fragment is evaluated? -->
<div th:with="popoverContent = ${myFragment :: myContent(someObject)}">    
    <a th:data-content="${popoverContent}"></a>
</div>

Can I insert a fragment within a th:with as a variable? I can create popoverContent server-side, but I'm thinking there's likely a better way.

Update: More Specifics on Use Case

I need tooltips with some basic math formulas to be styled.

In myFragment.html, I have an HTML table with multiple th:cases in a th:switch. Each td has a tooltip with the calculated values.

The tooltip reads something like, "Here is how we calculate your custom ratio: ((1 + 5) / 3) + 1 = 3", so we'd style it to be read more clearly.

It would be messy to do it server-side, and the best alternative right now is that I avoid using a th:fragment and supply the logic in each th:data-content field directly in each th:case.

It seems like a small thing, but it's surprisingly been somewhat of a headache since the calculations can sometimes change, and so modifying multiple places is error-prone and a chore. And we do this same sort of thing overall in multiple places.

riddle_me_this
  • 8,575
  • 10
  • 55
  • 80
  • Are you looking for something like `

    `. You'd normally use a message source and message resolver for externalizing strings. Check [docs](http://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#using-thtext-and-externalizing-text)

    – Ranjeet Feb 15 '18 at 07:40
  • Ok, TBH it's a little more than strings (there's some logic too). I'm getting null for the `popoverContent` when I try to use this route - let me take a closer look. – riddle_me_this Feb 15 '18 at 15:03
  • Updated the question to be more clear. The fragment contains logic. Changing the first `$` in `myTemplate.html` to a tilda works to insert `myFragment`, but the logic is not evaluated (processed). – riddle_me_this Feb 15 '18 at 22:46
  • I am not sure if I understand what is not evaluated. Can you provide an example of the logic which you like to be evaluated? – Ranjeet Feb 16 '18 at 05:35
  • In the above example, it would be `[object property]` It seems that `someObject` is evaluated as an empty string (not actually null). But I'm able to print out property values for it on `myTemplate.html`. – riddle_me_this Feb 16 '18 at 06:32
  • 1
    I have the same requirement. I opened https://github.com/thymeleaf/thymeleaf/issues/697 to hopefully get support for this in Thymeleaf. – Wim Deblauwe Jun 19 '18 at 17:09

2 Answers2

2

I don't know of any way to get a fragment as text, but here is one way you could do it with jquery:

<!-- onload -->
<script>
    $(function() {
        $('#dest').attr('data-content', $('#source').html());
    });
</script>

And the html would look something like:

<div id="dest"></div>
<div id="source" style="display: none;" th:insert="~{popover :: popover}" />

After doing rendering and inspecting the html in Chrome's developer tools I can see:

<div id="dest" data-content="<div>Hello, I am a popover</div>"></div>
<div id="source" style="display: none;"><div>Hello, I am a popover</div></div>
Metroids
  • 18,999
  • 4
  • 41
  • 52
1

You can add template using ~{} instead of ${} as specified in the first comment. The reason your someObject is not evaluated IMO is you are not using variable type expression i.e. ${someObject}

Overall you should do something like below:

myFragment.html

<div th:fragment="myContent(someObject)">
    Some popover strings with some business logic
    <span th:text="${someObject.property}">[object property]</span>
</div>

myTemplate.html

<div th:with="popoverContent = ~{myFragment :: myContent(${someObject})}">
    <th:block th:insert="${popoverContent}"></th:block>
</div>
Ranjeet
  • 859
  • 7
  • 19
  • it evaluates with `th:insert="${popoverContent}"`, but not with `th:data-content="${popoverContent}"`. I think the issue is because `th:insert` will actually process the fragment, and this `th:data-content` is implementing like `th:text` and NOT processing. Here's the background: https://github.com/thymeleaf/thymeleaf/issues/451 under the section "Writing fragments as text, not as... fragments" – riddle_me_this Feb 16 '18 at 16:19
  • +1. so close... maybe there's a clever way to get the same thing done. Really, now I would just need to store the result of `th:insert` in a variable for `th:data-content` to display. Appreciate the help. – riddle_me_this Feb 16 '18 at 18:06
  • It's the same use case. I need tooltips with some basic math formulas to be styled. It's in a table and each td has a tooltip with the calculated values. Like, "Here is how we calculate your custom ratio: (1 + 5) / 3 = 2". Feels a bit silly to do it server-side. – riddle_me_this Feb 16 '18 at 18:10
  • Updated the question with my use case – riddle_me_this Feb 16 '18 at 18:25
  • Sorry was on the mobile and somehow missed your comment. Couldn't you just take the text value of the div from java script if you wanted the processed text as a value. For example setting a hidden div via thymeleaf and setting the data-content attribute to that value on load of the page. – Ranjeet Feb 17 '18 at 01:54
  • Can you post an example? – riddle_me_this Feb 17 '18 at 06:17