Having a problem with freemarker output...
[#assign optionsHTML = ""]
[#list data as item]
[#assign optionsHTML = optionsHTML + '<option value="' + item.value +'>'+ item.label + '</option>' /]
[/#list]
so, if I do
<select>
${iptionsHTML}
</select>
the output from otions get html entities instead of actual html.... so
<option value=" .....
even if I do
[#assign optionsHTML = ""]
[#list data as item]
[#noescape]
[#assign optionsHTML = optionsHTML + '<option value="' + item.value +'>'+ item.label + '</option>' /]
[/#noescape]
[/#list]
tried even
<select>
${iptionsHTML?html}
</select>
but's even worse :(
Putting #noescape around #assign has no effect. Automatic escaping only applies to ${...}-s that are embedded directly into the static text (the HTML). So there's no escaping to disable inside that #assign.
?html is used to escape a string "manually". Like in your example you could write optionsHTML = optionsHTML + '<option value="${item.value?html}>${item.label?html}</option>', because you know that the value will be output non-auto-escaped later, and the ${...}-s inside the string literal aren't escaped automatically.
However, the best would be if you can organize your code so that things that generate HTML don't construct the HTML inside variables and then print the variable, but print the HTML directly into the output. That's what FTL is designed for.
So after trying stuff, I don't know what I've done wrong before, but clean, this way is working
[#assign optionsHTML = ""]
[#list data as item]
[#assign optionsHTML = optionsHTML + '<option value="' + item.value +'>'+ item.label + '</option>' /]
[/#list]
<select>
[#noescape]
${optionsHTML}
[/#noescape]
</select>
Like ddekany said, write something like this:
<select>
[#list data as item]
<option value="${item.value}">${item.label}</option>
[/#list]
</select>
I faced same problem in string with special chars.
In this example I have checknumber = "6547&6548"
which caused problem before using this #escape
the best and simple way to handle this as following code
<#escape x as x?html>${deposit.checkNumber}</#escape>
Related
When using the Str::between function from Laravel 8, it jumps over the first occurrence of the 'TO' variable. Is there something wrong I'm doing, or is it broken?
<span class="website-title">Name</span> All Rights Reserved.</p>';
$slice = Str::between($string, '<span class="current-year">', '</span>');
Returns '2022 Name' when it should only return '2022.'
I think it finds the last occurrence of the last parameter in the between method. To solve this, you could do something like
$slice = Str::between($string,
'<span class="current-year">',
'</span> <span class="website-title">');
I am currently working on some contracts and the my freemarker macros are working fine. But now I have to use the same macro twice and I'm getting the report: Expected a hash, but this evaluated to a number
It seems the same macro cant do the same thing twice, the macro I am currently using is:
[#macro TeilbetragProzent]
[#assign gesamt = ((verkaufsauftrag.beteiligungGesamt)!"") /]
[#assign nominale = ((nominale.betrag)!"")/]
[#if (gesamt?string)!=""]
[#assign prozent = ((nominale/gesamt)*100)/]
${(prozent)?string["0.##"]}
[#else]100
[/#if]
[/#macro]
I tried to change it a little:
[#macro TeilbetragProzent2]
[#assign gesamt2 = ((verkaufsauftrag.beteiligungGesamt)!"") /]
[#assign nominale2 = ((nominale2.betrag2)!"")/]
[#if (gesamt2?string)!=""]
[#assign prozent2 = ((nominale2/gesamt2)*100)/]
${(prozent2)?string["0.##"]}
[#else]100
[/#if]
[/#macro]
Still not working... Am i missing something?
Rather than an issue in the macro, I believe your issue lies in the second assign directive: [#assign nominale = ((nominale.betrag)!"")/]. You are trying to assign the value of the node betrag in the hash variable nominale (likely number, based on the error message) to a variable of the same name, nominale. If you change the variable name to something, I think you will have success.
[#macro TeilbetragProzent]
[#assign gesamt = ((verkaufsauftrag.beteiligungGesamt)!"") /]
[#assign nom = ((nominale.betrag)!"")/]
[#if (gesamt?string)!=""]
[#assign prozent = ((nom/gesamt)*100)/]
${(prozent)?string["0.##"]}
[#else]100
[/#if]
[/#macro]
After a ajax call the response received is a JSON String. I am able to list the data but was wondering if is it feasible to use spring:eval inside jQuery $.each? If someone has an example I would really appreciate. The line in question ends with "??"
Response received is JSON:
{"listOfData":[{"id":"XX","someValue":"James Bond"}]}
The rest of the code:
var obj = jQuery.parseJSON(JSON_String)
$.each(obj.listOfData, function (index, data) {
"<tr>" +
"<td style=\"padding: 3px;\">" +
(index + 1) +
"</td>" +
"<td style=\"padding: 3px;\">" +
<spring:eval expression="data.someValue" /> ??
"</td>" +
"</tr>" +
}
Depending on where this code is,
<td style=\"padding: 3px;\"><spring:eval expression=\"data.someValue\" /></td>
might work. If it doesn't, you could do the "eval" part server side and return ready-to-use datas from your JSON code.
If you are here then may be you are not on the right track. Try this solution. Works like a charm ... Solution 1 and similar solution Solution 2.
how would I concatenate a string so It can be rendered in HTML properly?
<c:set var="filter" value="${view}"/>
For example, I do something like this in JavaScript:
var view;
var sors;
var filterCriteria = view + "<br>";
if (sors != null)
{
filterCriteria = filter + "SORs: " + sors + ", ";
}
Then the answer is
${view} <br> whatever
or
<c:out value="${view}"> <br> whatever
The first one doesn't escape the HTML special chars in view (<, >, &, ', "), whereas the second one does (and transforms them to <, >, &, etc.)
If you want to output <br> as html tag you could use c:out as <c:out escapeXml="false" value="${view} <br>"/>
This is a problem I have run into before and I have yet to find an elegant solution, so I thought I would ask for SO's help.
I am iterating through an array and printing off some information from that array and having trouble figuring out how to print my start and end <div> tags. Below is an example table and the desired output along with a basic implementation of my current algorithm. I am hoping that somebody can point me to a better algorithm for printing the data. I'm doing it in PHP, but a generic algorithm would be wonderful.
Thanks very much!
Table: (spacing added for clarity)
Choice ID Choice Body Question ID Question Body
---------------------------------------------------------------------
1 Yes, very much 1 Do you like sandwiches?
2 Somewhat 1 Do you like sandwiches?
3 Not at all 1 Do you like sandwiches?
4 I hate them 1 Do you like sandwiches?
5 Sure, why not 2 Do you like apples?
6 Yesh, I guess 2 Do you like apples?
7 What are those 2 Do you like apples?
8 Yes, very much 3 Do you like chips?
9 Not at all 3 Do you like chips?
Desired Output:
<div class='question' id='1'>
<p>Do you like sandwiches?</p>
<div class='choices'>
<span class='choice'>Yes, very much</span>
<span class='choice'>Somewhat</span>
<span class='choice'>Not at all</span>
<span class='choice'>I hate them</span>
</div>
</div>
<div class='question' id='2'>
<p>Do you like apples?</p>
<div class='choices'>
<span class='choice'>Sure, why not</span>
<span class='choice'>Yeah, I guess</span>
<span class='choice'>What are those</span>
</div>
</div>
<div class='question' id='3'>
<p>Do you like chips?</p>
<div class='choices'>
<span class='choice'>Yes, very much</span>
<span class='choice'>Not at all</span>
</div>
</div>
Basic Algorithm I'm Currently Using:
$last_id = null;
while ($choice = pg_fetch_array($choices)) {
if ($last_id != $choice['id']) {
if ($last_id != null) {
echo "</div>";
}
echo "<div id='$choice[id]'>";
}
// Print choice info
$last_id = $choice['id'];
}
if ($last_id != null) {
echo "</div>";
}
Note: The reason I'm using this way is for optimization purposes. This requires only one database query, and there are going to be a lot of results. I don't want to have to do a query for each question to get it's choices. I know how to do that, and it is easier, but not very efficient or fast.
Edit 1: Fixed code, the algorithm now works, but still isn't pretty. For the commenter: pg_fetch_array() is a PostgreSQL function that basically creates an associative array. Very similar to an object. Allows you to just ask for the $choice['id'] or $choice['body'].
Grouping items by similar values can hardly be called an algorithm. It's more of a coding pattern if anything else.
A good way to code is to separate the mechanism from the intent. In this case the mechanism is how to keep track of the key values to find the grouping boundaries and the intent is to output HTML for each sequential group.
Python for instance has a library function called groupby to do exactly this. So in Python the code would look something like this (ignoring the fact that one would use a templating library for this):
from itertools import groupby
def question_from_row(row):
return dict(id=row['question_id'], body=row['question_body'])
for question, choices in groupby(questions, key=question_from_row):
print('<div class="question" id="%s">' % question['id'])
print(' <p>%s</p>\n' % question['body'])
print(' <div class="choices">')
for choice in choices:
print('<span class="choice">%s</span>' % choice['choice_body'])
print(' </div>')
print('</div>')
PHP to my knowledge doesn't have anything like that built in, but a naive implementation is pretty easy:
function array_groupby($input, $keyfunc) {
$output = array();
$last_key = null;
$current = null;
foreach ($input as $item) {
$item_key = $keyfunc($item);
if ($last_key === null || $item_key != $last_key) {
if ($current !== null) {
$output[] = $current;
}
$last_key = $item_key;
$current = array();
}
$current[] = $item;
}
if ($current !== null) {
$output[] = $current;
}
return $output;
}
This would be typical library code that you include in. The code that deals with the output then becomes rather trivial. Completely isolated from how the grouping is done. For instance you could change array_groupby to return an object that implements the Iterator interface and only lazily fetches from the input iterable.
$questions = array_groupby(pg_fetch_array($choices),
function($choice) { return $choice['id']; });
foreach ($questions as $choices) {
$question = $choices[0];
echo '<div class="question" id="'.$question['id'].'">';
echo '<p>'.$question['body'].'</p>';
echo '<div class="choices">';
foreach ($choices as $choice) {
echo '<span class="choice">'.$choice['choice_body'].'</span>';
}
echo '</div>';
echo '</div>';
}
This example is using the PHP 5.3 closures feature. On older versions specifying the function to extract the grouping key would be slightly uglier, perhaps calling for an object oriented approach.
You should print the closing </div> at the beginning of the loop, if the freshly read id is different from last one (and the last one is not null).
Additionally, after the loop (again, if last id is not null, which would mean that there were no groups at all) you need to close the last group.
Been a while since I've done any PHP but I'd try something like this...
// print leading div for very first in array
echo "<div>";
$last_question = null;
while ($choice = pg_fetch_array($choices)) {
// print choice info
echo "<span ...>";
if($last_question != $choice['question_id'])
{
// print trailing div for last one
echo "</div>";
// print leading div for next one
echo "<div>";
}
// set last question
$last_question = $choice['question_id'];
}
// print trailing div for very last in array
echo "</div>";
Might need improving to make sure it doesn't print an extra div at the end.