So I am having trouble getting the variable values to be shown in an email template. The 3rd party email templating provider is Postmark and it uses Mustache. My template is set up like this (I have ommitted some of the irrelevant html to keep things shorter):
{{#discount_group.delivery_fee}}
<tr>
<td width="30%" class="purchase_footer" valign="middle">
<p class="purchase_total">{{delivery_fee}}</p>
</td>
</tr>
{{/discount_group.delivery_fee}}
{{#discount_group.discount}}
<tr>
<td width="30%" class="purchase_footer" valign="middle">
<p class="purchase_total">{{discount}}</p>
</td>
</tr>
<tr>
<td width="30%" class="purchase_footer" valign="middle">
<p class="purchase_total_bold">{{grandtotal}}</p>
</td>
</tr>
{{/discount_group.discount}}
And my json payload looks like this:
"discount_group": {
"delivery_fee":"delivery_fee_Value",
"discount": "discount_Value",
"grandtotal": "grandtotal_Value"
}
But when I send out the email, the sections render properly but the variable values are blank (red box):
If I remove "delivery_fee" from the json payload, the section is not rendered as expected but the values are sill missing:
I have also tried {{discount_group.delivery_fee}} and {discount_group.discount}} etc but that still had the missing values.
What am I doing wrong?
Thanks in advance
So I figured it out. I'm not sure why it has to be this way but it does. My problem was in the payload. The payload should be formatted like this:
"discount_group": {
"delivery_fee":{
"delivery_fee":"delivery_fee_Value"
},
"discount": {
"discount":"discount_Value",
"grandtotal": "grandtotal_Value"
}
}
When you wrap a block of code in mustache, what you're doing is stepping into that object in your data in an effort to make your code more readable. Postmarks documentation calls it 'Scoping'. You can read up on here!
Therefore, by starting blocks with, for example, {{#discount_group.delivery_fee}}, you are already at delivery_fee and calling it again will return nothing since it doesn't exist.
With how your data was originally structured, you had everything you needed nested in discount_group, so you didn't need to nest further in your brackets. I know you have found a resolve, but in the future, instead of changing your data to match your code, you could consider instead update your code to be as follows:
{{#discount_group}}
<tr>
<td width="30%" class="purchase_footer" valign="middle">
<p class="purchase_total">{{delivery_fee}}</p>
</td>
</tr>
<tr>
<td width="30%" class="purchase_footer" valign="middle">
<p class="purchase_total">{{discount}}</p>
</td>
</tr>
<tr>
<td width="30%" class="purchase_footer" valign="middle">
<p class="purchase_total_bold">{{grandtotal}}</p>
</td>
</tr>
{{/discount_group}}
I have this block in thymeleaf where I'm trying to show the name of a protocolVersion isntead of the id. I only have the Id so I pass the list of protocolVersion (protocolVersions) and I'm iterating over it to show the one that matches the id (1007 is just a test).
<th:block th:each="item: ${protocolVersions}">
<tr th:if="${item.id == 1007}">
<td th:text="${item.name}"></td>
</tr>
</th:block>
I'm getting the error message:
Exception evaluating SpringEL expression: "item.id == 1007"
I've also tried something like this, as I've found it in one of the questions here:
<td th:if="${protocolVersions.?[id == '${excelMongoDoc.protocolVersionId}']}"
th:text="${protocolVersions[id == '${excelMongoDoc.protocolVersionId}'].name}">
</td>
But this is not working either. Can anyone help please?
Thanks
The expression is simply: ${protocolVersions.^[id==1007].name}. So you could do this in your table:
<tr>
<td th:text="${protocolVersions.^[id==1007].name}"></td>
</tr>
If you want to check against a variable, rather than hardcoding 1007 something like this:
<th:block th:with="check=1007">
<td th:text="${protocolVersions.^[id==#root.check].name}"></td>
</th:block>
I created xquery function which returns a table:
declare function local:table($collection as xs:string*, $interface as xs:string?, $date as xs:string?) as node() {
<table border="1">
<thead>
<tr>
<th>Inteface Name</th>
<th>Test Date</th>
<th>Test Result</th>
<th>Report Link</th>
</tr>
</thead>
<tbody>
{
for $child in xmldb:get-child-resources($collection)
let $doc := fn:doc(fn:concat($collection, '/', $child))
where (fn:ends-with($child, '.xml'))
and (($doc//*:interfaceName/text() eq $interface) or empty($interface))
and (($doc//*:reportDate/text() eq $date) or empty($date))
order by $doc//*:reportDate/text() descending
return
<tr>
<td>
{$doc//*:interfaceName/text()}
</td>
<td>
{$doc//*:reportDate/text()}
</td>
<td>
{$doc//*:testResult/text()}
</td>
<td>
<li>
<!--{$child} -->
{$child}
</li>
</td>
</tr>
}
</tbody>
</table>
I also added a few input controls on the page. One of them looks like:
<InterfaceName constraint="true" readonly="false" required="false" relevant="true">
<value>test</value>
</InterfaceName>
<xf:bind nodeset="InterfaceName">
<xf:bind nodeset="value" type="string"/>
<xf:input id="InterfaceName" ref="InterfaceName/value" incremental="true">
<xf:label></xf:label>
<xf:hint>xxxxxYYYZZZ</xf:hint>
<xf:help>Enter interface name</xf:help>
<xf:alert>Enter interface name</xf:alert>
</xf:input>
I also added a button to the webpage:
<trigger1 constraint="true" readonly="false" required="false" relevant="true">
<value></value>
</trigger1>
<xf:submission id="s-send"
replace="instance"
resource="echo:test"
method="get">
</xf:submission>
<div>
<xf:trigger id="trigger1" ref="trigger1/value" incremental="true">
<xf:label>Filter output</xf:label>
<xf:hint>a Hint for this control</xf:hint>
<xf:help>help for trigger1</xf:help>
<xf:send submission="s-send"/>
</xf:trigger>
</div>
On this button click I need to somehow pass parameters form those input controls to xquery function and return the table to the webpage. Entire webpage is of type xQuery (it builds html) and run with eXist-db.
Could you help me with this, please?
Thank you.
You'll need four elements to achieve your goal:
An <xf:instance id="result" > to store the result of calling your xquery. Make sure to add an id attribute to identify the instance further.
An <xf:submission> to call your xquery an store the result in the instance. This is the submission you'll call in the <xf:send> and may look like this:
<xf:submission id="s-send" method="get" replace="instance" instance="result">
<xf:resource value="concat('myxquery.xq?interface=',InterfaceName/value)"/>
</xf:submission>
Note that the concat function is used to build the xquery url, including parameters.
An <xf:output value="instance('result')" mediatype="application/xhtml+xml"> to show the contents of the result instance. The mediatype="application/xhtml+xml" attribute is needed to display the html table.
In the server side, you can't call an xquery function directly, you need to write an xquery (myquery.xq) that calls the function and extracts the parameters from the URL.
Take a look to this sample https://en.wikibooks.org/wiki/XQuery/Getting_URL_Parameters
I'm doing some bug-fix on a legacy project which was developed using Struts2 and JSTL. I have an issue with the multiple select below:
<tr class="itemTr">
<td class="formLabel"><span class="spamFormLabel">Tags </span>
</td>
<td class="formField"><html:select property="tags"
styleId="tags"
styleClass="baseField" size="1" multiple="true"
style="height:170">
<html:options property="tagsList"
labelProperty="tagsLabelList" styleClass="baseOptions" />
</html:select>
</td>
</tr>
When i request the values on the action class
request.getParameter("tags");
is just returning the first value I selected. My objective is to return all of them, of course...lol
String parreco[] = request.getParameterValues("tags");
Using this method I can use all the selected values
I'm writing an application that uses a given email template to generate multiple messages.
The e-mail parser works fine. I'm using RazorEngine to create the e-mail template.
The problem is that I need to generate a table using the following construct (a simple foreach):
<table>
<tbody>
<tr><th>Pedido</th><th>NF</th><th>Boleto</th><th>Vencimento</th><th>Valor</th></tr>
#foreach (dynamic item in Model.PagamentosEmAtraso) {
<tr>
<td valign="top" width="76">
<p align="center"><span style="font-size: small;">#item.NumeroPedido</span></p>
</td>
<td valign="top" width="60">
<p align="center"><span style="font-size: small;">#item.NumeroNotaFiscal</span></p>
</td>
<td valign="top" width="88">
<p align="center"><span style="font-size: small;">#item.NumeroBoleto</span></p>
</td>
<td valign="top" width="128">
<p align="center"><span style="font-size: small;">#item.DataVencimento.ToString("dd/MM/yyyy")</span></p>
</td>
<td valign="top" width="119">
<p align="center"><span style="font-size: small;">#item.ValorLiquido.ToString("C2") </span></p>
</td>
</tr>
}
</tbody>
</table>
When I exit the html editor, tinymce messes up my code, "fixing" my code using like this:
#foreach (dynamic item in Model.PagamentosEmAtraso) {}
<table>
This is issue is happening on newer versions of tinymce - it used to accept this kind of markup.
Is there any viable solution to let tinymce accept a possibly broken html without trying to fix it?
My tinymce configuration is:
function initializeTinyMce() {
$('textarea.tinymce').tinymce({
// Location of TinyMCE script
script_url: '/Scripts/tinymce/tiny_mce.js',
// General options
theme: "advanced",
plugins: " pa geb reak,legacyoutput,style,layer,table,save,advimage,advlink,emotions,iespell,inlinepopups,preview,media,searchreplace,print,c o nt extmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template",
width: "960",
height: "500",
entity_encoding: "raw",
// Theme options
theme_advanced_buttons1: " bo ld, italic,underline,strikethrough,sub,sup,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontse l ec t,fontsizeselect",
theme_advanced_buttons2: " cu t,c opy,paste,pastetext,pasteword,|,bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,image,cleanup,help,code,|,insert d at e,inserttime,preview,|,forecolor,backcolor",
theme_advanced_buttons3: "tablecontrols,|,hr,removeformat,visualaid,||,fullscreen",
theme_advanced_toolbar_location: "top",
theme_advanced_toolbar_align: "left",
theme_advanced_statusbar_location: "bottom",
theme_advanced_resizing: true,
// Example content CSS (should be your site CSS)
//content_css: "/Content/site.css",
// Drop lists for link/image/media/template dialogs
template_external_list_url: "lists/template_list.js",
external_link_list_url: "lists/link_list.js",
external_image_list_url: "lists/image_list.js",
media_external_list_url: "lists/media_list.js",
// Replace values for the template plugin
template_replace_values: {
username: "Some User",
staffid: "991234"
}
});
}
Since 3.4 it is not possible anymore to turn off the tinymce validator using a config setting.
The html needs to be valid, but you may define what gets accepted as valid by the tinymce validator and what not. Have a closer look at the tinymce config params valid_elments and valid_children.