Velocity Templates in Confluence with Handlebars - velocity

Why am I getting this error:
org.apache.velocity.exception.ParseErrorException: Encountered "btnBreakPrivateStartDisabled" at /templates/przerwy/askbreaks.vm[line 14, column 97]
Was expecting:
"(" ...
when using this:
<input type="button" id="button_break_private_start" class="breakButtons"
{{#if btnBreakPrivateStartDisabled}}disabled{{/if}}
value="$action.getText('break.ask.private')"
onclick="window.location.href='$req.contextPath/plugins/requests/requestprivatebreak.action'"/>

The #if is being interpreted as a Velocity directive, and since parentheses are required around the conditional expression in Velocity syntax, it produces the error you see above. Your syntax suggests that you meant for that #if directive to be processed by Handlebars instead. It's not clear how you are invoking Handlebars, but if you need to represent a literal #if in your output, you can escape the #.
Note that Confluence has built in support for Soy templates (Google Closure templates). If those might fit your need in place of Handlebars, they would allow you to write .soy templates directly without having to go through Velocity and without worrying about escaping.

Related

Parsing annotations within comments / Negative matching of strings in regexps

I'm defining the syntax of the Move IR. The test suite for this language includes various annotations to enable testing. I need to treat comments of this form specially:
//! new-transaction
// check: "Keep(ABORTED { code: 123,"
This file is an example arithmetic_operators_u8.mvir.
So far, I've got this working by disallowing ordinary single-line comments.
module MOVE-ANNOTATION-SYNTAX-CONCRETE
imports INT-SYNTAX
syntax #Layout ::= r"([\\ \\n\\r\\t])" // Whitespace
syntax Annotation ::= "//!" "new-transaction" [klabel(NewTransaction), symbol]
syntax Check ::= "//" "check:" "\"Keep(ABORTED { code:" Int ",\"" [klabel(CheckCode), symbol]
endmodule
module MOVE-ANNOTATION-SYNTAX-ABSTRACT
imports INT-SYNTAX
syntax Annotation ::= "#NewTransaction" [klabel(NewTransaction), symbol]
syntax Check ::= #CheckCode(Int) [klabel(CheckCode), symbol]
endmodule
I'd like to also be able to use ordinary comments.
As a first step, I was able to change the Layout to allow commits only if the begin with a ! using r"(\\/\\/[^!][^\\n\\r]*)"
I'd like to exclude all comments that start with either //! or // check: from comments. What's a good way of implementing this?
Where can I find documentation for the regular expression language that K uses?
K uses flex for its scanner, and thus for its regular expression language. As a result, you can find documentation on its regular expression language here.
You want a regular expression that expresses that comments can't start with ! or check:, but flex doesn't support negative lookahead or not patterns, so you will have to exhaustively enumerate all the cases of comments that don't start with those sequence of characters. It's a bit tedious, sadly.
For reference, here is a (simplified) regular expression drawn from the syntax of C that represents all pragmas that don't start with STDC. It should give you an idea of how to proceed:
#pragma([:space:]*)([^S].*|S|S[^T].*|ST|ST[^D].*|STD|STD[^C].*|STDC[_a-zA-Z0-9].*)?$

Uncrustify - whats adding space between 'assert' and '('

No matter how I update the config file I seem to always end up with a space
System.assert(true); becomes System.assert (true);
This is only when the function is called assert
The following both format without a space before the '('
System.asser(true);
System.assertt(true);
Uncrustify config https://pastebin.com/4bnNXzhC
I believe your problem is that Java has an assert statement which Uncrustify's confusing your function call as. Although that wouldn't make much sense considering I tried to test if adding/removing spaces before control statements would change this behavior and it didn't.
I did find a workaround for you through the following configuration options parsing as Java. Since Java supports the assert statement it is a bit odd that they don't have a specific configuration option for it. It may be in your best interest to file a bug report / GH issue with the Uncrustify devs to help better resolve this problem.
# Add or remove space between the user function name and '(' on function
# calls. You need to set a keyword to be a user function in the config file,
# like:
# set func_call_user tr _ i18n
sp_func_call_user_paren = remove # ignore/add/remove/force
set func_call_user assert
Keep in mind that Apex is not an officialy supported language of Uncrustify. So if things don't work specifically for Apex then there's really not much else that can be done.

Extracting tokens out of ES6 template literals with Ragel

JavaScript contains the following syntax:
`hello ${name}`
I'm wondering how a Ragel machine would split the syntax above. The way I see it, the type of the closing curly brace depends on the parsing state. For example, in the code below the curly brace is instead part of the string token, since the ${ token isn't there:
`hello name}`
Finally, it becomes more tricky when you consider that the right curly can also be found within the variable expression itself, ie:
`hello ${() => { return name }()}`
How would a similar context-dependent grammar be implemented with Ragel?
The syntax inside of `` is not normally something you would handle with your lexical analyzer. Better to send it to your parser as a sequence of literal text and/or tokens. So you'd send "`" as opening, "hello " as some literal text, then the tokens "(", ")" etc. To know when to stop and go back to literal text you either need some feedback from your parser to to your scanner, or inside the scanner you need to balance the parens.
Note I've never actually made a parser for javascript, just going on what you provided above.

Escaping +(plus) sign in Kendo grid ASP.NET MVC ClientTemplate

I've having a problem defining a ASP.NET MVC ClientTemplate for a column in a Kendo grid because the '+' sign is being stripped out, which causes the client-side generated template to fail because of bad syntax.
My ClientTemplate is:
c.Template(#<text></text>).ClientTemplate("#='Hello' + Name#")
In the client, however, this gets reduced to:
template: "#='Hello' Name#"
i.e. the plus sign has been rendered as a space (similar to URL encoding I guess). The template works perfectly if I use from JS directly (see this JSBin).
Does anyone know how I can escape the + sign so I can use it in the ClientTemplate?
I have tried escaping using '\\+' (gets rendered as '\'), '\+' (invalid C#), + (same as +, although others such as ,' work fine).
Any ideas? Thanks.
For reference I'm using Razor markup and Q2 2012 Kendo release (can't use Q3 yet as limited by jQuery version as we're upgrading from Telerik)
NOTE: before anyone asks why I'm doing this, my ClientTemplate is actually more complex but this is a simplified example to illustrate the problem :-)
I checked the source code1, the MVC wrapper is calling HttpUtility.UrlDecode on all templates before it renders them to JS. So to escape your + sign (or any other reserved URL character), use percent encoding. In this case %2B.
c.Template(#<text></text>).ClientTemplate("#='Hello' %2B Name#")
1 v2013.3, src\Kendo.Mvc\Kendo.Mvc\UI\Grid\Columns\GridColumnBase.cs, line 135. I suspect this is a bug and they meant to call HttpUtility.UrlEncode.
Found a solution (possibly more of a workaround). Rather than writing inline JavaScript I moved my code to a separate JS function and called that from the template code, e.g.:
#=myFunctionToDoComplicatedStuff(Name)#
To be honest, for reasons of testability, reuse and general good practice this is probably the approach that should be taken anyway. It's a bit annoying for something trivial though!
If you just need a simple solution for doing concatenation in your ClientTemplate that avoids the encoding issue with plus signs, you can use the javascript concat function like this:
c.Template(#<text></text>).ClientTemplate("#='Hello'.concat(Name)#")
Have you tried taking the arithmetic and putting it outside the quotations as below:
c.Template(#<text></text>).ClientTemplate("#='Hello'" + "Name#")
For what it's worth, I just ran into this and solved it by subtracting a negative value. Such as:
kendo.parseFloat(Amount) - -kendo.parseFloat(Tip)
I have found a solution by using an alternative plus sign.
c.Template(#<text></text>).ClientTemplate("#='Hello' (<span style=\\'font-size: 0.6em\\'>➕</span>{ Name#")
This will result in...
template: "#='Hello + Name#"

How to output ${expression} in Freemarker without it being interpreted?

I'm trying to use Freemarker in conjunction with jQuery Templates.
Both frameworks use dollar sign/curly brackets to identify expressions for substitution (or as they're called in freemarker, "interpolations") , e.g. ${person.name} .
So when I define a jQuery Template with expressions in that syntax, Freemarker tries to interpret them (and fails).
I've tried various combinations of escaping the ${ sequence to pass it through Freemarker to no avail - \${, \$\{, $\{, etc.
Inserting a freemarker comment in between the dollar and the curly (e.g. $<#-- -->{expression}) DOES work - but I'm looking for a more concise and elegant solution.
Is there a simpler way to get a Freemarker template to output the character sequence ${?
This should print ${person.name}:
${r"${person.name}"}
From the freemarker docs
A special kind of string literals is the raw string literals. In raw string literals, backslash and ${ have no special meaning, they are considered as plain characters. To indicate that a string literal is a raw string literal, you have to put an r directly before the opening quotation mark or apostrophe-quote
For longer sections without FreeMarker markup, use <#noparse>...</#noparse>.
Starting with FreeMarker 2.3.28, configure FreeMarker to use square bracket syntax ([=exp]) instead of brace syntax (${exp}) by setting the interpolation_syntax configuration option to square_bracket.
Note that unlike the tag syntax, the interpolation syntax cannot be specified inside the template. Changing the interpolation syntax requires calling the Java API:
Configuration cfg;
// ...
cfg.setInterpolationSyntax(SQUARE_BRACKET_INTERPOLATION_SYNTAX);
Then FreeMarker will consider ${exp} to be static text.
Do not confuse interpolation syntax with tag syntax, which also can have square_bracket value, but is independent of the interpolation syntax.
When using FreeMarker-based file PreProcessor (FMPP), either configure the setting via config.fmpp or on the command-line, such as:
fmpp --verbose --interpolation-syntax squareBracket ...
This will call the appropriate Java API prior to processing the file.
See also:
https://freemarker.apache.org/docs/dgui_misc_alternativesyntax.html
http://fmpp.sourceforge.net/settings.html#templateSyntax
Another option is to use #include with parse=false option. That is, put your jQuery Templates into the separate include page and use parse=false so that freemarker doesn't try and parse it.
This would be a good option when the templates are larger and contain double quotes.
I had to spent some time to figure out the following scenarios to escape ${expression} -
In Freemarker assignment:
<#assign var = r"${expression}">
In html attribute:
Some link
In Freemarker concatenation:
<#assign x = "something&"+r"${expression}"/>
If ${ is your only problem, then you could use the alternate syntax in the jQuery Templates plugin like this: {{= person.name}}
Maybe a little cleaner than escaping it.
Did you try $$?
I found from the Freemarker manual that ${r"${person.name}"} will print out ${person.name} without attempting to render it.
Perhaps you should also take a look at Freemarker escaping freemarker
I can confirm that the
${r"${item.id}"}
is the correct way as an example.
So I kinda full example will look like
<span> Remove </span>
and the output will be :
<span> Remove </span>
In the case when you want to use non-raw strings so that you can escape double quotes, apostrophes, etc, you can do the following:
Imagine that you want to use the string ${Hello}-"My friend's friend" inside of a string. You cannot do that with raw strings. What I have used that works is:
${"\x0024{Hello}-\"My friend's friend\""}
I have not escaped the apostrophe since I used double quotes.