I am new to thymeleaf and I don't understand the difference between th:field="${something}" and th:field="*{something}". When to use * and when to use $?
Quoting the thymeleaf documentation
Variable expressions not only can be written in ${...} expressions,
but also in *{...} ones.
There is an important difference, though: the asterisk syntax
evaluates expressions on selected objects rather than on the whole
context variables map. This is: as long as there is no selected
object, the dollar and the asterisk syntaxes do exactly the same.
From here in the 4.3 Expressions on selections (asterisk syntax) section.
Technically the difference is that if you have selected an Object
like so th:object="${session.user}
then you can use the * for the properties of the user object
like so th:text="*{lastName}"
If you haven't selected an object they are the same.
Related
I'm writing a DOM selectors to xpath converter and it just so happens that it would suit me very much if I could concatenate multiple predicates like this:
//div[#id][#class]
instead of like this:
//div[#id and #class]
Although a cursory test appears to suggest they behave the same, I'm not entirely sure they will under all circumstances. Will they?
Using multiple predicates is 100% equivalent to using the and operator provided that neither predicate is positional. A positional predicate is one whose value is numeric, or that explicitly uses position() or last(). For example, *[#x][1] is not the same as *[1][#x].
From https://stackoverflow.com/a/10820494/1764881, I know that the standard way of doing it seems to be:
var="SAMPLE$i"
echo ${!var}
But, I can't seem to do any of these following forms. They all failed:
echo ${!SAMPLE$i}
echo ${!"SAMPLE$i"}
I read the bash man page, but I still couldn't understand. Is it true that the first form is the only form accepted?
Yes. The underlying logic is that all parameter expansions take a single, literal word as the name of the parameter to expand, and any additional operator does something to the result. ! is no exception; var is expanded as usual, but the result is expanded again.
(As an aside, even arrays follow this rule. It might seem that something like ${array[2]%foo} applies two operators to array, but really array[2] is treated as the name of a single parameter. There is a little difference, as the index is allowed to be an arbitrary arithmetic expression rather than a literal number.)
(And for completeness, I should mention the actual exceptions, ${!prefix*} and ${!name[*]}, which confusingly use the same operator ! for querying variables themselves. The first lists variable names starting with the same prefix; the second lists the keys of the named array.)
We use Freemarker 2.3.20 and came across a strange behavior, when using the default operator together with string escaping like this:
${picture.#author[0]!""?js_string}
in this case, quotes in the authors value are not escaped if !"" is present.
We need to check first for the value and can't use the default op:
<#if picture.#author[0]??>${picture.#author[0]?js_string}</#if>
this is quite ugly and blown up code.
Is this a bug or a feature?
It's because of the operator precedences. ${picture.#author[0]!""?js_string} means ${picture.#author[0]!(""?js_string)}. What you want is ${(picture.#author[0]!"")?js_string}.
In the TFS DefaultTemplate.11.1.xaml build process template, there are many attributes whose entire values are surrounded by square braces [], so a tag has the form
<tagName attributeName="[attributeValue]">
where tagName, attributeName, and attributeValue are text strings.
I cannot find any documentation for this value syntax. From the template, it appears to cause the XAML processor to evaluate the text as an expression. Is this explained somewhere?
I believe that square braces in XAML do indeed denote a value expression. I am still uncertain exactly how this denotation is supported or enforced. Possibilities include:
-XAML syntax; I think this is the most likely answer.
-A Converter implementation somewhere which detects during parsing when a value begins and ends with square braces, and evaluates the content within during processing; I think this is the second-most likely answer.
-It's possible that the square braces are actually not special characters and are valid as part of an identifier, the evaluation of the value is performed via some other as yet unknown mechanism, and the square braces are present by convention only, perhaps to indicate that the value is not a literal but an expression to be evaluated. I think this is an unlikely answer.
Supporting research:
"Expressions created in the WF designer are serialized using square brackets, which is shorthand for VisualBasicValue or VisualBasicReference"
"Hand edit the workflow XAML file to change value of the Number property to [1+2] (the square brackets denote an expression)"
"Expressions are literal values or Visual Basic code bound to arguments or properties. They contain value elements (e.g. variables, constants, literals, properties) that are combined with operations to yield a new value. Expressions are written using VB.NET syntax even if the application is in a program using C#."
"Workflows produced by designer are saved in XAML, where expressions appear enclosed in square brackets."
The last quote above is the only official documentation I have found that in any way mentions the square brace surrounding expressions as XAML attribute values, and this still does not clarify whether the designer does this merely arbitrarily and without invoking any special syntax, or if expressions must appear enclosed in square brackets according to the official XAML specification and as such the designer must do this.
It is a property that is set before in your XAML like this for example: <x:Property Name="BuildNumberFormat" Type="InArgument(x:String)" /> If you open the build process templates in VS 2012 you are able to change/customize them using Workflow.
Say I have a field on a datawindow that is the value of a database column ("Insert > Column). It has conditions in which it needs to be protected (Properties>General>Protect).
I want to have the field background grey when it's protect. At the moment, the only way I can work out how to do this is to copy the protect conditional, no matter how complex, substituting the 1 (protect) and 0 (not protect) for colour values.
Is there some sort of syntax I can use in the Expression field for the column's background colour that references the protect value of the column? I tried
if (column.protect=1, Grey, White)
but it returns errorous saying it expects a TRUE/FALSE condition.
Is what I'm after impossible, or is it just a matter of getting the right syntax.
Cheers.
Wow. You like complex, layered questions.
The first problem is accessing the value, which isn't done as directly as you described. As a matter of fact, you use a Describe() to get the value. The only problem with that is that it comes back as a string in the following format, with quotes around (note that we're using standard PowerScript string notation where ~t is a tab)
"<DefaultValue>~t<Expression>"
You want the expression, so you'll have to parse it out, dropping the quotes as well.
Once you've got the expression, you'll need to evaluate it for the given row. That can be done with another Describe () call, particularly:
Describe ("Evaluate('<expression>', <rownum>)")
The row number that an expression is being evaluated on can be had with the GetRow() function.
This may sound like it needs PowerScript and some interim value storage, but as long as you're willing to make redundant function calls to get a given value more than once, you can do this in an expression, something like (for an example column b):
if (Describe ("Evaluate (~"" + Mid (Describe ("b.protect"),
Pos (Describe ("b.protect"), "~t")+1,
Len (Describe ("b.protect")) - Pos (Describe ("b.protect"), "~t") - 1)
+ "~", " + String (GetRow()) + ")")='1',
rgb(128, 128, 128),
rgb(255,255,255))
This looks complex, but if you put the Mid() expression in a compute field so you can see the result, you'll see that simply parses out the Protect expression and puts it into the Describe (Evaluate()) syntax described above.
I have put one cheat into my code for simplicity. I used the knowledge that I only had single quotes in my Protect expression, and chose to put the Evaluate() expression string in double quotes. If I was trying to do this generically for any column, and couldn't assume an absence of double quotes in my Protect expression, I'd have use a global function to do a replace of any double quotes in the Protect expression with escaped quotes (~"), which I believe in your code would look like a triple tilde and a quote. Then again, if I had to make a global function call (note that global function calls in expressions can have a significant performance impact if there are a lot of rows), I'd just pass it the Describe ("column.protect") and GetRow() and build the entire expression in PowerScript, which would be easier to understand and maintain.
Good luck,
Terry.