How to set variables in a thymeleaf fragment? - thymeleaf

I understand Thymeleaf is made for rendering the views however, I just wanted to know if there is any way to set a variable may be in request scope in a Thymeleaf fragment?
I have a very large conditional expression that I have to repeat a lot of times across the application so it will be really helpful if I can set a variable in main layout then reuse it in all other child fragments.
I am aware of using a Spring interceptor and setting the variable in model but I prefer not to.
Please advise.
Thanks
Prash

In the fragment template, define fragment with parameters:
<div th:fragment=”myfragment(myvariable)”>
<p th:text=”${myvariable}”></p>
</div>
and in layout template, include fragment with that variable specified:
<div th:include=”template :: myfragment(${variable})”></div>
Then variable is passed to the fragment template.

If you need the result of your expression only in the fragments you could use
th:with="var=${verylargeexpression}"
This creates a local variable which you can use everywhere within the dom element you defined it, including fragments.

<div th:include="'path/your/file/' + ${variable}"></div>
The code above can use variables that you can choose to build the file path

If you are using Spring MVC along with Thymeleaf, then you should be able to access any bean within thymeleaf template.
Just use expressions like this in global template ...
<span th:text="${beans.myBean.verylargeexpression}"></span>

Related

Reflection and thymeleaf

I use spring boot and thymeleaf. I have many entity and I need to create crud ui. All ui will be similar Is it possible to use reflection to reduce ui to generate?
I would like to loop on the fields and get value in the thymeleaf template
In these days I have been working on an issue very similar to yours.
I have discovered that Thymeleaf has this thing called preprocessing which allows you to have nested expression, so something like this works:
<p th:text="${__${'myObj.myField'}__}"></p>
In this situation, the expression __${'myObj.myField'}__ is evaluated first: after this preprocessing, the expression that will be evaluated by the <p> tag will become:
<p th:text="${myObj.myField}"></p>
Which is the desidered result. Note that, in the preprocessed expression, we are passing the field as a string: therefore, it should be totally possible to create a fragments with a th:each in it which accepts a list of strings in which each string is a field. This list could either be injected directly in the model through Java or could be statically declared in the Thymeleaf's markup. An example of such fragment could be:
<div th:fragment = "show-details">
<tr th:each = "field : ${fieldsToPrint}">
<td th:text = "${__${myObj + '.' + field}__}"></td>
</tr>
</div>
Which could, for example, be used like this:
<div th:replace = "myfragments :: show-details(fieldsToPrint = ${ {'name', 'surname'} }, myObj = ${objFromModel})"></div>
The list of fields could either be generate manually or through Java reflection.
This procedure still involves some work, but way less than creating by hand all the views, especially if you can show all the entities with the same show-details fragments. I have not got around to it yet, but it should be possible to use a similar pattern also for editing such entities.

Angular not finding variable made by ng-repeat

I am using an AngularDart component in my webpage with the #Component. I can access variables inside the class by using the standard angular expressions in the html by using ng-model and {{}}. However when implementing a standard looping procedure:
<div ng-repeat="(x, y) in example_dictionary" ng-if="example_dictionary!=null">
{{x}}
</div>
This snippet gives me the strange error Class '~~~' has no instance getter 'x' (Class name snipped). The error is not wrong per-say. The class really does not contain any getter of x, but it shouldn't need to because the ng-repeat method is setting it and maintaining it.
For added entertainment, I replaced the {{x}} section with a static string I am looping and behold the loop command does in fact loop through the dictionary the proper amount. So the ng-repeat is not causing any problems with either looping or setting both of the non-pre-existing x and y variables.
The question: Why can't I access x and how can I access x?
That should work, but have you tried?
<div ng-repeat="entry in example_dictionary">
{{entry.x}}
</div>
After reducing the problem to a really simple size, I found out that removing the ng-if section of the div fixed the problem. How and why that even was a problem is beyond me. I now segregated the action of ng-if and ng-repeat into separate divs. I am not particularly happy with my findings, but it works.

How to render two attributes if variable is set?

I'm very new to ruby templating and am trying to figure ut a best-practice for rendering attributes.
I get my values from a yaml file, for example:
about:
itemtype: SoftwareApplication
I then output them using the function t:
t(about.itemtype)
(about happens to be the page_class for the page)
What I want to do is output two attributes:
<div itemscope itemtype="http://schema.org/SoftwareApplication">
If the item type is set. Otherwise, I don't want to output anything.
<div>
I understand I could do an inline if-statement, but is there a cleaner way of doing this?
I don't know about Middleman, but you can use a helper method to decorate the output of your t(about.itemtype) with additional content in Rails.

Is there a Grails equivalent for the jsp form tags?

I have an (as yet) simple Spring 3 MVC web-app using JSP as the view technology. I am considering rewriting it in Grails before I get too far along.
One thing I like about Spring is the "form" tags provided in the spring-form.tld tag-library. Given a model property "myFormModel" with the "myProperty" property, this allows me to write something like: -
<form:form commandName="myFormModel">
<form:input path="myProperty" cssErrorClass="error"/>
The key here is that the form:input tag automatically does all the binding to the property in the command object, so generating (roughly) in HTML: -
<form>
<input type="text" name="myProperty" value="xyz"/>
Spring MVC will bind the form parameters to the class and pass the object to the controller. Less to go wrong.
(Please excuse the JSP and HTML, it's indicative, possibly slightly incorrect)
As I understand the GSP form tags: -
<g:form name="myForm" url="[controller:'myController', action:'foo']">
<g:textField value="${myFormModel.myProperty}" class="${...blah to select error}"/>
I cannot specify a "path" attribute: I must manually generate the name. When the path becomes complex (say a property of a item from a list), this can become hairy and noisy.
I cannot automatically specify both "normal" and "error" CSS classes: I must put EL into the <input> class attribute. Messy!
I must admit I am surprised that GSP is (what I consider) behind Spring, I thought it was all about making the obvious things simple and the hard things possible. Easy-to-read/implement forms would seem a no-brainer.
So, my questions: -
am I missing something?
should I (and can I) use the spring-form.tld in my GSP?
It makes me wonder what other gotcha's I will run into...
The beanFields plugin does everything the Spring form tags do and more. It makes working with forms about as concise as possible.

Better way to implement an Html Helper method?

I created an html helper
Html.BreadCrumb(IDictionary<string, string> crumbs)
Where the first string is the label and the second string is the URL.
The helper creates the html required (an unordered list, some classes for first element, current element, last element, dead element and separators etc)
All working nice, but I do this by creating a stringbuilder, pumping all the html in it and returning the stringbuilder's content as a string.
I figure in this example it doesn't matter all that much, but what if an Html helper is churning out a big load of html? Isn't there a way to push it to Response.Write instead of a stringbuilder?
Or any other issues/improvements you have?
BTW we have a naming pattern in ASP.NET MVC for the various rendering techniques.
Helpers that return a string of what they are should be named what they are. For example, Url.Action() and Html.TextBox() return those exact items. Thus, these helpers should be used with the <%= %> syntax.
Helpers that render directly to the output stream should start with Render. For example, Html.RenderPartial(). These are used with the <% %> syntax.
Helpers that use the IDisposable pattern should be named with Begin/End. For example, Html.BeginForm() and Html.EndForm(). These should also be used with the <% %> syntax.
Thanks,
Eilon
It certainly is possible to use Response.Write instead of returning a string; see the source for System.Web.Mvc.Ajax.Form (in AjaxExtensions.cs) in the MVC source for an example.
You then call the helper with <% instead of <%=.
Will it be any faster? I doubt it, but it's easy to test.
I don't think you will have any performance problems as long as the size of the HTML pages you produce is reasonable. And when you really start to create pages of megabytes in size, then you should ask yourself, why are you creating such huge HTML files?

Resources