I am using alternative freemarker syntax(the one with square brackets). It works fine but I am not able to figure out how to use if condition to check if a number is greater than or less than. Following is the syntax I have
[#if ${numberCoupons} <= 1]
[#assign couponsText = 'coupon']
[/#if]
Here "<" symbol fails. Do you know what am I doing wrong here.
Also is there any documentation for list of entire directives that can be used with alternative syntax of freemarker?
You should be able to use any of the following:
[#if (numberCoupons <= 1)]
[#if numberCoupons <= 1]
[#if numberCoupons lte 1]
[#if numberCoupons \lte 1]
I would use the parens.
This is detailed at:
http://freemarker.sourceforge.net/docs/dgui_template_exp.html#dgui_template_exp_comparison
Scroll down just a little to the last paragraph in that section that starts with "There is a little problem"
In this case the error message should complain about the {, not the <. Are you looking at the good place? Anyway, you can't use ${...} there. It should be simply [#if numberCoupons <= 1].
Related
How do I write HQL to determine if results from a field have 1st character as alpha and the following four are numeric. (i.e. - the format of the field is 'F5555', so I need to verify all the results returned from the query for this field are following the correct format.
You can try this:
select REGEXP_EXTRACT( 'd55555' , '^[A-Za-z ]?[0-9]{5}$', 0);
Now, in order to understand, please read this and see the next comments:
^ means the beginning of the string(in this mode we mark the beginning);
[A-Za-z] - means any letter: upper or lower case;
? - means that we want only 1 occurrence of the previous character class;
[0-9] - any digit from 0 to 9;
{5} - means that the previous character class ([0-9]) must appear 5 times exactly (no more, no less);
$ - end of the string;
Hope that you understood.
I'm trying to run the following th:if:
th:if="${camelContext.getRouteStatus( route.id )} &eq; 'Hey'
but I get this error:
org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: "${camelContext.getRouteStatus( route.id )} &neq; 'Hey' " (camel:92)
However, if I try
th:if="${camelContext.getRouteStatus( route.id )} > 41 "
I get a different error, but now indicating that it's able to parse the expression, its just that it cannot compare Strings and numbers:
Cannot execute GREATER THAN from Expression "${camelContext.getRouteStatus( route.id )} > 41". Left is "Started", right is "41" (camel:92)
That's fine, I just wanted to check if I was writing the syntax correctly, and I don't want to compare numbers anyways, I want to compare the RouteStatus string.
Anyways, maybe someone can help me with this problem? Basically I want to do a if-else on the contents of a string, but I can't get this to work..
Cheers
Have you tried this:
th:if="${camelContext.getRouteStatus( route.id )} == 'Hey'"
Maybe it will work like this?
The example on the thymeleaf shows something similar:
Values in expressions can be compared with the >, <, >= and <= symbols, as usual, and also the == and != operators can be used to check equality (or the lack of it). Note that XML establishes that the < and > symbols should not be used in attribute values, and so they should be substituted by < and >.
th:if="${prodStat.count} gt; 1"
th:text="'Execution mode is ' + ( (${execMode} == 'dev')? 'Development' : 'Production')"
Even though textual aliases exist for some of these operators: gt (>), lt (<), ge (>=), le (<=), not (!). Also eq (==), neq/ne (!=), it is sometimes still better to stick with the old fashion operators.
It seems that your expression is malformed, but maybe this a copy paste issue.
Could you try: th:if="${camelContext.getRouteStatus( route.id ) eq 'Hey'} ?
I want to convert a string to number in freemarker. I want to put some conditional check based on the value of the number. ?number doesn't seems to work.
Any suggestions?
Sorry, ?number does work fine. I was not able to compare the converted number with another number.
This didn't work for me:
<#assign num = numString?number>
<#if num > 100>
</#if>
When I enclosed (num > 100) inside the brackets it worked:
<#if (num > 100)>
</#if>
Since the comparison was not working, I was assuming that conversion was not happening.
My bad.
In your code, you use the closed bracket, so freemarker is evaluating
<#if num >
you should instead use
<#if num gt 100>
This is discussed at the end of this documentation on if statements
https://freemarker.apache.org/docs/ref_directive_if.html
The reason this is working for some and not others is because of the parentheses, which is also explained at the bottom of the documentation
I think you can use it like this:string?eval
Use the below code
<#if num?string > 100?string>
</#if>
It worked for me.
I have an associative array and I generate a lot of different things with this array.
The output I need has the form
aa, ab, ac, ad, af, ak, az
So the last entry does not have a comma after it
{section name=i loop=$aColums}
{if $aColums[i].contshow eq 'y'}
{$aColums[i].Name}
{endif}
{/section}
My problem is that I don't know when I've reached the last value, which has the contshow=y attribute. So my next thought was to apply the comma before I write aColums[i].Name. But here I have a similar problem becuase I don't know when I've reached the first value with contshow=y.
Does anyone have a suggestion?
There is an alternative method, using the section's .last property.
{section name=i loop=$aColums}
{if $aColums[i].contshow eq 'y'}
{$aColums[i].Name}{if $smarty.section.i.last eq false}, {/if}
{endif}
{/section}
This adds a ', ' after every output Name - unless it's the last iteration of the {section}. I'm assuming that your $aColums array data doesn't already have commas tacked on.
You also have another option - pregenerate this string in PHP using implode:
$aColumsString = implode(', ', $aColums);
$smarty->assign('aColumsString', $aColumsString);
Then just output to the template as needed. If you require the list with commas more than once, this is probably the more efficient method. If you need it once, it's probably a toss-up effiency-wise.
The general way to deal with this is to write the commas before each element. In this way, the special-case is the first element (which doesn't need a preceding comma) rather than the last, and it's a lot easier to work out whether you're seeing the first element or not. Just set a boolean flag to true initially, then set it to false after matching an entry.
Mind you, Smarty might have a utility function for "joining" the array with a given string (comma, in this case). If such a function exists, using it directly would be the best option.
In Smarty 3, this is much simplified:
{foreach $aColumns AS $aCol}
{$aCol}{if not $aCol#last}, {/if}
{/foreach}
I want to search div id in an html doc with certain pattern.
I want to match this pattern in regex:
foo_([[:digit:]]{1.8})
using xpath. What is the xpath equivalent for the above pattern?
I'm stuck with //div[#id="foo_ and then what? If someone could continue a legal expression for it.
EDIT
Sorry, I think I have to elaborate more. Actually it's not foo_, it's post_message_
Btw, I use mechanize/nokogiri ( ruby )
Here's the snippet :
html_doc = Nokogiri::HTML(open(myfile))
message_div = html_doc.xpath('//div[substring(#id,13) = "post_message_" and substring-after(#id, "post_message_") => 0 and substring-after(#id, "post_message_") <= 99999999]')
Still failed. Error message:
Couldn't evaluate expression '//div[substring(#id,13) = "post_message_" and substring-after(#id, "post_message_") => 0 and substring-after(#id, "post_message_") <= 99999999]' (Nokogiri::XML::XPath::SyntaxError)
How about this (updated):
XPath 1.0:
"//div[substring-before(#id, '_') = 'foo'
and substring-after(#id, '_') >= 0
and substring-after(#id, '_') <= 99999999]"
Edit #2: The OP made a change to the question. The following, even more reduced XPath 1.0 expression works for me:
"//div[substring(#id, 1, 13) = 'post_message_'
and substring(#id, 14) >= 0
and substring(#id, 14) <= 99999999]"
XPath 2.0 has a convenient matches() function:
"//div[matches(#id, '^foo_\d{1,8}$')]"
Apart from the better portability, I would expect the numerical expression (XPath 1.0 style) to perform better than the regex test, though this would only become noticeable when processing large data sets.
Original version of the answer:
"//div[substring-before(#id, '_') = 'foo'
and number(substring-after(#id, '_')) = substring-after(#id, '_')
and number(substring-after(#id, '_')) >= 0
and number(substring-after(#id, '_')) <= 99999999]"
The use of the number() function is unnecessary, because the mathematical comparison operators coerce their arguments to numbers implicitly, any non-numbers will become NaN and the greater than/less than tests will fail.
I also removed the encoding of the angle brackets, since this is an XML requirement, not an XPath requirement.
As already pointed out, in XPath 2.0 it would be good to use its standard regex capabilities with a function like the matches() function.
One possible XPath 1.0 solution:
//div[starts-with(#id, 'post_message_')
and
string-length(#id) = 21
and
translate(substring-after(#id, 'post_message_'),
'0123456789',
''
)
=
''
]
Do note the following:
The use of the standard XPath function starts-with().
The use of the standard XPath function string-length().
The use of the standard XPath function substring-after().
The use of the standard XPath function translate().
Or use xpath function matches(string,pattern).
<xsl:if test="matches(name(.),'foo_')">
Unfortunately it's not regex, but it might be enough unless you have other foo_ tags you don't need, then I Guess you can add a few more "if" checks to cull them out.
Nikkou makes this very easy and readable:
doc.search('div').attr_matches('id', /post_message_\d{1,8}/)