How do you parse booleans in Scriban? - scriban

Is it possible to perform bool.parse or similar operations?
Simplified Scriban template to demonstrate question:
var template = Template.Parse("{{ $parsed = foo | bool.parse }}");
var result = template.Render(new { foo = "True"});
This throws the error: (1,25) : error : Object bool is null

Unfortunately there isn't a way parse booleans with a built in function. One work around is to do the following:
var template = Template.Parse("{{ if foo | string.downcase == `true`; $parsed = true; end; $parsed; }}");
var result = template.Render(new { foo = "True"});
Here is a link to the issue in github: https://github.com/lunet-io/scriban/issues/243.

Related

How to add dynamic values to field injections list with custom trigger to camunda properties panel?

I have two questions here
Is it possible to add dynamic lists values to field injection list input ?
Can I create a trigger for this so this can be initiated from any other input selection say a class selection will populate all fields
I was just looking into FieldInjection.js whether that can be extented for the same
Can someone please provide a hint or direction for this ?
Thanks.
For anyone interested in the answer, I was able to achieve the above goal by changing the set function of the Java Class select input as folllowing
few imports
var extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'),
elementHelper = require('../../../../helper/ElementHelper')
var CAMUNDA_FIELD_EXTENSION_ELEMENT = 'camunda:Field';
function getExtensionFields(bo) {
return bo && extensionElementsHelper.getExtensionElements(bo, CAMUNDA_FIELD_EXTENSION_ELEMENT) || [];
}
then changing the set function to create extension element and push the field values as :
set: function(element, values, node) {
var bo = getBusinessObject(element);
var type = getImplementationType(element);
var attr = getAttribute(type);
var prop = {}
var commands = [];
prop[attr] = values.delegate || '';
var extensionElements = getExtensionFields(bo);
//remove any extension elements existing before
extensionElements.forEach(function(ele){
commands.push(extensionElementsHelper.removeEntry(getBusinessObject(element), element, ele));
});
if(prop[attr] !== ""){
var extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory);
commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements }));
var arrProperties = ["private org.camunda.bpm.engine.delegate.Expression com.cfe.extensions.SampleJavaDelegate.varOne","private org.camunda.bpm.engine.delegate.Expression com.cfe.extensions.SampleJavaDelegate.varTwo"]
var newFieldElem = "";
arrProperties.forEach(function(prop){
var eachProp = {
name:"",
string:"",
expression:""
}
var type = prop.split(" ")[1].split(".").reverse()[0];
var val = prop.split(" ")[2].split(".").reverse()[0];
eachProp.name = val;
if( type == "String"){
eachProp.string = "${" + val +" }"
}else if( type == "Expression"){
eachProp.expression = "${" + val +" }"
}
newFieldElem = elementHelper.createElement(CAMUNDA_FIELD_EXTENSION_ELEMENT, eachProp, extensionElements, bpmnFactory);
commands.push(cmdHelper.addElementsTolist(element, extensionElements, 'values', [ newFieldElem ]));
});
}
commands.push(cmdHelper.updateBusinessObject(element, bo, prop));
return commands;
}
Cheers !.

Reg-ex query is too greedy

Consider the following snippet:
<Offering id=1 blah blah templateid=abc something=blah
gretre
rtert
ret
tr
/Offering>
<Offering id=2 blah blah templateid=def something=blah>
gretre
rtert
ret
tr
</Offering>
<Offering id=3 blah blah templateid=ghi something=blah>
gretre
rtert
ret
tr
</Offering>
Given that all I know is the template id, I need to return the whole Offering node that contains it. i.e. for templateid=def, I need to return:
<Offering id=2 blah blah templateid=def something=blah>
gretre
rtert
ret
tr
</Offering>
I've tried all sorts but the closest I can get is something along the lines of (?s)<Offering.+?templateid=def.+?</Offering> which returns from the first offering until the end of the offering containing my template id. I understand why but nothing I've tried can fix it. I'm guessing lookarounds but I just can't get it right.
How can I return the whole offering node?
You could modify your regex using negation and I would probably use a word boundary as well.
<Offering[^>]*\btemplateid=def[^>]*>[^<]*</Offering>
If you have other tags inside of this tag, you could do ...
(?s)<Offering[^>]*\btemplateid=def.+?</Offering>
This should work but please notice that I escaped the / character, and you may not need to do that depending on what language you're using:
(<Offering[^>]* templateid=ghi [^>]*>[^<]*<\/Offering>)
As you say you "need to return the whole Offering node", the arguably simpler, safer and more readable way would be a DOM parser. I've included examples of how you might do this in JavaScript and PHP below.
PHP
$doc = new DOMDocument();
#$doc->loadHTML($testStr); //Only needed if you're loading HTML like in the example which has repeated attributes and other things that could cause errors
$body = $doc->getElementsByTagName('body')->item(0);
$templateID = 'def';
$myNode = null;
foreach($body->childNodes as $node)
{
if($node->nodeName=='offering')
{
if($node->attributes->getNamedItem('templateid')->nodeValue == $templateID)
{
$myNode = $node;
}
}
}
//$id = $myNode->attributes->getNamedItem('id')->nodeValue;
//$html = $doc->saveHTML($myNode)
JavaScript
var testStr = document.getElementById('str_container').innerHTML;
var parser = new DOMParser();
var doc = parser.parseFromString(testStr,'text/html');
var templateID = 'def';
var myEl = null;
for(var i=0,c=doc.body.children.length;i<c;i++)
{
if(doc.body.children[i].getAttribute('templateid')===templateID)
{
myEl = doc.body.children[i];
}
}
//var id = myEl.id;
//var html = myEl.outerHTML;
console.log(myEl || 'not found');
JavaScript >= IE8
var testStr = document.getElementById('str_container').innerHTML;
var parser = new DOMParser();
var doc = parser.parseFromString(testStr,'text/html');
var templateID = 'def';
var myEl = doc.body.querySelector('offering[templateid='+templateID+']');
//var id = myEl.id;
//var html = myEl.outerHTML;
console.log(myEl || 'not found');

RegExp in Node Js not working: Cannot call method 'toString' of null

This exact function does not work on Node Js, even though it work fine on a regular browser. How can I make it work on NodeJS?
Example: http://jsfiddle.net/wC53N/
var MyHereDoc = function() {
var bodyEmail = function(){
var test = 1;
/*HEREDOC
<div>
Hola1
<p>
hola2
</p>
</div>
HEREDOC*/
};
var here = "HEREDOC";
var reobj = new RegExp("/\\*"+here+"\\n[\\s\\S]*?\\n"+here+"\\*/", "m");
str = reobj.exec(bodyEmail).toString();
str = str.replace(new RegExp("/\\*"+here+"\\n",'m'),'').toString();
toPrint = str.replace(new RegExp("\\n"+here+"\\*/",'m'),'').toString();
document.getElementById("demo").innerHTML = toPrint;
}
MyHereDoc();
If you try to run this same code on NodeJS u will get this error:
Cannot call method 'toString' of null
But Why? any idea how to make it works, or what am I doing wrong?
Thanks

Get Ember-data model type from string

If I have a model type defined like this:
App.Model = DS.Model.extend({});
How could I construct the type from a string like 'model';
I dwant to be to be generic about using the store, instead of having to be specific like this:
App.store.load(App.model, obj);
If I understand you correctly, you can solve your issue using Ember.getPath, see http://jsfiddle.net/pangratz666/SGsU7/:
App.Model = Ember.Object.extend();
var capitalize = function(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
var string = 'model';
var capitalizedString = capitalized(string); // Model
var type = Ember.getPath(App, capitalizedString);
console.log(type === App.Model); // true
​

Using underscore.js groupBy with Ember.js

Is it possible to use underscore's groupBy function with ember.js?
I have the following attempt which is obviously not working:
var activities = App.store.findMany(App.Activity, feed.mapProperty('id').uniq())
var grouped = _.groupBy(activities, function(activity){
return activity.get('dateLabel;')
});
I get the following error:
Object App.Activity has no method 'get'
The store is loaded with the correct data so findMany will not make a remote call.
The problem is that findMany returns a DS.ManyArray which is probably a lot different than what _.groupBy is looking for.
You could implement your own groupBy function tailored for ember-data DS-ManyArray objects and extend _ with it:
_.emberArrayGroupBy = function(emberArray, val) {
var result = {}, key, value, i, l = emberArray.get('length'),
iterator = _.isFunction(val) ? val : function(obj) { return obj.get(val); };
for (i = 0; i < l; i++) {
value = emberArray.objectAt(i);
key = iterator(value, i);
(result[key] || (result[key] = [])).push(value);
}
return result;
};
Now you can call
var grouped = _.emberArrayGroupBy(activities, function(activity) {
return activity.get('dateLabel');
});
or more simply
var grouped = _.emberArrayGroupBy(activities, 'dateLabel');
The function above is based on underscore's original groupBy() implementation, which looks very similar:
_.groupBy = function(obj, val) {
var result = {};
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
each(obj, function(value, index) {
var key = iterator(value, index);
(result[key] || (result[key] = [])).push(value);
});
return result;
};
Try this code:
var activities = App.store.findMany(App.Activity, feed.mapProperty('id').uniq())
var grouped = _.groupBy(activities, function(activity){
return activity.get('dateLabel;')
}).bind(this);
I did not run this code to test how it works but the idea is to 'bind' outer scope into inner closure function scope.
Hope this helps to get you some ideas...