Combined Handlebars in SendGrid - email

I'm trying to set up a string match using handlebars in SendGrid. As I understand it, you can only use the if statement with booleans so I'm trying via {{equals}} instead. This works fine but I'm then trying to inject that 'thing' into the result. The result I'm after in the below is that if the data = TEXT then the email reads "This is some TEXT"
{{#equals thing "TEXT"}}
This is some {{insert thing}}
{{/equals}}
Using {{insert thing}} outside the {{equals}} handlebar is fine but when inside it doesn't return anything. I just get "This is some"
Does anyone know if this is supported or if there is a better way?
Thanks.

I'm not entirely sure how to explain it, but it seems that within blocks in handlebars there is a new scope. This works well for loops, where the scope is the current item in the loop, but less well for conditionals where the scope doesn't seem to include anything. You can get back to the root scope using the #root keyword though, so you can use that to get something from outside of the block. In this case, you can use it like this:
{{#equals thing "TEXT"}}
This is some {{insert #root.thing}}
{{/equals}}

Related

Sparx Enterprise Architect DocumentGenerator does not honour TaggedValues on Stereotype or values from SetProjectConstants and ReplaceField

maybe someone can help me on this. I am trying to generate a document via the DocumentGenerator interface. All in all this works well, except that the DocumentGenerator does not replace the Report Constants with actual values (which are defined on the report package stereotype.
This is the general flow of the document creation code (which generally works):
var gen = Repository.CreateDocumentGenerator();
gen.SetProjectConstant("ReportName", "My Project");
gen.NewDocument(string.Empty);
gen.ReplaceField("ReportName", "My Project");
gen.InsertCoverPageDocument(tags[REPORT_COVERPAGE]);
gen.InsertBreak(DocumentBreak.breakPage);
gen.InsertTOCDocument(tags[REPORT_TOC]);
gen.InsertBreak(DocumentBreak.breakPage);
gen.DocumentPackage((int)nativeId, 0, template);
gen.SaveDocument(fileName, DocumentType.dtDOCX);
I tried ReplaceField and SetProjectConstant both and one at a time before and after calls to NewDocument/InsertCoverPageDocument:
Strangely there is one constant that is being replaced: ReportSummary.
When I run the document generator via "F8" all constants are being replaced correctly.
Other project constants are being replaced correctly.
I can reproduce the behaviour on EA v14.1.1429 and v12.0.1215.
Does someone have a hint for further troubleshooting? Thanks in advance!
========== UPDATE ==========
When I use ReplaceField at the end (before the actual call to SaveDocument the following Report Constants get replaced: {ReportTitle} and {ReportName}
I discovered some workaround: when I manually remove the predefined {Report~} constants from the template and re-add them as Project Constants, their values get replaced correctly.
I will examine this further and give an update as
I did some further investigation on this and came to the following conclusion and workaround (as I have received no comments or answers on this):
I deleted all references to ReportConstants in my EA templates and replaced them by ProjectConstants with the same name.
In my code where I want to generate the documentation I (re)set all ProjectConstants with the actual values via SetProjectConstant and additionally added a call to ReplaceField to replace the constants with the actual values.
The previous mentioned calls are inserted directly before the call to SaveDocument document.
tags.ForEach(t =>
{
if (string.IsNullOrWhiteSpace(t.Key)) return;
generator.SetProjectConstant(t.Key, t.Value);
generator.ReplaceField(t.Key, t.Value);
});
generator.SaveDocument(fileName, DocumentType.dtDOCX);
If someone comes up with a better resonse or explanation for the behaviour I am happy to accept this as answer.
I have also found that when you call ReplaceField on these project constants in a CoverPage template, the formatting defined in the template is overwritten. It seems that some of the SetProjectConstant calls actually set the values as you would expect, and the rest do not.. hence the need to call both sets of APIs.

Working with layout object attributes and variables in FileMaker

This is the first time I'm encountering GetLayoutObjectAttribute and I am having serious issues with it. My variable $web won't set. I think it's because PD_WebV isn't the right object name to refer to, but I don't know how to find the right object name. I can't find the objects name when I hit Edit Layout, so does anyone know how to find an layout objects name?
Loop
Pause/Resume Script [Duration (seconds): 1]
Set Variable[$Web; Value: GetLayoutObjectAttribute("PD_WebV";"content")]
If[$Web="done"]
#execute if statements
After Edit:
After some troubleshooting, I found out that PD_WebV is the right object name to refer and it's refered to correctly, so my new question is why doesn't the script go to the line If[$Web="done"] and how could I fix it? Ss my If statement not evaluating something it should be? Is my $web variable never set to done or is the issue something completely different? Would the problem possibly have to do with my WebDirect sharing settings? Any guidance would help. Thanks.
After, After Edit:
So now that my application is getting past Set Variable[$Web; Value: GetLayoutObjectAttribute("PD_WebV";"content")], the variable $web only equals <HTML></HTML>. Does anyone know a way, without using javascript, to test the inside of the html tags?
Also, I printed the bounds of the webViewer PD_WebV that I can't locate on the layout but am referring to in the script. The bounds that are printed are different each time I run the script. Is the usual or unusual? My source is also about:blank so it doesn't look like I'm sourcing from a URL
Is my $web variable never set to done or is the issue something
completely different?
If you're doing:
Set Variable[$Web; Value: GetLayoutObjectAttribute("PD_WebV";"content")]
then the only time
$Web="done"
will return true is when the web page loaded into your web viewer contains exactly the string "done" (in practical terms, that's never).
I have already suggested in a comment that you test for:
PatternCount ( $webpage ; "</html>" )
This is assuming you want the subsequent steps to execute only after the page has finished loading. The entire script would look something like this:
Loop
Pause/Resume Script [Duration (seconds): 1]
Set Variable[$Web; Value: GetLayoutObjectAttribute("PD_WebV";"content")]
Exit Loop If [ PatternCount ( $webpage ; "</html>" ) ]
End Loop
# execute statements
You might also want to add a counter to the loop and exit the script after n trials.
Ah, I reread your question.
To set the object name for your webviewer so that the GetLayoutObjectAttribute function works you need to set it in the Name field in the inspector when you have the webviewer selected.
e.g.:
After that your variable should populate.
Be aware
What it will populate with will be all of the html from the browser, i.e. not a boolean true/false liek your conditional suggests.
I'm not sure exactly what you're trying to accomplish, but to be able to determine a result from your web viewer you'll need to either parse the HTML to see if it's content contains what you're looking for or within the code you're setting the webviewer with, fire a javascript function that calls back to the FileMaker file using a FileMaker url.

How do I pass xquery through eXist-db's REST api?

I understand how to use Xpath
http://localhost:8080/exist/rest/db/movies?_query=//movie[title=%22Spider-Man%22]/node()
But how to pass an xquery query? I keep reading everywhere that the REST api is for both xpath and xquery but I can't get my query to work. Here is what I'm trying to pass as an example (I've tested this in the xquery sandbox and it works):
for $movie in doc("movies/movies.xml")/movies/movie[year > 2002]
return <movie> { ($movie/title, $movie/year) } </movie>
How do I pass this in a URL? I dont really know where to start so I've tried just pasting the query above as the GET param, similar to the xpath query. So the url I pass is
http://localhost:8080/exist/rest/db/movies/?_query=for%20$movie%20in%20doc(%22movies/movies.xml%22)/movies/movie[year%20%3E%202002]%20return%20%3Cmovie%3E%20{%20($movie/title,%20$movie/year)%20}%20%3C/movie%3E
The page I get back is this
Am I going about this totally the wrong way? "movies" is a collection in my db.
It looks like your query was successfully executed. The <exist:result/> element looks quite correct, but it simply didn't find any movies which fit your filter criteria. It might also be a namespace issue. You should try your query locally to see if it returns something.
Your <script id="tinyhippos-injected"/> element is rather weird, as I did not expect tiny hippos here. However, this seems to be due to some Chrome extension you use.
Also, if your XQuery is a bit longer a URL paramter will not do and the encoding is difficult to read and maintain anyways. You might want to take a look at the eXist documentation about how to submit a POST request with an XQuery.

Is it possible to use a control without putting it on a form in VB6?

I'm pretty sure about the answer to this, but I'm trying a variety of things to get a very stubborn project to work. One idea was to try to run code through a control without defining it on a form.
So, for example, my original code looked like this:
frmProcess.MyViewer.MaxPageSize = 100
frmProcess.MyViewer.ResetPages
frmProcess.MyViewer.AddPageToView "C:\TestPage1.txt"
I've changed it to:
Dim objViewer As MyViewer
objViewer.MaxPageSize = 100
objViewer.ResetPages
objViewer.AddPageToView "C:\TestPage1.txt"
I get an error window with "Run-time error '91': Object variable or With block variable not set".
But there doesn't seem to be a way to 'set' this control. Is this just impossible, or is there another way to do it that doesn't require a form?
EDIT: I ended up abandoning this entire path of activity, as an alternate solution was found that got around the problem I was having with this form freezing. I don't want to delete this question in case someone else comes along and can benefit from the answers, which are potentially useful.
Try this on a form.
Dim objViewer As MyViewer
Set objViewer = Controls.Add("MyViewer", "MyViewer1")
objViewer.MaxPageSize = 100
objViewer.ResetPages
objViewer.AddPageToView "C:\TestPage1.txt"
I've had similar situations in the past. If all else fails and you have to use a form you can do something crude like
1) Set the .Left property of the control to a negative number (like -10000) so the control doesn't appear on the form, the user can not see it
2) Make the entire form not visible..
ActiveX controls normally expect a number of services from their containers, for example persistence. They are also "packaged and marked" in ways that set the kinds of instantiation they support.
See Introduction to ActiveX Controls.
While it is perfectly possible for a control to be created in such a way as to make many of the available services optional, most controls are created from template code that requires a number of them. And most controls that are "visible at runtime" are going to require container services.
However that doesn't mean a control can't be designed to support containerless instantiation. A well known example of such a control is Microsoft Script Control 1.0 (MSScriptControl.ScriptControl) which can be used either way.

How do I change inline javascript with Tritium?

I'm transforming a website using tritium, and there's a chunk of inline javascript that interferes with how the mobile site should work. There's really only one line that I want to take out, however, so I can't really just remove the whole chunk. Right now what I'm doing is just fetching the text and using a regex replace to remove the line:
$(".//script[contains(text(), "part of inline js")] {
# an example of the line i want to take out
text() {
replace("document.getElementById('someid').value = 'somevalue';") {
set("")
}
}
}
This seems kind of clunky, though, especially if the section I want to change gets very long. Is there a better way of doing this?
So I would probably use a regular expression in this case. Once you've got a unique enough capture, you can just capture the rest of the line.
In this case maybe it's something like:
replace(/.*getElementById\('someid'\)\.value.*/, "")
As of right now this is the only way to edit inline scripts.