I am using freemarker ..want to find the length of assign variable ..i used size and length function ..but it fails and returns the error ..Please help me in how to find length of the assign variable
Please find the below code i have tried...
Input data --- cusID="a-1242" -- I want to split input data by - and want to store in separate variable through assign function
<#list (it.#CusID[0]!"")?split("-") as c><#if ((c?index) ==0)>
<#assign first>${c}</#assign>
<#assign firstlen = c?size>
</#if>
</#list>
Above code firstlen is used to find the length but it fails to find length
ERROR MESSAGES find below
For "?size" left-hand operand: Expected an extended-hash or sequence
or extended collection, but this has evaluated to a markup_output
(wrapper: f.c.TemplateXMLOutputModel):
As the error message says, first stores XML markup, not just a plain text string. You can't get the length of markup with ?length, as it's not obvious what that means (like if the content of which XML elements matter, what if you have an entity reference, etc.). The reason it's markup is that <#assign first>...</#assign> is not a normal assignment, it's for capturing output, and you are using XML output format. Instead, use normal value assignment: <#assign first = c>. Now first will have the same type as c, string.
Related
Hoping this issue is easy enough to resolve.
I am trying to retrieve a single value from a sequence using FreeMarker via the advanced form PDF functionality in NetSuite.
Here is a snippet of code:
<#assign getOps>
<#list record.item as assembly>
{item: ${assembly.item}, op: ${assembly.operationsequencenumber}}
</#list>
</#assign>
Number of words: ${getOps?word_list?size}
${getOps}
When I print the above, the following is printed:
I want to be able to capture single values from this sequence, using something similar to ${getOps.item} but an error is fired:
For "." left-hand operand: Expected a hash, but this has evaluated to
a string (wrapper: f.t.SimpleScalar):
==> getOps[2] [in template "template" at line 126, column 3]
---- FTL stack trace ("~" means nesting-related):
Failed at: ${getOps[2].item} [in template "template" at line 126, column 1]
Can you identify the issue here?
Any help is appreciated.
Thanks
You are capturing output into a single string there. So it's unstructured, a flat string, therefore you can't traverse it anymore. If you really need to transform the original list, you need to use ?map (see in the FreeMarker Manual). But Netsuite uses a FreeMarker fork, and I'm not sure if they support ?map.
i've the following situation with Freemarker.
When returning to a page in .ftl i send from Java a parameter to the url, similar to "AAA% BBB#DDD.COM", in Java it is ok.
When looking at the Url it does instead Write : "AAA%25+BBB#DDD.COM" And then with the following code:
<#if myCase??>
value = ${user}
</#if>
It does write in my html field "AAA%" but not the remaining.
How can i try to solve this issue?
Thanks in advance.
EDIT: After further investigations i do see the code i put before does write this on the Html:
value="AAA%" BBB#CCC.com=""
EDIT2: Let'see if i can give you more informations, first of, here's the relevant Java code :
Map mapping = new HashMap();
if(user != null && !user.isEmpty()){
mapping.put("user",user); //EG: AAA% BBB#DDD.COM (Checked in debug)
}
I have an URL similar to : mysite.xx?user=AAA%25+BBB#DDD.COM so the user it's attached as query param of the url.
I do need to reuse the "user" param to repopulate the Form field relative to the username, this is not a valid email i know, but an alias system already installed by the customer does the aliasing system this way.
What could be the cause of the problem
Given your template:
<#if myCase??>
value = ${user}
</#if>
Output written by Freemarker in output-mode HTML results in following:
value = AAA% BBB#DDD.COM
Freemarker does not understand that (from your context) the value of user should be an attribute-value (assignment). Instead it treats the contents of string user as HTML itself (this could be complete HTML-source as input-field, single tags, etc.). It simply pastes the contents of the model at the position in your template where you have set the variable-interpolation ${user}.
The Freemarker-result is no valid HTML (attribute-value pair), because each attribute should adhere some naming-conventions (i.e. no special-characters). When the attribute has a value, it is followed by an equal-sign and this followed by the value enclosed in double-quotes.
So most browsers convert your result into a valid HTML attribute - actually two attributes: value="AAA%" and BBB#CCC.com="". Opened the output-HTML in Firefox, you will see this in Inspector (NOT IN the raw source-view):
<input type="text" value="AAA%" bbb#ddd.com="">
What is not the cause
FreeMarker is auto-escaping (escpecially when in OutputMode HTML) when it writes the final HTML.
#ddekany Thanks for your comment ! It made me reproduce and discover the real cause.
URL encoding/decoding
In Java you could even encode the string variable user. So it converts % (i.e. percent-sign followed by space) into %25+ which is valid to be used inside an URL.
Run this java snippet online on IDEONE to the effects of URL-encoding and URL-decoding.
Solutions
Use either of these solutions to get desired output by fixing the HTML-attribute value-assignment in your template:
(1) use double-quotes:
<#if myCase??>
value="${user}"
</#if>
(2) use some built-ins to transform the plain string-output:
Use some of FreeMarker's built-ins for strings. In your case you could append ?url to the variable-name and use double-quotes around your variable-interpolation within your template, e.g.:
<#if myCase??>
href="mailto:${user?url}"
</#if>
Caution: validate URL or email-address (even parts of it) as early as possible
BBB#DDD.COM is a valid email-address. But % and whitespaces are not allowed inside an email-address.
On the other side # is typically not part of an URL, except as part inside a query-param value. But your user (URL) does not start with http:// etc.
So depending on the use-case/purpose of your (so called URL) user with value AAA% BBB#DDD.COM it could finally represent part of an URL or email-address.
In your special case, said:
populate the form field relative to the username. Model-variable user does not contain a valid email-address. It is used in conjunction with an alias system already installed by the customer. So aliasing will work this way.
Let's suppose the end-user which does later edit the form-field is responsible of making it valid (or a script does this validation).
Anyway bear in mind that an internet-address (like URL/email) needs some validation:
either before written to the final HTML (using Java or Freemarker)
or after being further processed inside your web-page (using JavaScript).
Otherwise it could possibly not yield the desired effect.
See also
Related questions:
Is there any way to url decode variable on Freemarker?
Java URL encoding of query string parameters
So simple question, which I simply cannot solve: how to reverse a string using Freemarker?
I have tried following:
<#assign reversed = mystring?reverse() />
But strings does not have reverse method... I've also tried:
<#assign reversed = mystring?split("")?reverse()?join("") />
But apparently split("") is not valid freemarker syntax. Is there a way to do this?
There's no function built in for reversing a string. Out of curiosity, what's the use case?
As of the trick with split, it's a valid syntax, only as the error message says, you aren't allowed to split with an empty string. But, you are allowed split with an empty regular expression:
<#assign reversed = myString?split("", "r")?reverse?join("")>
But this is a hack of course... Generally, you are supposed to expose the extra functions you need through TemplateMethodModelEx objects, or through Java beans, or even static utility classes.
How can I use parameters in format descriptor in Fortran90?
I want to make a matrix, say square(n*n), but I want to make it general. So, I declared a parameter like this: integer,parameter::n=3 (say n is 3 here)
Then after inputting the elements of the matrix in a do/implied do loop, I want to write it with the format function as follows:
format(ni5)
But it gives the error: Unexpected element 'N' in format string
Any simple way to solve this??
Little-known fact: format specifiers can be constructed at runtime as a character string. This means that you can programmatically define the format specifier and pass it to the write statement.
CHARACTER(len=30) fm
INTEGER :: i
i = 3
WRITE(fm,'(a,i1,a)')"(",i,"i5)"
WRITE(*,fm)1,2,3
In the above, we are generating the actual format specifier with the number of integers that you need to print for the given situation (i), then using that string as the format of the second write statement.
I very rarely see people use this trick, and its possible that it is not defined in the actual standard, but it does work in gfortran.
I have an XML file to parse in which the element tags are of the form:
<mensa-1>
..
</mensa-1>
<mensa-2>
..
</mensa-2>
Is it possible to parse such elements via Xpath when the element names differ via a number at the end?
The following XPath expression returns all the elements whose names start with "mensa-":
//*[starts-with(name(),'mensa-')]