Page tree

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 129 Next »

This is the documentation for ConfiForms Server/Data Center app

However, this might also work for ConfiForms cloud and in most cases it does. But please see this page to understand the differences between server and cloud versions of the ConfiForms app.


 

Looking for CLOUD documentation?  This page has information for both versions


ConfiForms IFTTT macro is a powerful tool which helps you to built integrations with other systems: to send emails, to create issues in Jira, to build workflows in Confluence, to organise templates and rules. And also to create various types of cool things around ConfiForms and Confluence.

Important note: IFTTT operations in ConfiForms are NOT TRANSACTIONAL, this means that the ConfiForms record save operation and the following after that IFTTT actions will be executed in own transactions. Failure of IFTTT action will NOT result in save operation rollback and the record still will be created

All the IFTTT integration operations are not transactional and executed in own scope, independently from ConfiForms internal operations


ConfiForms IFTTT macro is a part of ConfiForms Form definition and must be placed inside the ConfiForms Form macro body. You can place as many ConfiForms IFTTT macros as you want. Each macro has an event it is binded to. There are 4 types of events in ConfiForms:

  • onCreated - fires AFTER the record is created
  • onModified - fires AFTER the record has been modified
  • onDeleted - fires AFTER the record has been deleted
  • onError - fires in case if any of the previously executed IFTTT rules failed  / resulted in an error


You can define the "condition", to limit the scope when action is fired. Meaning that you can define to execute an action only when certain condition is met.

Conditions macro parameter expects a filter, more about filters could be found here: ConfiForms Filters


ConfiForms IFTTTs generate results (type depends on the IFTTT type)

These results could be used to created "chained" flows, when one IFTTT uses the results of the previous IFTTT(s). The easiest way is to set the name to the IFTTT result (see RESULTNAME), so you can reference it anytime via [iftttResult_RESULTNAME

Important to note that result chaining is PER EVENT. Which means you can reference results of previous IFTTTs only if the event is matching (onCreated, onModified, onDeleted and onError). Each event has own chain of results. 


At the moment ConfiForms IFTTT macro has 38 action types to choose from.


Each action has different set of parameters to set. In most cases you can use references to your entry fields via [entry.FIELD_NAME] in macro parameters, so these will be replaced with actual values.


Important

The execution order for actions is the same as you put them inside the ConfiForms Form macro body (obviously, filtered by event type). IFTTT execution also supports referencing of results for previous execution: Advanced integrations with IFTTT macros with ConfiForms


Below, you can find a list of integrations scenarios the macro can support and it's configuration details

Actions list

There are 38 different actions supported by IFTTT out-of-the-box (some actions are very generic, so the integration scenarios number is a lot bigger)



Each IFTTT action has own parameters, but the following parameters are supported by all actions


When specified (in the docs below, for an action) - a macro body is used as a template, otherwise leave it empty



Parameter nameDescription
Event

Type of event in ConfiForms this IFTTT action should be fired on

  • On Created
  • On Modified
  • On Deleted


Action to performOne of the actions to perform. See the list above
Do not report errorA checkbox field to disable error reporting and continue with the workflow even if current macro has resulted in an error
Custom name for the action result

This is used in advanced techniques, when you want to use the result of the IFTTT in next IFTTT or want to save the result of some IFTTT or some part of the result back into a ConfiForms record. See below the result types and the contents stored in the result for each IFTTT action.


A result (depending on the action type) is stored in the context in the variable prefixed by "iftttResult_"

And is accessible using the Velocity notation via

${iftttResult_RESULTNAME}
or (see Velocity templates syntax for more on "!" operator)
$!{iftttResult_RESULTNAME}

Same can be archived with 
[iftttResult_RESULTNAME]
since ConfiForms version 2.11

Where "RESULTNAME" is the value given in this macro parameter.

Some results hold rich objects. See "Result type" section for exact IFTTT action below


Add Attachment Label

SERVER/DC


Add a label or labels to attachment
Result type:
NO RESULT



Add Page Label

SERVER/DC

CLOUD

Adds label to a page, you can apply a label (or labels) to page sub-pages as well

Result type:
NO RESULT

Add Page Watcher

SERVER/DC

CLOUD

Adds a user or group of users as a page watcher
Result type:

Page object (page where the watcher's were added)

Depending on the IFTTT result name you can access all of the properties available from Page object.

For example (when result name is MYRESULT)

${iftttResult_MYRESULT.id}
${iftttResult_MYRESULT.spaceKey}
${iftttResult_MYRESULT.displayTitle}

Same can be archived with 
[iftttResult_RESULTNAME.id]
[iftttResult_RESULTNAME.spaceKey]
[iftttResult_RESULTNAME.displayTitle]
since ConfiForms version 2.11

Any other property, which Page object provide (any "get" method)

Applink Service

SERVER/DC


Sends a request to configured Application link service

A user specifies which HTTP method to use, which URL service to execute (url must be given as "relative" url, this means it is "concatenated" with the base url in your applink service)

More about Application links in Confluence could be found here: https://confluence.atlassian.com/display/APPLINKS/Application+Links+Documentation

Result type:

Response returned from a request to a service is returned and stored as result

If response is a JSON then you can apply Virtual functions to work on a JSON object

Please note that virtual functions could be applied only on ConfiForms fields, not the IFTTT result directly. This means you will need to save the response to some ConfiForms field temporarily in order to apply the functions and convert the response to JSON.

Audit

Nothing to configure: see Using new Audit IFTTT action

SERVER/DC

Automatic audit for your form. Audit form with <form_name>_log is created for you automatically, with a field referencing your <form_name>
Result type:
NO RESULT

Copy Attachment

SERVER/DC

CLOUD

Copies attachment from one page to another. In contrast to "Move Attachment" action, the copy of an attachment created. Original attachment stays untouched
Result type:
NO RESULT

Copy ConfiForms Data



SERVER/DC

CLOUD

Copies data from one ConfiForms form to another, can have custom mapping for fields and have a filter applied before copying the data

Also, it can "flatten" the multi-select values to copy the data to a new form in an "expanded" view


Please note that if you leave the filter empty then ALL the records from a source form will be copied to a destination form.

To copy just one, current record, you will need to apply the following filter

id:[entry.id]

It is important to note that this action never fires any other "Create ConfiForms Entry", "Delete ConfiForms Entry" or "Copy ConfiForms Data" for the entry created

Result type:
Last created (copied) record as object. This means that you can access any property available in ConfiForms record. Please note that the values accessed using the Velocity notation (${}) return "raw" (internal) values. More on this Accessing field values and properties

Copy ConfiForms Data to DB



SERVER/DC

Executes a SQL statement you specify on your database (on the database connection you have configured)

You must specify a valid SQL statement - either INSERT or UPDATE

Similar to "Copy ConfiForms Data" action you can filter records on original form before copying, as well as "flatten" records in order to have multi-value fields as separate rows (if necessary)


ConfiForms uses JDBC driver to connect to your database. See more on Some guidelines on using database fields in ConfiForms and Working with database fields in ConfiForms

Result type:
NO RESULT

Copy Page



SERVER/DC

Copies page from one location to another

A user performing an operation should have enough permissions (to copy the page from source location to destination location (create page permisison))

Result type:

Copied page as object. Any property a Page object has

For example (when result name is MYRESULT)

${iftttResult_MYRESULT.id}
${iftttResult_MYRESULT.spaceKey}
${iftttResult_MYRESULT.displayTitle}
...

Same can be archived with 
[iftttResult_MYRESULT.id]
[iftttResult_MYRESULT.spaceKey]
[iftttResult_MYRESULT.displayTitle]
since ConfiForms version 2.11

Any other property, which Page object provides (any "get" method)




Create Attachment



SERVER/DC

CLOUD

Creates a file, based on the content you specify in macro body and uploads it as attachment.

See more Creating a file with calendar invitation - ics file in Confluence and sending it via email with ConfiForms

You need to specify field name to use to store the reference to a created attachment - ConfiForms field of type "File" is the preferred field type to store this



Macro body:

Template / content to use to generate the contents
You can reference any field value using [entry.fieldname] notation, more on this Accessing field values and properties

Result type:
File contents as text into the result

Create BlogPost



 

SERVER/DC

CLOUD

Creates blog post based on the contents in macro body and the title given.

Blog post will be created in a Confluence space specified.

You can apply labels to a created blog post

Macro body:

Template / content to use to generate the contents
You can reference any field value using [entry.fieldname] notation, more on this Accessing field values and properties

IFTTT macro body evaluates as Velocity template
Macro body is evaluated as Velocity Template! This allows you to use #if #end constructions around JSON mapping parts.

Field values are stored in Velocity templates under field names!

For multi-value holding fields and for the single choice fields, like dropdowns, radio group fields, etc the field is always present in the context and has the value, so you cannot check it with 

#if(${somefield})
#end

as it will always be evaluated to true, but you can check if it has any values

--- check if field has no values

#if(${somefield.isEmpty()})
#end

--- check if the field is NOT empty and has values
#if(!${somefield.isEmpty()})
#end

Single choice field

--- get id
#if(${somefield.id})
#end   

--- get label
#if(${somefield.label})
#end


Checking if multi-value field has certain label or id

--- check if field has label (stored in values)
#if(${somefield.hasLabel("some_label")})
#end   

--- check if field has id (stored in values)
#if(${somefield.hasId("some_id")})
#end


Also, there is standard set of objects inside the context

context.put("entry", entry); <- ConfiForms Entry (raw)
context.put("user", user); <- Confluence user object
context.put("page", contentObject); <- AbstractPage object


Since ConfiForms version 1.49.3 there are additional objects in the context:

context.put("generalUtil", new com.atlassian.confluence.util.GeneralUtil());
context.put("res", ServletActionContext.getResponse());
context.put("req", ServletActionContext.getRequest());
context.put("action", com.atlassian.confluence.renderer.radeox.macros.MacroUtils.getConfluenceActionSupport());


Since ConfiForms version 2.27.3

context.put("null", new NullTool()); // helper tool to check for nulls https://cwiki.apache.org/confluence/display/velocity/NullTool
context.put("esc", new EscapeTool()); // helper tool to escape values https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/EscapeTool.html
context.put("list", new ListTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/ListTool.html
context.put("iter", new IteratorTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/IteratorTool.html

See Apache velocity tools for detailed documentation on these helper classes


Since ConfiForms version 3.10.0

New class that allows you to query other forms for data right inside your Velocity template

Available under "dataLoader" and allows you to query other forms.
Returns a list of RegEntry (ConfiForms Entry (raw)) instances

  • findByFilter(long pageId, String formName)
  • findByFilter(long pageId, String formName, String filter)
  • findByFilter(long pageId, String formName, String filter, String sortedBy)
  • findById(long pageId, String formName, String id)



Very similar to what is available in the context when you develop Confluence user macros: 
https://confluence.atlassian.com/doc/writing-user-macros-4485.html
https://developer.atlassian.com/server/confluence/confluence-objects-accessible-from-velocity/                
              
which you can reference as any other variable in Velocity using velocity syntax, for example: ${page.id} to reference page id of current page

Also, a helpful link from apache 
---- copied from Apache https://wiki.apache.org/velocity/CheckingForNull

Q: I want to check for null, something like this:

#if ($car.fuel == null)

A: There are several approaches. Select the one most suitable depending on what you really want to do. (Thanks, everybody, for all the feedback on the user list.) See also: Bugzilla #20999Bugzilla #27741VelocityNullSupport.

Approach 1: Use the fact that null is evaluated as a false conditional. (cf. http://velocity.apache.org/engine/devel/user-guide.html#Conditionals)

#if( ! $car.fuel )
  • Note: The conditional will also pass if the result of $car.fuel is the boolean false. What this approach is actually checking is whether the reference is null or false.

Approach 2: Use the fact that null is evaluated as an empty string in quiet references. (cf. http://velocity.apache.org/engine/devel/user-guide.html#quietreferencenotation)

#if( "$!car.fuel" == "" )
  • Note: The conditional will also pass if the result of $car.fuel is an empty String. What this approach is actually checking is whether the reference is null or empty.

BTW, just checking for empty can be achieved by:

#if( "$car.fuel" == "" )

Approach 3: Combine Approach 1 and 2. This will check for null and null only.

#if ((! $car.fuel) && ("$!car.fuel" == ""))
  • Note: The logic underlying here is that: "(null or false) and (null or > empty-string)" => if true, must be null. This is true because "false and empty-string and not null" is never true. IMHO, this makes the template too complicated to read.

Approach 4: Use a Tool that can check for null (NullTool,ViewNullTool).

#if( $null.isNull($car.fuel) )
  • Note: Of course, NullTool must be in the Context as $null in this case (in ConfiForms it is included into the context under "null" variable name).

In ConfiForms version 2.15.3+ we have extended NullTool to have 2 more convenient methods (isNullOrEmpty and isNotNullOrEmpty) to check if the value is null or empty


isNull
isNullOrEmpty
isNotNull
isNotNullOrEmpty


Approach 5: Don't check for null directly, use a self-explaining method.

#if( $car.fuelEmpty )
  • Note: This is my (Shinobu Kawai's) recommended solution. You have to implement the method, but it makes the template so easy-to-read.


public boolean isFuelEmpty()
{
  // return true if fuel is empty.
}

Approach 6: Use a custom directive. cf. IfNullDirectiveIfNotNullDirective

#ifnull( $car.fuel )
#ifnotnull( $car.fuel )
  • Note: You will have to register the directive in your velocity.properties.


userdirective = org.apache.velocity.tools.generic.directive.Ifnull
userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull

Result type:

Created Blog Post - complete object, as https://docs.atlassian.com/confluence/5.8.9/com/atlassian/confluence/pages/BlogPost.html

Example:

${iftttResult_MYRESULT.id}
${iftttResult_MYRESULT.displayTitle}
other properties from BlogPost object

Same can be archived with 
[iftttResult_MYRESULT.id]
[iftttResult_MYRESULT.spaceKey]
[iftttResult_MYRESULT.displayTitle]
since ConfiForms version 2.11

(if result was named "MYRESULT")


Create Comment

SERVER/DC

Creates page comment. Comment contents will be take from IFTTT macro body
Macro body:

Macro body is used as comment template

Template / content to use to generate the contents
You can reference any field value using [entry.fieldname] notation, more on this Accessing field values and properties

IFTTT macro body evaluates as Velocity template
Macro body is evaluated as Velocity Template! This allows you to use #if #end constructions around JSON mapping parts.

Field values are stored in Velocity templates under field names!

For multi-value holding fields and for the single choice fields, like dropdowns, radio group fields, etc the field is always present in the context and has the value, so you cannot check it with 

#if(${somefield})
#end

as it will always be evaluated to true, but you can check if it has any values

--- check if field has no values

#if(${somefield.isEmpty()})
#end

--- check if the field is NOT empty and has values
#if(!${somefield.isEmpty()})
#end

Single choice field

--- get id
#if(${somefield.id})
#end   

--- get label
#if(${somefield.label})
#end


Checking if multi-value field has certain label or id

--- check if field has label (stored in values)
#if(${somefield.hasLabel("some_label")})
#end   

--- check if field has id (stored in values)
#if(${somefield.hasId("some_id")})
#end


Also, there is standard set of objects inside the context

context.put("entry", entry); <- ConfiForms Entry (raw)
context.put("user", user); <- Confluence user object
context.put("page", contentObject); <- AbstractPage object


Since ConfiForms version 1.49.3 there are additional objects in the context:

context.put("generalUtil", new com.atlassian.confluence.util.GeneralUtil());
context.put("res", ServletActionContext.getResponse());
context.put("req", ServletActionContext.getRequest());
context.put("action", com.atlassian.confluence.renderer.radeox.macros.MacroUtils.getConfluenceActionSupport());


Since ConfiForms version 2.27.3

context.put("null", new NullTool()); // helper tool to check for nulls https://cwiki.apache.org/confluence/display/velocity/NullTool
context.put("esc", new EscapeTool()); // helper tool to escape values https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/EscapeTool.html
context.put("list", new ListTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/ListTool.html
context.put("iter", new IteratorTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/IteratorTool.html

See Apache velocity tools for detailed documentation on these helper classes


Since ConfiForms version 3.10.0

New class that allows you to query other forms for data right inside your Velocity template

Available under "dataLoader" and allows you to query other forms.
Returns a list of RegEntry (ConfiForms Entry (raw)) instances

  • findByFilter(long pageId, String formName)
  • findByFilter(long pageId, String formName, String filter)
  • findByFilter(long pageId, String formName, String filter, String sortedBy)
  • findById(long pageId, String formName, String id)



Very similar to what is available in the context when you develop Confluence user macros: 
https://confluence.atlassian.com/doc/writing-user-macros-4485.html
https://developer.atlassian.com/server/confluence/confluence-objects-accessible-from-velocity/                
              
which you can reference as any other variable in Velocity using velocity syntax, for example: ${page.id} to reference page id of current page

Also, a helpful link from apache 
---- copied from Apache https://wiki.apache.org/velocity/CheckingForNull

Q: I want to check for null, something like this:

#if ($car.fuel == null)

A: There are several approaches. Select the one most suitable depending on what you really want to do. (Thanks, everybody, for all the feedback on the user list.) See also: Bugzilla #20999Bugzilla #27741VelocityNullSupport.

Approach 1: Use the fact that null is evaluated as a false conditional. (cf. http://velocity.apache.org/engine/devel/user-guide.html#Conditionals)

#if( ! $car.fuel )
  • Note: The conditional will also pass if the result of $car.fuel is the boolean false. What this approach is actually checking is whether the reference is null or false.

Approach 2: Use the fact that null is evaluated as an empty string in quiet references. (cf. http://velocity.apache.org/engine/devel/user-guide.html#quietreferencenotation)

#if( "$!car.fuel" == "" )
  • Note: The conditional will also pass if the result of $car.fuel is an empty String. What this approach is actually checking is whether the reference is null or empty.

BTW, just checking for empty can be achieved by:

#if( "$car.fuel" == "" )

Approach 3: Combine Approach 1 and 2. This will check for null and null only.

#if ((! $car.fuel) && ("$!car.fuel" == ""))
  • Note: The logic underlying here is that: "(null or false) and (null or > empty-string)" => if true, must be null. This is true because "false and empty-string and not null" is never true. IMHO, this makes the template too complicated to read.

Approach 4: Use a Tool that can check for null (NullTool,ViewNullTool).

#if( $null.isNull($car.fuel) )
  • Note: Of course, NullTool must be in the Context as $null in this case (in ConfiForms it is included into the context under "null" variable name).

In ConfiForms version 2.15.3+ we have extended NullTool to have 2 more convenient methods (isNullOrEmpty and isNotNullOrEmpty) to check if the value is null or empty


isNull
isNullOrEmpty
isNotNull
isNotNullOrEmpty


Approach 5: Don't check for null directly, use a self-explaining method.

#if( $car.fuelEmpty )
  • Note: This is my (Shinobu Kawai's) recommended solution. You have to implement the method, but it makes the template so easy-to-read.


public boolean isFuelEmpty()
{
  // return true if fuel is empty.
}

Approach 6: Use a custom directive. cf. IfNullDirectiveIfNotNullDirective

#ifnull( $car.fuel )
#ifnotnull( $car.fuel )
  • Note: You will have to register the directive in your velocity.properties.


userdirective = org.apache.velocity.tools.generic.directive.Ifnull
userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull




Result type:
Created comment - complete object properties  https://docs.atlassian.com/atlassian-confluence/6.0.1/com/atlassian/confluence/pages/Comment.html

Create (Update) ConfiForms Entry




SERVER/DC

CLOUD

Creates (or updates) ConfiForms Entry in the specified form

It is important to note that this action never fires any other "Create ConfiForms Entry", "Delete ConfiForms Entry" or "Copy ConfiForms Data" for the entry created

Additionally, you can stop the propagation of the "create/update" events completely.


To update the current ConfiForms record leave the "Reference to form and it's location" empty and in parameters to set specify:

entryId=[entry.id]

To target the current record


You can also have your values be evaluated as expressions and contain Supported math operators, formulas and functions

In this case they should be wrapped in ()

Example:

myfield=(FORMATDATE(NOW()))

myfield=(ZEROIFEMPTY("[entry.anotherfield]"))
Result type:

Created entry object, same as in Copy ConfiForms Data


${iftttResult_MYRESULT.somefield}

Same can be archived with 
[iftttResult_MYRESULT.somefield]
since ConfiForms version 2.11

Where "somefield" is the name of the field in ConfiForms form

More details/examples:

This action helps you to create different types of update rules for your ConfiForms entries. You can create an audit for all changes, you can update entries in other forms or entries in the same form based on chosen criteria

Same action type is used for creating new entries and updating existing and the parameter to indicate that is "entryId"

So, to create record you will specify:

someparam=[entry.somefield]&anotherparam=[entry.another]

But to update existing record you will need to have something like this:

entryId=[entry.id]&someparam=[entry.somefield]&anotherparam=[entry.another]

You can also set constant values, does not have to be a reference to some field value

someparam=MY CONSTANT&anotherparam=[entry.another]

The above example will set "someparam" to constant value of "MY CONSTANT" and "anotherparam" will be set to a value found on the field named "another"


Important bit which is often forgotten is to specify which form and where it is located (form name and pageId), the last parameter in the macro. If this is not specified then nothing is executed, as ConfiForms does not know where this action to be applied


Other tutorials:




Create Insight Object



SERVER/DC

Creates Insight object based on the JSON mapping given

See Creating Jira issue from Confluence with ConfiForms for a tutorial on Creating JIRA issues, the concept behind creating Insight objects is identical


IFTTT macro body evaluates as Velocity template
Macro body is evaluated as Velocity Template! This allows you to use #if #end constructions around JSON mapping parts.

Field values are stored in Velocity templates under field names!

For multi-value holding fields and for the single choice fields, like dropdowns, radio group fields, etc the field is always present in the context and has the value, so you cannot check it with 

#if(${somefield})
#end

as it will always be evaluated to true, but you can check if it has any values

--- check if field has no values

#if(${somefield.isEmpty()})
#end

--- check if the field is NOT empty and has values
#if(!${somefield.isEmpty()})
#end

Single choice field

--- get id
#if(${somefield.id})
#end   

--- get label
#if(${somefield.label})
#end


Checking if multi-value field has certain label or id

--- check if field has label (stored in values)
#if(${somefield.hasLabel("some_label")})
#end   

--- check if field has id (stored in values)
#if(${somefield.hasId("some_id")})
#end


Also, there is standard set of objects inside the context

context.put("entry", entry); <- ConfiForms Entry (raw)
context.put("user", user); <- Confluence user object
context.put("page", contentObject); <- AbstractPage object


Since ConfiForms version 1.49.3 there are additional objects in the context:

context.put("generalUtil", new com.atlassian.confluence.util.GeneralUtil());
context.put("res", ServletActionContext.getResponse());
context.put("req", ServletActionContext.getRequest());
context.put("action", com.atlassian.confluence.renderer.radeox.macros.MacroUtils.getConfluenceActionSupport());


Since ConfiForms version 2.27.3

context.put("null", new NullTool()); // helper tool to check for nulls https://cwiki.apache.org/confluence/display/velocity/NullTool
context.put("esc", new EscapeTool()); // helper tool to escape values https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/EscapeTool.html
context.put("list", new ListTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/ListTool.html
context.put("iter", new IteratorTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/IteratorTool.html

See Apache velocity tools for detailed documentation on these helper classes


Since ConfiForms version 3.10.0

New class that allows you to query other forms for data right inside your Velocity template

Available under "dataLoader" and allows you to query other forms.
Returns a list of RegEntry (ConfiForms Entry (raw)) instances

  • findByFilter(long pageId, String formName)
  • findByFilter(long pageId, String formName, String filter)
  • findByFilter(long pageId, String formName, String filter, String sortedBy)
  • findById(long pageId, String formName, String id)



Very similar to what is available in the context when you develop Confluence user macros: 
https://confluence.atlassian.com/doc/writing-user-macros-4485.html
https://developer.atlassian.com/server/confluence/confluence-objects-accessible-from-velocity/                
              
which you can reference as any other variable in Velocity using velocity syntax, for example: ${page.id} to reference page id of current page

Also, a helpful link from apache 
---- copied from Apache https://wiki.apache.org/velocity/CheckingForNull

Q: I want to check for null, something like this:

#if ($car.fuel == null)

A: There are several approaches. Select the one most suitable depending on what you really want to do. (Thanks, everybody, for all the feedback on the user list.) See also: Bugzilla #20999Bugzilla #27741VelocityNullSupport.

Approach 1: Use the fact that null is evaluated as a false conditional. (cf. http://velocity.apache.org/engine/devel/user-guide.html#Conditionals)

#if( ! $car.fuel )
  • Note: The conditional will also pass if the result of $car.fuel is the boolean false. What this approach is actually checking is whether the reference is null or false.

Approach 2: Use the fact that null is evaluated as an empty string in quiet references. (cf. http://velocity.apache.org/engine/devel/user-guide.html#quietreferencenotation)

#if( "$!car.fuel" == "" )
  • Note: The conditional will also pass if the result of $car.fuel is an empty String. What this approach is actually checking is whether the reference is null or empty.

BTW, just checking for empty can be achieved by:

#if( "$car.fuel" == "" )

Approach 3: Combine Approach 1 and 2. This will check for null and null only.

#if ((! $car.fuel) && ("$!car.fuel" == ""))
  • Note: The logic underlying here is that: "(null or false) and (null or > empty-string)" => if true, must be null. This is true because "false and empty-string and not null" is never true. IMHO, this makes the template too complicated to read.

Approach 4: Use a Tool that can check for null (NullTool,ViewNullTool).

#if( $null.isNull($car.fuel) )
  • Note: Of course, NullTool must be in the Context as $null in this case (in ConfiForms it is included into the context under "null" variable name).

In ConfiForms version 2.15.3+ we have extended NullTool to have 2 more convenient methods (isNullOrEmpty and isNotNullOrEmpty) to check if the value is null or empty


isNull
isNullOrEmpty
isNotNull
isNotNullOrEmpty


Approach 5: Don't check for null directly, use a self-explaining method.

#if( $car.fuelEmpty )
  • Note: This is my (Shinobu Kawai's) recommended solution. You have to implement the method, but it makes the template so easy-to-read.


public boolean isFuelEmpty()
{
  // return true if fuel is empty.
}

Approach 6: Use a custom directive. cf. IfNullDirectiveIfNotNullDirective

#ifnull( $car.fuel )
#ifnotnull( $car.fuel )
  • Note: You will have to register the directive in your velocity.properties.


userdirective = org.apache.velocity.tools.generic.directive.Ifnull
userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull

Macro body:

JSON mapping wrapped in "No Format" or in "Code" macro to have a raw text

JSON mapping should be of structure specified in Insight REST API https://documentation.riada.se/display/ICV50/Version+1.0+documentation

/rest/insight/1.0/object/create service in particular

Result type:

Created Object ID as text

${iftttResult_MYRESULT}
or (see Velocity templates syntax for more on "!" operator)
$!{iftttResult_MYRESULT}

Same can be archived with 
[iftttResult_MYRESULT]
since ConfiForms version 2.11

(if result was named "MYRESULT")

If IFTTT macro is set to ignore errors (execute in silent mode, then there might be NO RESULT in the variable, so accessing it with "!", like $!{iftttResult_MYRESULT} is safer)

More details / examples:

You can create Insight Objects from ConfiForms entries. However, this is a bit technical to setup as the integration is done through the JSON document you will need to prepare. See tutorial below for more details and examples. Important: you must have a correctly configured Application link to JIRA

Also, there are some helpers to help you with preparing correct JSON, see Virtual functions

Tutorials:

  • Creating Jira issue from Confluence with ConfiForms (similar concept to creating Insight Objects, but expects a different mapping and uses a different service underneath)

    Definitely use the NoFormat macro to place the JSON mapping inside the IFTTT macro body




Create Jira Issue



SERVER/DC

CLOUD

Creates JIRA issue based on the JSON mapping given using https://docs.atlassian.com/software/jira/docs/api/REST/9.2.0/#api/2/issue-createIssue

See Creating Jira issue from Confluence with ConfiForms

You can add users as watchers to created JIRA issue. Must be a valid user (list of users) given


When you want to add an attachment to JIRA issue from ConfiForms file field - you will need to place the "ConfiForms Field" macro inside the ConfiForms IFTTT macro body. This way, you will tell ConfiForms, in addition to issue creation, to upload the file to JIRA. You can upload multiple files, just by placing additional ConfiForms Field macros referencing other file fields into the macro body

IFTTT macro body evaluates as Velocity template
Macro body is evaluated as Velocity Template! This allows you to use #if #end constructions around JSON mapping parts.

Field values are stored in Velocity templates under field names!

For multi-value holding fields and for the single choice fields, like dropdowns, radio group fields, etc the field is always present in the context and has the value, so you cannot check it with 

#if(${somefield})
#end

as it will always be evaluated to true, but you can check if it has any values

--- check if field has no values

#if(${somefield.isEmpty()})
#end

--- check if the field is NOT empty and has values
#if(!${somefield.isEmpty()})
#end

Single choice field

--- get id
#if(${somefield.id})
#end   

--- get label
#if(${somefield.label})
#end


Checking if multi-value field has certain label or id

--- check if field has label (stored in values)
#if(${somefield.hasLabel("some_label")})
#end   

--- check if field has id (stored in values)
#if(${somefield.hasId("some_id")})
#end


Also, there is standard set of objects inside the context

context.put("entry", entry); <- ConfiForms Entry (raw)
context.put("user", user); <- Confluence user object
context.put("page", contentObject); <- AbstractPage object


Since ConfiForms version 1.49.3 there are additional objects in the context:

context.put("generalUtil", new com.atlassian.confluence.util.GeneralUtil());
context.put("res", ServletActionContext.getResponse());
context.put("req", ServletActionContext.getRequest());
context.put("action", com.atlassian.confluence.renderer.radeox.macros.MacroUtils.getConfluenceActionSupport());


Since ConfiForms version 2.27.3

context.put("null", new NullTool()); // helper tool to check for nulls https://cwiki.apache.org/confluence/display/velocity/NullTool
context.put("esc", new EscapeTool()); // helper tool to escape values https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/EscapeTool.html
context.put("list", new ListTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/ListTool.html
context.put("iter", new IteratorTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/IteratorTool.html

See Apache velocity tools for detailed documentation on these helper classes


Since ConfiForms version 3.10.0

New class that allows you to query other forms for data right inside your Velocity template

Available under "dataLoader" and allows you to query other forms.
Returns a list of RegEntry (ConfiForms Entry (raw)) instances

  • findByFilter(long pageId, String formName)
  • findByFilter(long pageId, String formName, String filter)
  • findByFilter(long pageId, String formName, String filter, String sortedBy)
  • findById(long pageId, String formName, String id)



Very similar to what is available in the context when you develop Confluence user macros: 
https://confluence.atlassian.com/doc/writing-user-macros-4485.html
https://developer.atlassian.com/server/confluence/confluence-objects-accessible-from-velocity/                
              
which you can reference as any other variable in Velocity using velocity syntax, for example: ${page.id} to reference page id of current page

Also, a helpful link from apache 
---- copied from Apache https://wiki.apache.org/velocity/CheckingForNull

Q: I want to check for null, something like this:

#if ($car.fuel == null)

A: There are several approaches. Select the one most suitable depending on what you really want to do. (Thanks, everybody, for all the feedback on the user list.) See also: Bugzilla #20999Bugzilla #27741VelocityNullSupport.

Approach 1: Use the fact that null is evaluated as a false conditional. (cf. http://velocity.apache.org/engine/devel/user-guide.html#Conditionals)

#if( ! $car.fuel )
  • Note: The conditional will also pass if the result of $car.fuel is the boolean false. What this approach is actually checking is whether the reference is null or false.

Approach 2: Use the fact that null is evaluated as an empty string in quiet references. (cf. http://velocity.apache.org/engine/devel/user-guide.html#quietreferencenotation)

#if( "$!car.fuel" == "" )
  • Note: The conditional will also pass if the result of $car.fuel is an empty String. What this approach is actually checking is whether the reference is null or empty.

BTW, just checking for empty can be achieved by:

#if( "$car.fuel" == "" )

Approach 3: Combine Approach 1 and 2. This will check for null and null only.

#if ((! $car.fuel) && ("$!car.fuel" == ""))
  • Note: The logic underlying here is that: "(null or false) and (null or > empty-string)" => if true, must be null. This is true because "false and empty-string and not null" is never true. IMHO, this makes the template too complicated to read.

Approach 4: Use a Tool that can check for null (NullTool,ViewNullTool).

#if( $null.isNull($car.fuel) )
  • Note: Of course, NullTool must be in the Context as $null in this case (in ConfiForms it is included into the context under "null" variable name).

In ConfiForms version 2.15.3+ we have extended NullTool to have 2 more convenient methods (isNullOrEmpty and isNotNullOrEmpty) to check if the value is null or empty


isNull
isNullOrEmpty
isNotNull
isNotNullOrEmpty


Approach 5: Don't check for null directly, use a self-explaining method.

#if( $car.fuelEmpty )
  • Note: This is my (Shinobu Kawai's) recommended solution. You have to implement the method, but it makes the template so easy-to-read.


public boolean isFuelEmpty()
{
  // return true if fuel is empty.
}

Approach 6: Use a custom directive. cf. IfNullDirectiveIfNotNullDirective

#ifnull( $car.fuel )
#ifnotnull( $car.fuel )
  • Note: You will have to register the directive in your velocity.properties.


userdirective = org.apache.velocity.tools.generic.directive.Ifnull
userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull

Macro body:

JSON mapping wrapped in "No Format" or in "Code" macro to have a raw text

JSON mapping should be of structure specified in JIRA REST API - https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-create-issue

Result type:

Created issue KEY as text

${iftttResult_MYRESULT}
or (see Velocity templates syntax for more on "!" operator)
$!{iftttResult_MYRESULT}

Same can be archived with 
[iftttResult_MYRESULT]
since ConfiForms version 2.11

(if result was named "MYRESULT")

If IFTTT macro is set to ignore errors (execute in silent mode, then there might be NO RESULT in the variable, so accessing it with "!", like $!{iftttResult_MYRESULT} is safer)

More details / examples:

You can create JIRA issues from ConfiForms entries. However, this is a bit technical to setup as the integration is done through the JSON document you will need to prepare. See tutorial below for more details and examples. Important: you must have a correctly configured Application link to JIRA

Also, there are some helpers to help you with preparing correct JSON, see Virtual functions

This action type supports uploading files to created JIRA ticket, an example is also available in the same tutorial.

Important to note that currently this action selects a primary app link to JIRA, if you have more than 1 JIRA connected then you will be able to create JIRA issues only in your primary JIRA (the one set as primary in your application links)

Tutorials:




Create Page



SERVER/DC

CLOUD

Creates Confluence page based on the template given (in macro body)

See Creating links in original ConfiForms entry to just created page

Using ConfiForms app as template engine to create pages in Confluence


In Confluence the page title should be unique within a Confluence space.

ConfiForms will create a new version of the page if the page with given title already exists in the Confluence space specified

Important to note is that if you put ConfiForms Field macros inside the IFTTT macro body and this macros will be WITHOUT a "view" macro around them, then a ListView macro with a filter set to current record is created as a wrapper for ALL the content in the IFTTT macro body.

If you want to avoid "auto-wrapping" then you need to make sure that all ConfiForms Field macros you put are within the "view" macro (TableView, ListView, CardView, etc)

In contrast, when you use [entry.fieldname] notations then there is no need to wrap anything in views macros. But in this case the data is static data copied (not referenced) there from ConfiForms

All references (like [entry.filed_name]) inside the IFTTT macro body to ConfiForms fields are evaluated against the current record.

If you have an IFTTT action to create a page with ConfiForms Form and it should have filters or field rules which in the created page should look like [entry.fieldname] you will need to wrap these into a virtual function

asEntryRef(REF_TO_ENTRY)


Example:

[entry.id.asEntryRef(entry.id)]

This will return

[entry.id]

When this is necessary?

The use case is when you use it within an IFTTT or have a ListView which has another ListView inside and you want to prevent ConfiForms from applying the context variables onto the sub-lists


The function can be used with any field type (as long as the field exists) and actually the following constructions are perfectly valid

[entry.id.asEntryRef(entry.somefield)] will return [entry.somefield]
[entry.id.asEntryRef(entry.mytextfield)] will return [entry.mytextfield]
[entry.id.asEntryRef(entry.anotherfield)] will return [entry.anotherfield]
[entry.id.asEntryRef(entry.id)] will return [entry.id]


As you can see we apply the function on the same ID field (exists in every ConfiForms record) and the parameter you give in is the important bit in all this...

So, the parameter (PARAM) you give to asEntryRef is wrapped into the brackets and returned:

[PARAM]


You can also use "_func" pseoudo property of a record as a bridge to "asEntryRef" function when the "id" is not available (assigned)

This is always available

[entry._func.asEntryRef(entry.somefield)] will return [entry.somefield]
[entry._func.asEntryRef(entry.mytextfield)] will return [entry.mytextfield]
[entry._func.asEntryRef(entry.anotherfield)] will return [entry.anotherfield]
[entry._func.asEntryRef(entry.id)] will return [entry.id]


IFTTT macro body evaluates as Velocity template
Macro body is evaluated as Velocity Template! This allows you to use #if #end constructions around JSON mapping parts.

Field values are stored in Velocity templates under field names!

For multi-value holding fields and for the single choice fields, like dropdowns, radio group fields, etc the field is always present in the context and has the value, so you cannot check it with 

#if(${somefield})
#end

as it will always be evaluated to true, but you can check if it has any values

--- check if field has no values

#if(${somefield.isEmpty()})
#end

--- check if the field is NOT empty and has values
#if(!${somefield.isEmpty()})
#end

Single choice field

--- get id
#if(${somefield.id})
#end   

--- get label
#if(${somefield.label})
#end


Checking if multi-value field has certain label or id

--- check if field has label (stored in values)
#if(${somefield.hasLabel("some_label")})
#end   

--- check if field has id (stored in values)
#if(${somefield.hasId("some_id")})
#end


Also, there is standard set of objects inside the context

context.put("entry", entry); <- ConfiForms Entry (raw)
context.put("user", user); <- Confluence user object
context.put("page", contentObject); <- AbstractPage object


Since ConfiForms version 1.49.3 there are additional objects in the context:

context.put("generalUtil", new com.atlassian.confluence.util.GeneralUtil());
context.put("res", ServletActionContext.getResponse());
context.put("req", ServletActionContext.getRequest());
context.put("action", com.atlassian.confluence.renderer.radeox.macros.MacroUtils.getConfluenceActionSupport());


Since ConfiForms version 2.27.3

context.put("null", new NullTool()); // helper tool to check for nulls https://cwiki.apache.org/confluence/display/velocity/NullTool
context.put("esc", new EscapeTool()); // helper tool to escape values https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/EscapeTool.html
context.put("list", new ListTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/ListTool.html
context.put("iter", new IteratorTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/IteratorTool.html

See Apache velocity tools for detailed documentation on these helper classes


Since ConfiForms version 3.10.0

New class that allows you to query other forms for data right inside your Velocity template

Available under "dataLoader" and allows you to query other forms.
Returns a list of RegEntry (ConfiForms Entry (raw)) instances

  • findByFilter(long pageId, String formName)
  • findByFilter(long pageId, String formName, String filter)
  • findByFilter(long pageId, String formName, String filter, String sortedBy)
  • findById(long pageId, String formName, String id)



Very similar to what is available in the context when you develop Confluence user macros: 
https://confluence.atlassian.com/doc/writing-user-macros-4485.html
https://developer.atlassian.com/server/confluence/confluence-objects-accessible-from-velocity/                
              
which you can reference as any other variable in Velocity using velocity syntax, for example: ${page.id} to reference page id of current page

Also, a helpful link from apache 
---- copied from Apache https://wiki.apache.org/velocity/CheckingForNull

Q: I want to check for null, something like this:

#if ($car.fuel == null)

A: There are several approaches. Select the one most suitable depending on what you really want to do. (Thanks, everybody, for all the feedback on the user list.) See also: Bugzilla #20999Bugzilla #27741VelocityNullSupport.

Approach 1: Use the fact that null is evaluated as a false conditional. (cf. http://velocity.apache.org/engine/devel/user-guide.html#Conditionals)

#if( ! $car.fuel )
  • Note: The conditional will also pass if the result of $car.fuel is the boolean false. What this approach is actually checking is whether the reference is null or false.

Approach 2: Use the fact that null is evaluated as an empty string in quiet references. (cf. http://velocity.apache.org/engine/devel/user-guide.html#quietreferencenotation)

#if( "$!car.fuel" == "" )
  • Note: The conditional will also pass if the result of $car.fuel is an empty String. What this approach is actually checking is whether the reference is null or empty.

BTW, just checking for empty can be achieved by:

#if( "$car.fuel" == "" )

Approach 3: Combine Approach 1 and 2. This will check for null and null only.

#if ((! $car.fuel) && ("$!car.fuel" == ""))
  • Note: The logic underlying here is that: "(null or false) and (null or > empty-string)" => if true, must be null. This is true because "false and empty-string and not null" is never true. IMHO, this makes the template too complicated to read.

Approach 4: Use a Tool that can check for null (NullTool,ViewNullTool).

#if( $null.isNull($car.fuel) )
  • Note: Of course, NullTool must be in the Context as $null in this case (in ConfiForms it is included into the context under "null" variable name).

In ConfiForms version 2.15.3+ we have extended NullTool to have 2 more convenient methods (isNullOrEmpty and isNotNullOrEmpty) to check if the value is null or empty


isNull
isNullOrEmpty
isNotNull
isNotNullOrEmpty


Approach 5: Don't check for null directly, use a self-explaining method.

#if( $car.fuelEmpty )
  • Note: This is my (Shinobu Kawai's) recommended solution. You have to implement the method, but it makes the template so easy-to-read.


public boolean isFuelEmpty()
{
  // return true if fuel is empty.
}

Approach 6: Use a custom directive. cf. IfNullDirectiveIfNotNullDirective

#ifnull( $car.fuel )
#ifnotnull( $car.fuel )
  • Note: You will have to register the directive in your velocity.properties.


userdirective = org.apache.velocity.tools.generic.directive.Ifnull
userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull


Macro body:

Template / content to use to generate the contents
You can reference any field value using [entry.fieldname] notation, more on this Accessing field values and properties

IFTTT macro body evaluates as Velocity template
Macro body is evaluated as Velocity Template! This allows you to use #if #end constructions around JSON mapping parts.

Field values are stored in Velocity templates under field names!

For multi-value holding fields and for the single choice fields, like dropdowns, radio group fields, etc the field is always present in the context and has the value, so you cannot check it with 

#if(${somefield})
#end

as it will always be evaluated to true, but you can check if it has any values

--- check if field has no values

#if(${somefield.isEmpty()})
#end

--- check if the field is NOT empty and has values
#if(!${somefield.isEmpty()})
#end

Single choice field

--- get id
#if(${somefield.id})
#end   

--- get label
#if(${somefield.label})
#end


Checking if multi-value field has certain label or id

--- check if field has label (stored in values)
#if(${somefield.hasLabel("some_label")})
#end   

--- check if field has id (stored in values)
#if(${somefield.hasId("some_id")})
#end


Also, there is standard set of objects inside the context

context.put("entry", entry); <- ConfiForms Entry (raw)
context.put("user", user); <- Confluence user object
context.put("page", contentObject); <- AbstractPage object


Since ConfiForms version 1.49.3 there are additional objects in the context:

context.put("generalUtil", new com.atlassian.confluence.util.GeneralUtil());
context.put("res", ServletActionContext.getResponse());
context.put("req", ServletActionContext.getRequest());
context.put("action", com.atlassian.confluence.renderer.radeox.macros.MacroUtils.getConfluenceActionSupport());


Since ConfiForms version 2.27.3

context.put("null", new NullTool()); // helper tool to check for nulls https://cwiki.apache.org/confluence/display/velocity/NullTool
context.put("esc", new EscapeTool()); // helper tool to escape values https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/EscapeTool.html
context.put("list", new ListTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/ListTool.html
context.put("iter", new IteratorTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/IteratorTool.html

See Apache velocity tools for detailed documentation on these helper classes


Since ConfiForms version 3.10.0

New class that allows you to query other forms for data right inside your Velocity template

Available under "dataLoader" and allows you to query other forms.
Returns a list of RegEntry (ConfiForms Entry (raw)) instances

  • findByFilter(long pageId, String formName)
  • findByFilter(long pageId, String formName, String filter)
  • findByFilter(long pageId, String formName, String filter, String sortedBy)
  • findById(long pageId, String formName, String id)



Very similar to what is available in the context when you develop Confluence user macros: 
https://confluence.atlassian.com/doc/writing-user-macros-4485.html
https://developer.atlassian.com/server/confluence/confluence-objects-accessible-from-velocity/                
              
which you can reference as any other variable in Velocity using velocity syntax, for example: ${page.id} to reference page id of current page

Also, a helpful link from apache 
---- copied from Apache https://wiki.apache.org/velocity/CheckingForNull

Q: I want to check for null, something like this:

#if ($car.fuel == null)

A: There are several approaches. Select the one most suitable depending on what you really want to do. (Thanks, everybody, for all the feedback on the user list.) See also: Bugzilla #20999Bugzilla #27741VelocityNullSupport.

Approach 1: Use the fact that null is evaluated as a false conditional. (cf. http://velocity.apache.org/engine/devel/user-guide.html#Conditionals)

#if( ! $car.fuel )
  • Note: The conditional will also pass if the result of $car.fuel is the boolean false. What this approach is actually checking is whether the reference is null or false.

Approach 2: Use the fact that null is evaluated as an empty string in quiet references. (cf. http://velocity.apache.org/engine/devel/user-guide.html#quietreferencenotation)

#if( "$!car.fuel" == "" )
  • Note: The conditional will also pass if the result of $car.fuel is an empty String. What this approach is actually checking is whether the reference is null or empty.

BTW, just checking for empty can be achieved by:

#if( "$car.fuel" == "" )

Approach 3: Combine Approach 1 and 2. This will check for null and null only.

#if ((! $car.fuel) && ("$!car.fuel" == ""))
  • Note: The logic underlying here is that: "(null or false) and (null or > empty-string)" => if true, must be null. This is true because "false and empty-string and not null" is never true. IMHO, this makes the template too complicated to read.

Approach 4: Use a Tool that can check for null (NullTool,ViewNullTool).

#if( $null.isNull($car.fuel) )
  • Note: Of course, NullTool must be in the Context as $null in this case (in ConfiForms it is included into the context under "null" variable name).

In ConfiForms version 2.15.3+ we have extended NullTool to have 2 more convenient methods (isNullOrEmpty and isNotNullOrEmpty) to check if the value is null or empty


isNull
isNullOrEmpty
isNotNull
isNotNullOrEmpty


Approach 5: Don't check for null directly, use a self-explaining method.

#if( $car.fuelEmpty )
  • Note: This is my (Shinobu Kawai's) recommended solution. You have to implement the method, but it makes the template so easy-to-read.


public boolean isFuelEmpty()
{
  // return true if fuel is empty.
}

Approach 6: Use a custom directive. cf. IfNullDirectiveIfNotNullDirective

#ifnull( $car.fuel )
#ifnotnull( $car.fuel )
  • Note: You will have to register the directive in your velocity.properties.


userdirective = org.apache.velocity.tools.generic.directive.Ifnull
userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull

Result type:

Page object (page created)

Depending on the IFTTT result name you can access all of the properties available from Page object.

For example (when result name is MYRESULT)

${iftttResult_MYRESULT.id}
${iftttResult_MYRESULT.spaceKey}
${iftttResult_MYRESULT.displayTitle}
...

Same can be archived with 
[iftttResult_MYRESULT.id]
[iftttResult_MYRESULT.spaceKey]
[iftttResult_MYRESULT.displayTitle]
since ConfiForms version 2.11

Any other property, which Page object provides (any "get" method)

More details / examples:

You can create a page based on the template in this IFTTT macro body. You can have a template embedded or you can reference Confluence template with

[template.TEMPLATE_NAME]

Templates can reference field values using 

  • [entry.FIELD_NAME] to embed the values statically
  • using ConfiForms Field macro to have a dynamic reference to original form, so when the value is changed in the original form then it will get's changed in the page created


You can set your own root page (also dynamically based on the values in your entries, as usual... by referencing via [entry.FIELD_NAME]), you can enable custom permissions on newly created pages 

Additional tutorials:

IFTTT macro body evaluates as Velocity template
Macro body is evaluated as Velocity Template! This allows you to use #if #end constructions around JSON mapping parts.

Field values are stored in Velocity templates under field names!

For multi-value holding fields and for the single choice fields, like dropdowns, radio group fields, etc the field is always present in the context and has the value, so you cannot check it with 

#if(${somefield})
#end

as it will always be evaluated to true, but you can check if it has any values

--- check if field has no values

#if(${somefield.isEmpty()})
#end

--- check if the field is NOT empty and has values
#if(!${somefield.isEmpty()})
#end

Single choice field

--- get id
#if(${somefield.id})
#end   

--- get label
#if(${somefield.label})
#end


Checking if multi-value field has certain label or id

--- check if field has label (stored in values)
#if(${somefield.hasLabel("some_label")})
#end   

--- check if field has id (stored in values)
#if(${somefield.hasId("some_id")})
#end


Also, there is standard set of objects inside the context

context.put("entry", entry); <- ConfiForms Entry (raw)
context.put("user", user); <- Confluence user object
context.put("page", contentObject); <- AbstractPage object


Since ConfiForms version 1.49.3 there are additional objects in the context:

context.put("generalUtil", new com.atlassian.confluence.util.GeneralUtil());
context.put("res", ServletActionContext.getResponse());
context.put("req", ServletActionContext.getRequest());
context.put("action", com.atlassian.confluence.renderer.radeox.macros.MacroUtils.getConfluenceActionSupport());


Since ConfiForms version 2.27.3

context.put("null", new NullTool()); // helper tool to check for nulls https://cwiki.apache.org/confluence/display/velocity/NullTool
context.put("esc", new EscapeTool()); // helper tool to escape values https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/EscapeTool.html
context.put("list", new ListTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/ListTool.html
context.put("iter", new IteratorTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/IteratorTool.html

See Apache velocity tools for detailed documentation on these helper classes


Since ConfiForms version 3.10.0

New class that allows you to query other forms for data right inside your Velocity template

Available under "dataLoader" and allows you to query other forms.
Returns a list of RegEntry (ConfiForms Entry (raw)) instances

  • findByFilter(long pageId, String formName)
  • findByFilter(long pageId, String formName, String filter)
  • findByFilter(long pageId, String formName, String filter, String sortedBy)
  • findById(long pageId, String formName, String id)



Very similar to what is available in the context when you develop Confluence user macros: 
https://confluence.atlassian.com/doc/writing-user-macros-4485.html
https://developer.atlassian.com/server/confluence/confluence-objects-accessible-from-velocity/                
              
which you can reference as any other variable in Velocity using velocity syntax, for example: ${page.id} to reference page id of current page

Also, a helpful link from apache 
---- copied from Apache https://wiki.apache.org/velocity/CheckingForNull

Q: I want to check for null, something like this:

#if ($car.fuel == null)

A: There are several approaches. Select the one most suitable depending on what you really want to do. (Thanks, everybody, for all the feedback on the user list.) See also: Bugzilla #20999Bugzilla #27741VelocityNullSupport.

Approach 1: Use the fact that null is evaluated as a false conditional. (cf. http://velocity.apache.org/engine/devel/user-guide.html#Conditionals)

#if( ! $car.fuel )
  • Note: The conditional will also pass if the result of $car.fuel is the boolean false. What this approach is actually checking is whether the reference is null or false.

Approach 2: Use the fact that null is evaluated as an empty string in quiet references. (cf. http://velocity.apache.org/engine/devel/user-guide.html#quietreferencenotation)

#if( "$!car.fuel" == "" )
  • Note: The conditional will also pass if the result of $car.fuel is an empty String. What this approach is actually checking is whether the reference is null or empty.

BTW, just checking for empty can be achieved by:

#if( "$car.fuel" == "" )

Approach 3: Combine Approach 1 and 2. This will check for null and null only.

#if ((! $car.fuel) && ("$!car.fuel" == ""))
  • Note: The logic underlying here is that: "(null or false) and (null or > empty-string)" => if true, must be null. This is true because "false and empty-string and not null" is never true. IMHO, this makes the template too complicated to read.

Approach 4: Use a Tool that can check for null (NullTool,ViewNullTool).

#if( $null.isNull($car.fuel) )
  • Note: Of course, NullTool must be in the Context as $null in this case (in ConfiForms it is included into the context under "null" variable name).

In ConfiForms version 2.15.3+ we have extended NullTool to have 2 more convenient methods (isNullOrEmpty and isNotNullOrEmpty) to check if the value is null or empty


isNull
isNullOrEmpty
isNotNull
isNotNullOrEmpty


Approach 5: Don't check for null directly, use a self-explaining method.

#if( $car.fuelEmpty )
  • Note: This is my (Shinobu Kawai's) recommended solution. You have to implement the method, but it makes the template so easy-to-read.


public boolean isFuelEmpty()
{
  // return true if fuel is empty.
}

Approach 6: Use a custom directive. cf. IfNullDirectiveIfNotNullDirective

#ifnull( $car.fuel )
#ifnotnull( $car.fuel )
  • Note: You will have to register the directive in your velocity.properties.


userdirective = org.apache.velocity.tools.generic.directive.Ifnull
userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull




Delete Attachment



SERVER/DC

CLOUD

Deletes attachments from Confluence. A user must have enough permissions to delete attachments

Attachment ID could be extracted from a file/attachment field value in ConfiForms as follows - using Virtual functions 

(in case of ONE attachment)

[entry.myattachmentfield.asAttachment.id]

(in case if you field holds links to multiple attachments)

[entry.myattachmentfield.asAttachments.transform(id).asList]


Also, some user handy macro to see attachment IDs Attachments list

Result type:
NO RESULT



Delete ConfiForms Entry



SERVER/DC

CLOUD

Deletes the ConfiForms entries by a given filter


You can automatically delete entries, and this is done by specifying a filter. When you want to delete just a record created then the filter is by id:

id:[entry.id]

Important difference (between Creating and Deleting actions) here is the name of the field used to reference entry ID. In filters you need to specify it as "id" and in field parameters you will need to use "entryId"

So, deleting entries happens by filter, more about filters ConfiForms Filters

You will need also to specify explicitly which form to use and where it is located (pageId). See last parameter in Macro editor for ConfiForms IFTTT macro for this action type


Tutorials:


Result type:
NO RESULT



Delete Page




Deletes the page in Confluence

A user must have enough permissions to delete the page

Result type:

Page object to be deleted

Depending on the IFTTT result name you can access all of the properties available from Page object.

For example (when result name is MYRESULT)

${iftttResult_MYRESULT.id}
${iftttResult_MYRESULT.spaceKey}
${iftttResult_MYRESULT.displayTitle}
...

Same can be archived with 
[iftttResult_MYRESULT.id]
[iftttResult_MYRESULT.spaceKey]
[iftttResult_MYRESULT.displayTitle]
since ConfiForms version 2.11

Any other property, which Page object provides (any "get" method)




Force Page Re-index



SERVER/DC

Forces page re-index

Sometimes you want a particular page to be re-indexed when a ConfiForms entry get's created/updated or deleted. This action type helps you to achieve that.

Result type:

Resolved Page object to re-index

Depending on the IFTTT result name you can access all of the properties available from Page object.

For example (when result name is MYRESULT)

${iftttResult_MYRESULT.id}
${iftttResult_MYRESULT.spaceKey}
${iftttResult_MYRESULT.displayTitle}
...

Same can be archived with 
[iftttResult_MYRESULT.id]
[iftttResult_MYRESULT.spaceKey]
[iftttResult_MYRESULT.displayTitle]
since ConfiForms version 2.11

Any other property, which Page object provides (any "get" method)

Generate Next Number


(experimental)

SERVER/DC


Generates (based on the filtering criteria) and sets next number on the configured field

On highly concurrent systems this may generate duplicates. We are working on improving this. At the moment this is an experimental functionality

See quick tutorial on this here: Using generate next number IFTTT rule and Using generate next number IFTTT rule to have sequence numbers per day

Result type:

NO RESULT




Move Attachment



SERVER/DC

CLOUD

Moves attachment from one page to another

You should specify the attachment ID to be moved and the page destination it should be moved to. A user must have enough permissions to attach the file to a destination page and enough permissions to read the configured attachment.

Can move multiple attachments in one go, See Virtual functions for "asAttachment" function to see how

Result type:
NO RESULT



Move Page



SERVER/DC

CLOUD

Moves page from one location to another

A user performing an operation should have enough permissions (to move the page from source location to destination location)

Result type:

Moved page as object. Any property a Page object has

For example (when result name is MYRESULT)

${iftttResult_MYRESULT.id}
${iftttResult_MYRESULT.spaceKey}
${iftttResult_MYRESULT.displayTitle}
...

Same can be archived with 
[iftttResult_MYRESULT.id]
[iftttResult_MYRESULT.spaceKey]
[iftttResult_MYRESULT.displayTitle]
since ConfiForms version 2.11

Any other property, which Page object provides (any "get" method)




Redirect to URL



SERVER/DC


Redirects to given URL (server side forward if no timeout is given and if timeout is given then via JavaScript)

You can give timeout in a way: url|timeout

(in milliseconds)

Result type
NO RESULT



Remove Attachment Label



SERVER/DC

Removes a label from attachment or attachments
Result type:
NO RESULT



Remove Page Label



SERVER/DC

CLOUD

Removes page label(s). Silently ignores if a page does not have a requested label to be removed
Result type:

Page object, Any property a Page object  via

${iftttResult_MYRESULT.<PAGE_OBJECT_PROPERTY>}


Same can be archived with 
[iftttResult_MYRESULT.<PAGE_OBJECT_PROPERTY>]
since ConfiForms version 2.11





Remove Page Edit Restrictions



SERVER/DC

Action to help you to remove page edit restrictions. It is safe to attempt to remove page restrictions for a user, even if this user has no restrictions set
Result type:

Page object, Any property a Page object via

${iftttResult_MYRESULT.<PAGE_OBJECT_PROPERTY>}

Same can be archived with 
[iftttResult_MYRESULT.<PAGE_OBJECT_PROPERTY>]
since ConfiForms version 2.11

Remove Page View Restrictions



SERVER/DC

Action to help you to remove page view restrictions. It is safe to attempt to remove page restrictions for a user, even if this user has no restrictions set
Result type:

Page object, Any property a Page object via

${iftttResult_MYRESULT.<PAGE_OBJECT_PROPERTY>}

Same can be archived with 
[iftttResult_MYRESULT.<PAGE_OBJECT_PROPERTY>]
since ConfiForms version 2.11

Remove Page Watcher



SERVER/DC

CLOUD

Removes page watcher or watchers from the page

Silently ignores if a page does not have a requested watcher to be removed.

Result type:

Page object, Any property a Page object via

${iftttResult_MYRESULT.<PAGE_OBJECT_PROPERTY>}

Same can be archived with 
[iftttResult_MYRESULT.<PAGE_OBJECT_PROPERTY>]
since ConfiForms version 2.11



Rename Page



SERVER/DC

CLOUD

Renames a page

A user performing an operation should have enough permissions to modify the page

Result type:

Page object, Any property a Page object via

${iftttResult_MYRESULT.<PAGE_OBJECT_PROPERTY>}

Same can be archived with 
[iftttResult_MYRESULT.<PAGE_OBJECT_PROPERTY>]
since ConfiForms version 2.11



Restrict Page Edit



SERVER/DC

Restricts page edit permissions to certain users / editors
Result type:

Page object, Any property a Page object via

${iftttResult_MYRESULT.<PAGE_OBJECT_PROPERTY>}

Same can be archived with 
[iftttResult_MYRESULT.<PAGE_OBJECT_PROPERTY>]
since ConfiForms version 2.11



Restrict Page View



SERVER/DC

Restricts page view permissions to certain users only
Result type:

Page object, Any property a Page object via

${iftttResult_MYRESULT.<PAGE_OBJECT_PROPERTY>}

Same can be archived with 
[iftttResult_MYRESULT.<PAGE_OBJECT_PROPERTY>]
since ConfiForms version 2.11



Render (execute) macro




SERVER/DC

Renders a contents of it's body and adds the result of a render into a result chain

Result type:

What render macro renders, as string

${iftttResult_MYRESULT}

Same can be archived with 
[iftttResult_MYRESULT]
since ConfiForms version 2.11



Run JavaScript




SERVER/DC

Executes a JavaScript snippet given in the IFTTT macro body

Code snippet is executed in the "init" block

<script type="text/javascript">
  AJS.toInit(function() {
      ...
      YOUR CODE WILL BE HERE
      ...
  });
</script>

And will be executed on a page load. Administrators could restrict this in ConfiForms general settings!

Macro body:

JSON mapping wrapped in "No Format" or in "Code" macro to have a raw text

Template / content to use to generate the contents
You can reference any field value using [entry.fieldname] notation, more on this Accessing field values and properties

Result type:

An internal object holding a JavaScript snippet

You can access script value (as text)

${iftttResult_MYRESULT.script}or${iftttResult_MYRESULT}

Same can be archived with 
[iftttResult_MYRESULT]
since ConfiForms version 2.11

(when IFTTT result is called "MYRESULT")




Send Email



SERVER/DC

CLOUD

Send email to a recipient or a group of recipients

Each email is sent individually

To add ConfiForms file field to an email as attachment - place ConfiForms Field macro into the IFTTT macro body


Email server configured in your Confluence server is used for sending the emails

Emails sent by ConfiForms are NOT queued and sent immediately (to avoid "bulk" message flags, and sent "individual and personal" direct messages)

Macro body:

Is the template to be used to construct an email message body

See more on Sending an email with attachments from Confluence with ConfiForms app

Template / content to use to generate the contents
You can reference any field value using [entry.fieldname] notation, more on this Accessing field values and properties

IFTTT macro body evaluates as Velocity template
Macro body is evaluated as Velocity Template! This allows you to use #if #end constructions around JSON mapping parts.

Field values are stored in Velocity templates under field names!

For multi-value holding fields and for the single choice fields, like dropdowns, radio group fields, etc the field is always present in the context and has the value, so you cannot check it with 

#if(${somefield})
#end

as it will always be evaluated to true, but you can check if it has any values

--- check if field has no values

#if(${somefield.isEmpty()})
#end

--- check if the field is NOT empty and has values
#if(!${somefield.isEmpty()})
#end

Single choice field

--- get id
#if(${somefield.id})
#end   

--- get label
#if(${somefield.label})
#end


Checking if multi-value field has certain label or id

--- check if field has label (stored in values)
#if(${somefield.hasLabel("some_label")})
#end   

--- check if field has id (stored in values)
#if(${somefield.hasId("some_id")})
#end


Also, there is standard set of objects inside the context

context.put("entry", entry); <- ConfiForms Entry (raw)
context.put("user", user); <- Confluence user object
context.put("page", contentObject); <- AbstractPage object


Since ConfiForms version 1.49.3 there are additional objects in the context:

context.put("generalUtil", new com.atlassian.confluence.util.GeneralUtil());
context.put("res", ServletActionContext.getResponse());
context.put("req", ServletActionContext.getRequest());
context.put("action", com.atlassian.confluence.renderer.radeox.macros.MacroUtils.getConfluenceActionSupport());


Since ConfiForms version 2.27.3

context.put("null", new NullTool()); // helper tool to check for nulls https://cwiki.apache.org/confluence/display/velocity/NullTool
context.put("esc", new EscapeTool()); // helper tool to escape values https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/EscapeTool.html
context.put("list", new ListTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/ListTool.html
context.put("iter", new IteratorTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/IteratorTool.html

See Apache velocity tools for detailed documentation on these helper classes


Since ConfiForms version 3.10.0

New class that allows you to query other forms for data right inside your Velocity template

Available under "dataLoader" and allows you to query other forms.
Returns a list of RegEntry (ConfiForms Entry (raw)) instances

  • findByFilter(long pageId, String formName)
  • findByFilter(long pageId, String formName, String filter)
  • findByFilter(long pageId, String formName, String filter, String sortedBy)
  • findById(long pageId, String formName, String id)



Very similar to what is available in the context when you develop Confluence user macros: 
https://confluence.atlassian.com/doc/writing-user-macros-4485.html
https://developer.atlassian.com/server/confluence/confluence-objects-accessible-from-velocity/                
              
which you can reference as any other variable in Velocity using velocity syntax, for example: ${page.id} to reference page id of current page

Also, a helpful link from apache 
---- copied from Apache https://wiki.apache.org/velocity/CheckingForNull

Q: I want to check for null, something like this:

#if ($car.fuel == null)

A: There are several approaches. Select the one most suitable depending on what you really want to do. (Thanks, everybody, for all the feedback on the user list.) See also: Bugzilla #20999Bugzilla #27741VelocityNullSupport.

Approach 1: Use the fact that null is evaluated as a false conditional. (cf. http://velocity.apache.org/engine/devel/user-guide.html#Conditionals)

#if( ! $car.fuel )
  • Note: The conditional will also pass if the result of $car.fuel is the boolean false. What this approach is actually checking is whether the reference is null or false.

Approach 2: Use the fact that null is evaluated as an empty string in quiet references. (cf. http://velocity.apache.org/engine/devel/user-guide.html#quietreferencenotation)

#if( "$!car.fuel" == "" )
  • Note: The conditional will also pass if the result of $car.fuel is an empty String. What this approach is actually checking is whether the reference is null or empty.

BTW, just checking for empty can be achieved by:

#if( "$car.fuel" == "" )

Approach 3: Combine Approach 1 and 2. This will check for null and null only.

#if ((! $car.fuel) && ("$!car.fuel" == ""))
  • Note: The logic underlying here is that: "(null or false) and (null or > empty-string)" => if true, must be null. This is true because "false and empty-string and not null" is never true. IMHO, this makes the template too complicated to read.

Approach 4: Use a Tool that can check for null (NullTool,ViewNullTool).

#if( $null.isNull($car.fuel) )
  • Note: Of course, NullTool must be in the Context as $null in this case (in ConfiForms it is included into the context under "null" variable name).

In ConfiForms version 2.15.3+ we have extended NullTool to have 2 more convenient methods (isNullOrEmpty and isNotNullOrEmpty) to check if the value is null or empty


isNull
isNullOrEmpty
isNotNull
isNotNullOrEmpty


Approach 5: Don't check for null directly, use a self-explaining method.

#if( $car.fuelEmpty )
  • Note: This is my (Shinobu Kawai's) recommended solution. You have to implement the method, but it makes the template so easy-to-read.


public boolean isFuelEmpty()
{
  // return true if fuel is empty.
}

Approach 6: Use a custom directive. cf. IfNullDirectiveIfNotNullDirective

#ifnull( $car.fuel )
#ifnotnull( $car.fuel )
  • Note: You will have to register the directive in your velocity.properties.


userdirective = org.apache.velocity.tools.generic.directive.Ifnull
userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull

Result type:

NO RESULT (for versions of ConfiForms prior to 1.39.2)

FROM VERSION 1.39.2

The following properties are supported from version 1.39.2

subject
body
recipientsCount

This means, you can access it with

${iftttResult_MYRESULT.subject}
${iftttResult_MYRESULT.body}
${iftttResult_MYRESULT.recipientsCount}

Same can be archived with 
[iftttResult_MYRESULT.subject]
[iftttResult_MYRESULT.body]
[iftttResult_MYRESULT.recipientsCount]
since ConfiForms version 2.11
More details / examples:

There is a number of tutorials on using this action type:




Send Notification



SERVER/DC

Sends internal notification to a user (or users) in Confluence

Notification will appear in the top-right corner. The message body is configured using the ConfiForms macro body


This action type send internal Confluence notification to the user specified, the notification will be visible in the "workbox", in the right top corner of Confluence toolbar.

Sending this type of notifications is very similar to Sending email, the difference is only in where the notification ends up. And what you can use for notification message body (defined through the ConfiForms IFTTT macro body) - free to use Confluence formatting macros, as they are correctly shown inside the Confluence notifications workbox.

Confluence Notification could be sent only to a registered user (email notification can be sent to any external email address, unless your email server does not support that)

IFTTT macro body evaluates as Velocity template
Macro body is evaluated as Velocity Template! This allows you to use #if #end constructions around JSON mapping parts.

Field values are stored in Velocity templates under field names!

For multi-value holding fields and for the single choice fields, like dropdowns, radio group fields, etc the field is always present in the context and has the value, so you cannot check it with 

#if(${somefield})
#end

as it will always be evaluated to true, but you can check if it has any values

--- check if field has no values

#if(${somefield.isEmpty()})
#end

--- check if the field is NOT empty and has values
#if(!${somefield.isEmpty()})
#end

Single choice field

--- get id
#if(${somefield.id})
#end   

--- get label
#if(${somefield.label})
#end


Checking if multi-value field has certain label or id

--- check if field has label (stored in values)
#if(${somefield.hasLabel("some_label")})
#end   

--- check if field has id (stored in values)
#if(${somefield.hasId("some_id")})
#end


Also, there is standard set of objects inside the context

context.put("entry", entry); <- ConfiForms Entry (raw)
context.put("user", user); <- Confluence user object
context.put("page", contentObject); <- AbstractPage object


Since ConfiForms version 1.49.3 there are additional objects in the context:

context.put("generalUtil", new com.atlassian.confluence.util.GeneralUtil());
context.put("res", ServletActionContext.getResponse());
context.put("req", ServletActionContext.getRequest());
context.put("action", com.atlassian.confluence.renderer.radeox.macros.MacroUtils.getConfluenceActionSupport());


Since ConfiForms version 2.27.3

context.put("null", new NullTool()); // helper tool to check for nulls https://cwiki.apache.org/confluence/display/velocity/NullTool
context.put("esc", new EscapeTool()); // helper tool to escape values https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/EscapeTool.html
context.put("list", new ListTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/ListTool.html
context.put("iter", new IteratorTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/IteratorTool.html

See Apache velocity tools for detailed documentation on these helper classes


Since ConfiForms version 3.10.0

New class that allows you to query other forms for data right inside your Velocity template

Available under "dataLoader" and allows you to query other forms.
Returns a list of RegEntry (ConfiForms Entry (raw)) instances

  • findByFilter(long pageId, String formName)
  • findByFilter(long pageId, String formName, String filter)
  • findByFilter(long pageId, String formName, String filter, String sortedBy)
  • findById(long pageId, String formName, String id)



Very similar to what is available in the context when you develop Confluence user macros: 
https://confluence.atlassian.com/doc/writing-user-macros-4485.html
https://developer.atlassian.com/server/confluence/confluence-objects-accessible-from-velocity/                
              
which you can reference as any other variable in Velocity using velocity syntax, for example: ${page.id} to reference page id of current page

Also, a helpful link from apache 
---- copied from Apache https://wiki.apache.org/velocity/CheckingForNull

Q: I want to check for null, something like this:

#if ($car.fuel == null)

A: There are several approaches. Select the one most suitable depending on what you really want to do. (Thanks, everybody, for all the feedback on the user list.) See also: Bugzilla #20999Bugzilla #27741VelocityNullSupport.

Approach 1: Use the fact that null is evaluated as a false conditional. (cf. http://velocity.apache.org/engine/devel/user-guide.html#Conditionals)

#if( ! $car.fuel )
  • Note: The conditional will also pass if the result of $car.fuel is the boolean false. What this approach is actually checking is whether the reference is null or false.

Approach 2: Use the fact that null is evaluated as an empty string in quiet references. (cf. http://velocity.apache.org/engine/devel/user-guide.html#quietreferencenotation)

#if( "$!car.fuel" == "" )
  • Note: The conditional will also pass if the result of $car.fuel is an empty String. What this approach is actually checking is whether the reference is null or empty.

BTW, just checking for empty can be achieved by:

#if( "$car.fuel" == "" )

Approach 3: Combine Approach 1 and 2. This will check for null and null only.

#if ((! $car.fuel) && ("$!car.fuel" == ""))
  • Note: The logic underlying here is that: "(null or false) and (null or > empty-string)" => if true, must be null. This is true because "false and empty-string and not null" is never true. IMHO, this makes the template too complicated to read.

Approach 4: Use a Tool that can check for null (NullTool,ViewNullTool).

#if( $null.isNull($car.fuel) )
  • Note: Of course, NullTool must be in the Context as $null in this case (in ConfiForms it is included into the context under "null" variable name).

In ConfiForms version 2.15.3+ we have extended NullTool to have 2 more convenient methods (isNullOrEmpty and isNotNullOrEmpty) to check if the value is null or empty


isNull
isNullOrEmpty
isNotNull
isNotNullOrEmpty


Approach 5: Don't check for null directly, use a self-explaining method.

#if( $car.fuelEmpty )
  • Note: This is my (Shinobu Kawai's) recommended solution. You have to implement the method, but it makes the template so easy-to-read.


public boolean isFuelEmpty()
{
  // return true if fuel is empty.
}

Approach 6: Use a custom directive. cf. IfNullDirectiveIfNotNullDirective

#ifnull( $car.fuel )
#ifnotnull( $car.fuel )
  • Note: You will have to register the directive in your velocity.properties.


userdirective = org.apache.velocity.tools.generic.directive.Ifnull
userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull

Macro body:

Template / content to use to generate the contents
You can reference any field value using [entry.fieldname] notation, more on this Accessing field values and properties

IFTTT macro body evaluates as Velocity template
Macro body is evaluated as Velocity Template! This allows you to use #if #end constructions around JSON mapping parts.

Field values are stored in Velocity templates under field names!

For multi-value holding fields and for the single choice fields, like dropdowns, radio group fields, etc the field is always present in the context and has the value, so you cannot check it with 

#if(${somefield})
#end

as it will always be evaluated to true, but you can check if it has any values

--- check if field has no values

#if(${somefield.isEmpty()})
#end

--- check if the field is NOT empty and has values
#if(!${somefield.isEmpty()})
#end

Single choice field

--- get id
#if(${somefield.id})
#end   

--- get label
#if(${somefield.label})
#end


Checking if multi-value field has certain label or id

--- check if field has label (stored in values)
#if(${somefield.hasLabel("some_label")})
#end   

--- check if field has id (stored in values)
#if(${somefield.hasId("some_id")})
#end


Also, there is standard set of objects inside the context

context.put("entry", entry); <- ConfiForms Entry (raw)
context.put("user", user); <- Confluence user object
context.put("page", contentObject); <- AbstractPage object


Since ConfiForms version 1.49.3 there are additional objects in the context:

context.put("generalUtil", new com.atlassian.confluence.util.GeneralUtil());
context.put("res", ServletActionContext.getResponse());
context.put("req", ServletActionContext.getRequest());
context.put("action", com.atlassian.confluence.renderer.radeox.macros.MacroUtils.getConfluenceActionSupport());


Since ConfiForms version 2.27.3

context.put("null", new NullTool()); // helper tool to check for nulls https://cwiki.apache.org/confluence/display/velocity/NullTool
context.put("esc", new EscapeTool()); // helper tool to escape values https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/EscapeTool.html
context.put("list", new ListTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/ListTool.html
context.put("iter", new IteratorTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/IteratorTool.html

See Apache velocity tools for detailed documentation on these helper classes


Since ConfiForms version 3.10.0

New class that allows you to query other forms for data right inside your Velocity template

Available under "dataLoader" and allows you to query other forms.
Returns a list of RegEntry (ConfiForms Entry (raw)) instances

  • findByFilter(long pageId, String formName)
  • findByFilter(long pageId, String formName, String filter)
  • findByFilter(long pageId, String formName, String filter, String sortedBy)
  • findById(long pageId, String formName, String id)



Very similar to what is available in the context when you develop Confluence user macros: 
https://confluence.atlassian.com/doc/writing-user-macros-4485.html
https://developer.atlassian.com/server/confluence/confluence-objects-accessible-from-velocity/                
              
which you can reference as any other variable in Velocity using velocity syntax, for example: ${page.id} to reference page id of current page

Also, a helpful link from apache 
---- copied from Apache https://wiki.apache.org/velocity/CheckingForNull

Q: I want to check for null, something like this:

#if ($car.fuel == null)

A: There are several approaches. Select the one most suitable depending on what you really want to do. (Thanks, everybody, for all the feedback on the user list.) See also: Bugzilla #20999Bugzilla #27741VelocityNullSupport.

Approach 1: Use the fact that null is evaluated as a false conditional. (cf. http://velocity.apache.org/engine/devel/user-guide.html#Conditionals)

#if( ! $car.fuel )
  • Note: The conditional will also pass if the result of $car.fuel is the boolean false. What this approach is actually checking is whether the reference is null or false.

Approach 2: Use the fact that null is evaluated as an empty string in quiet references. (cf. http://velocity.apache.org/engine/devel/user-guide.html#quietreferencenotation)

#if( "$!car.fuel" == "" )
  • Note: The conditional will also pass if the result of $car.fuel is an empty String. What this approach is actually checking is whether the reference is null or empty.

BTW, just checking for empty can be achieved by:

#if( "$car.fuel" == "" )

Approach 3: Combine Approach 1 and 2. This will check for null and null only.

#if ((! $car.fuel) && ("$!car.fuel" == ""))
  • Note: The logic underlying here is that: "(null or false) and (null or > empty-string)" => if true, must be null. This is true because "false and empty-string and not null" is never true. IMHO, this makes the template too complicated to read.

Approach 4: Use a Tool that can check for null (NullTool,ViewNullTool).

#if( $null.isNull($car.fuel) )
  • Note: Of course, NullTool must be in the Context as $null in this case (in ConfiForms it is included into the context under "null" variable name).

In ConfiForms version 2.15.3+ we have extended NullTool to have 2 more convenient methods (isNullOrEmpty and isNotNullOrEmpty) to check if the value is null or empty


isNull
isNullOrEmpty
isNotNull
isNotNullOrEmpty


Approach 5: Don't check for null directly, use a self-explaining method.

#if( $car.fuelEmpty )
  • Note: This is my (Shinobu Kawai's) recommended solution. You have to implement the method, but it makes the template so easy-to-read.


public boolean isFuelEmpty()
{
  // return true if fuel is empty.
}

Approach 6: Use a custom directive. cf. IfNullDirectiveIfNotNullDirective

#ifnull( $car.fuel )
#ifnotnull( $car.fuel )
  • Note: You will have to register the directive in your velocity.properties.


userdirective = org.apache.velocity.tools.generic.directive.Ifnull
userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull

Result type:
NO RESULT



Set Page Revision



SERVER/DC

Updates page with a revision information (timestamp and version)

Revision is inserted into the page storage and that increases the page version and generates all related events (page modified event, etc)

This comes handy when you have other plugins that rely on the page versioning and could trigger corresponding actions when it's changes

Macro body:

EMPTY

Result type:
NO RESULT



Update Jira Issue



SERVER/DC

CLOUD

Updates JIRA issue using given JSON object by calling to https://docs.atlassian.com/software/jira/docs/api/REST/9.2.0/#api/2/issue-editIssue

JIRA issue key must be set as macro parameter, could be looked up dynamically from ConfiForms field

It is a wrapper action to ease the setup of updates to JIRA issue from ConfiForms. Same could be achieved with the help of "Applink service" action

IFTTT macro body should hold a JSON structure to update the JIRA issue (use "No Format" macro to construct JSON structure as-is)

Example:

Another example:

See more on JSON structure the "update JIRA issue" API expects

https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/updating-an-issue-via-the-jira-rest-apis


IFTTT macro body evaluates as Velocity template
Macro body is evaluated as Velocity Template! This allows you to use #if #end constructions around JSON mapping parts.

Field values are stored in Velocity templates under field names!

For multi-value holding fields and for the single choice fields, like dropdowns, radio group fields, etc the field is always present in the context and has the value, so you cannot check it with 

#if(${somefield})
#end

as it will always be evaluated to true, but you can check if it has any values

--- check if field has no values

#if(${somefield.isEmpty()})
#end

--- check if the field is NOT empty and has values
#if(!${somefield.isEmpty()})
#end

Single choice field

--- get id
#if(${somefield.id})
#end   

--- get label
#if(${somefield.label})
#end


Checking if multi-value field has certain label or id

--- check if field has label (stored in values)
#if(${somefield.hasLabel("some_label")})
#end   

--- check if field has id (stored in values)
#if(${somefield.hasId("some_id")})
#end


Also, there is standard set of objects inside the context

context.put("entry", entry); <- ConfiForms Entry (raw)
context.put("user", user); <- Confluence user object
context.put("page", contentObject); <- AbstractPage object


Since ConfiForms version 1.49.3 there are additional objects in the context:

context.put("generalUtil", new com.atlassian.confluence.util.GeneralUtil());
context.put("res", ServletActionContext.getResponse());
context.put("req", ServletActionContext.getRequest());
context.put("action", com.atlassian.confluence.renderer.radeox.macros.MacroUtils.getConfluenceActionSupport());


Since ConfiForms version 2.27.3

context.put("null", new NullTool()); // helper tool to check for nulls https://cwiki.apache.org/confluence/display/velocity/NullTool
context.put("esc", new EscapeTool()); // helper tool to escape values https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/EscapeTool.html
context.put("list", new ListTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/ListTool.html
context.put("iter", new IteratorTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/IteratorTool.html

See Apache velocity tools for detailed documentation on these helper classes


Since ConfiForms version 3.10.0

New class that allows you to query other forms for data right inside your Velocity template

Available under "dataLoader" and allows you to query other forms.
Returns a list of RegEntry (ConfiForms Entry (raw)) instances

  • findByFilter(long pageId, String formName)
  • findByFilter(long pageId, String formName, String filter)
  • findByFilter(long pageId, String formName, String filter, String sortedBy)
  • findById(long pageId, String formName, String id)



Very similar to what is available in the context when you develop Confluence user macros: 
https://confluence.atlassian.com/doc/writing-user-macros-4485.html
https://developer.atlassian.com/server/confluence/confluence-objects-accessible-from-velocity/                
              
which you can reference as any other variable in Velocity using velocity syntax, for example: ${page.id} to reference page id of current page

Also, a helpful link from apache 
---- copied from Apache https://wiki.apache.org/velocity/CheckingForNull

Q: I want to check for null, something like this:

#if ($car.fuel == null)

A: There are several approaches. Select the one most suitable depending on what you really want to do. (Thanks, everybody, for all the feedback on the user list.) See also: Bugzilla #20999Bugzilla #27741VelocityNullSupport.

Approach 1: Use the fact that null is evaluated as a false conditional. (cf. http://velocity.apache.org/engine/devel/user-guide.html#Conditionals)

#if( ! $car.fuel )
  • Note: The conditional will also pass if the result of $car.fuel is the boolean false. What this approach is actually checking is whether the reference is null or false.

Approach 2: Use the fact that null is evaluated as an empty string in quiet references. (cf. http://velocity.apache.org/engine/devel/user-guide.html#quietreferencenotation)

#if( "$!car.fuel" == "" )
  • Note: The conditional will also pass if the result of $car.fuel is an empty String. What this approach is actually checking is whether the reference is null or empty.

BTW, just checking for empty can be achieved by:

#if( "$car.fuel" == "" )

Approach 3: Combine Approach 1 and 2. This will check for null and null only.

#if ((! $car.fuel) && ("$!car.fuel" == ""))
  • Note: The logic underlying here is that: "(null or false) and (null or > empty-string)" => if true, must be null. This is true because "false and empty-string and not null" is never true. IMHO, this makes the template too complicated to read.

Approach 4: Use a Tool that can check for null (NullTool,ViewNullTool).

#if( $null.isNull($car.fuel) )
  • Note: Of course, NullTool must be in the Context as $null in this case (in ConfiForms it is included into the context under "null" variable name).

In ConfiForms version 2.15.3+ we have extended NullTool to have 2 more convenient methods (isNullOrEmpty and isNotNullOrEmpty) to check if the value is null or empty


isNull
isNullOrEmpty
isNotNull
isNotNullOrEmpty


Approach 5: Don't check for null directly, use a self-explaining method.

#if( $car.fuelEmpty )
  • Note: This is my (Shinobu Kawai's) recommended solution. You have to implement the method, but it makes the template so easy-to-read.


public boolean isFuelEmpty()
{
  // return true if fuel is empty.
}

Approach 6: Use a custom directive. cf. IfNullDirectiveIfNotNullDirective

#ifnull( $car.fuel )
#ifnotnull( $car.fuel )
  • Note: You will have to register the directive in your velocity.properties.


userdirective = org.apache.velocity.tools.generic.directive.Ifnull
userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull


Macro body:

Template / content to use to generate the contents
You can reference any field value using [entry.fieldname] notation, more on this Accessing field values and properties

IFTTT macro body evaluates as Velocity template
Macro body is evaluated as Velocity Template! This allows you to use #if #end constructions around JSON mapping parts.

Field values are stored in Velocity templates under field names!

For multi-value holding fields and for the single choice fields, like dropdowns, radio group fields, etc the field is always present in the context and has the value, so you cannot check it with 

#if(${somefield})
#end

as it will always be evaluated to true, but you can check if it has any values

--- check if field has no values

#if(${somefield.isEmpty()})
#end

--- check if the field is NOT empty and has values
#if(!${somefield.isEmpty()})
#end

Single choice field

--- get id
#if(${somefield.id})
#end   

--- get label
#if(${somefield.label})
#end


Checking if multi-value field has certain label or id

--- check if field has label (stored in values)
#if(${somefield.hasLabel("some_label")})
#end   

--- check if field has id (stored in values)
#if(${somefield.hasId("some_id")})
#end


Also, there is standard set of objects inside the context

context.put("entry", entry); <- ConfiForms Entry (raw)
context.put("user", user); <- Confluence user object
context.put("page", contentObject); <- AbstractPage object


Since ConfiForms version 1.49.3 there are additional objects in the context:

context.put("generalUtil", new com.atlassian.confluence.util.GeneralUtil());
context.put("res", ServletActionContext.getResponse());
context.put("req", ServletActionContext.getRequest());
context.put("action", com.atlassian.confluence.renderer.radeox.macros.MacroUtils.getConfluenceActionSupport());


Since ConfiForms version 2.27.3

context.put("null", new NullTool()); // helper tool to check for nulls https://cwiki.apache.org/confluence/display/velocity/NullTool
context.put("esc", new EscapeTool()); // helper tool to escape values https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/EscapeTool.html
context.put("list", new ListTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/ListTool.html
context.put("iter", new IteratorTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/IteratorTool.html

See Apache velocity tools for detailed documentation on these helper classes


Since ConfiForms version 3.10.0

New class that allows you to query other forms for data right inside your Velocity template

Available under "dataLoader" and allows you to query other forms.
Returns a list of RegEntry (ConfiForms Entry (raw)) instances

  • findByFilter(long pageId, String formName)
  • findByFilter(long pageId, String formName, String filter)
  • findByFilter(long pageId, String formName, String filter, String sortedBy)
  • findById(long pageId, String formName, String id)



Very similar to what is available in the context when you develop Confluence user macros: 
https://confluence.atlassian.com/doc/writing-user-macros-4485.html
https://developer.atlassian.com/server/confluence/confluence-objects-accessible-from-velocity/                
              
which you can reference as any other variable in Velocity using velocity syntax, for example: ${page.id} to reference page id of current page

Also, a helpful link from apache 
---- copied from Apache https://wiki.apache.org/velocity/CheckingForNull

Q: I want to check for null, something like this:

#if ($car.fuel == null)

A: There are several approaches. Select the one most suitable depending on what you really want to do. (Thanks, everybody, for all the feedback on the user list.) See also: Bugzilla #20999Bugzilla #27741VelocityNullSupport.

Approach 1: Use the fact that null is evaluated as a false conditional. (cf. http://velocity.apache.org/engine/devel/user-guide.html#Conditionals)

#if( ! $car.fuel )
  • Note: The conditional will also pass if the result of $car.fuel is the boolean false. What this approach is actually checking is whether the reference is null or false.

Approach 2: Use the fact that null is evaluated as an empty string in quiet references. (cf. http://velocity.apache.org/engine/devel/user-guide.html#quietreferencenotation)

#if( "$!car.fuel" == "" )
  • Note: The conditional will also pass if the result of $car.fuel is an empty String. What this approach is actually checking is whether the reference is null or empty.

BTW, just checking for empty can be achieved by:

#if( "$car.fuel" == "" )

Approach 3: Combine Approach 1 and 2. This will check for null and null only.

#if ((! $car.fuel) && ("$!car.fuel" == ""))
  • Note: The logic underlying here is that: "(null or false) and (null or > empty-string)" => if true, must be null. This is true because "false and empty-string and not null" is never true. IMHO, this makes the template too complicated to read.

Approach 4: Use a Tool that can check for null (NullTool,ViewNullTool).

#if( $null.isNull($car.fuel) )
  • Note: Of course, NullTool must be in the Context as $null in this case (in ConfiForms it is included into the context under "null" variable name).

In ConfiForms version 2.15.3+ we have extended NullTool to have 2 more convenient methods (isNullOrEmpty and isNotNullOrEmpty) to check if the value is null or empty


isNull
isNullOrEmpty
isNotNull
isNotNullOrEmpty


Approach 5: Don't check for null directly, use a self-explaining method.

#if( $car.fuelEmpty )
  • Note: This is my (Shinobu Kawai's) recommended solution. You have to implement the method, but it makes the template so easy-to-read.


public boolean isFuelEmpty()
{
  // return true if fuel is empty.
}

Approach 6: Use a custom directive. cf. IfNullDirectiveIfNotNullDirective

#ifnull( $car.fuel )
#ifnotnull( $car.fuel )
  • Note: You will have to register the directive in your velocity.properties.


userdirective = org.apache.velocity.tools.generic.directive.Ifnull
userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull

Result type:

Issue key as text, accessible directly via result name (for example, if result name is "MYRESULT")

${iftttResult_MYRESULT}
or (see Velocity templates syntax for more on "!" operator)
$!{iftttResult_MYRESULT}

Same can be archived with 
[iftttResult_MYRESULT]
since ConfiForms version 2.11



Update ConfiForms Entries by Filter



SERVER/DC

CLOUD

Updates ConfiForms entries according to the pattern given by filter


Parameters could be set as expressions (similarly to "Create/Update ConfiForms Entry")

You can also have your values be evaluated as expressions and contain Supported math operators, formulas and functions

In this case they should be wrapped in ()

Example:

myfield=(FORMATDATE(NOW()))

myfield=(ZEROIFEMPTY("[entry.anotherfield]"))
Result type:
NO RESULT



WebService Request



SERVER/DC

CLOUD


Fires a request to a webservice


Some examples on Jira intergation

Macro body:

JSON mapping wrapped in "No Format" or in "Code" macro to have a raw text (when you want to send POST/PUT requests with body)

Template / content to use to generate the contents
You can reference any field value using [entry.fieldname] notation, more on this Accessing field values and properties

IFTTT macro body evaluates as Velocity template
Macro body is evaluated as Velocity Template! This allows you to use #if #end constructions around JSON mapping parts.

Field values are stored in Velocity templates under field names!

For multi-value holding fields and for the single choice fields, like dropdowns, radio group fields, etc the field is always present in the context and has the value, so you cannot check it with 

#if(${somefield})
#end

as it will always be evaluated to true, but you can check if it has any values

--- check if field has no values

#if(${somefield.isEmpty()})
#end

--- check if the field is NOT empty and has values
#if(!${somefield.isEmpty()})
#end

Single choice field

--- get id
#if(${somefield.id})
#end   

--- get label
#if(${somefield.label})
#end


Checking if multi-value field has certain label or id

--- check if field has label (stored in values)
#if(${somefield.hasLabel("some_label")})
#end   

--- check if field has id (stored in values)
#if(${somefield.hasId("some_id")})
#end


Also, there is standard set of objects inside the context

context.put("entry", entry); <- ConfiForms Entry (raw)
context.put("user", user); <- Confluence user object
context.put("page", contentObject); <- AbstractPage object


Since ConfiForms version 1.49.3 there are additional objects in the context:

context.put("generalUtil", new com.atlassian.confluence.util.GeneralUtil());
context.put("res", ServletActionContext.getResponse());
context.put("req", ServletActionContext.getRequest());
context.put("action", com.atlassian.confluence.renderer.radeox.macros.MacroUtils.getConfluenceActionSupport());


Since ConfiForms version 2.27.3

context.put("null", new NullTool()); // helper tool to check for nulls https://cwiki.apache.org/confluence/display/velocity/NullTool
context.put("esc", new EscapeTool()); // helper tool to escape values https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/EscapeTool.html
context.put("list", new ListTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/ListTool.html
context.put("iter", new IteratorTool()); // helper tool to work on lists https://velocity.apache.org/tools/2.0/apidocs/org/apache/velocity/tools/generic/IteratorTool.html

See Apache velocity tools for detailed documentation on these helper classes


Since ConfiForms version 3.10.0

New class that allows you to query other forms for data right inside your Velocity template

Available under "dataLoader" and allows you to query other forms.
Returns a list of RegEntry (ConfiForms Entry (raw)) instances

  • findByFilter(long pageId, String formName)
  • findByFilter(long pageId, String formName, String filter)
  • findByFilter(long pageId, String formName, String filter, String sortedBy)
  • findById(long pageId, String formName, String id)



Very similar to what is available in the context when you develop Confluence user macros: 
https://confluence.atlassian.com/doc/writing-user-macros-4485.html
https://developer.atlassian.com/server/confluence/confluence-objects-accessible-from-velocity/                
              
which you can reference as any other variable in Velocity using velocity syntax, for example: ${page.id} to reference page id of current page

Also, a helpful link from apache 
---- copied from Apache https://wiki.apache.org/velocity/CheckingForNull

Q: I want to check for null, something like this:

#if ($car.fuel == null)

A: There are several approaches. Select the one most suitable depending on what you really want to do. (Thanks, everybody, for all the feedback on the user list.) See also: Bugzilla #20999Bugzilla #27741VelocityNullSupport.

Approach 1: Use the fact that null is evaluated as a false conditional. (cf. http://velocity.apache.org/engine/devel/user-guide.html#Conditionals)

#if( ! $car.fuel )
  • Note: The conditional will also pass if the result of $car.fuel is the boolean false. What this approach is actually checking is whether the reference is null or false.

Approach 2: Use the fact that null is evaluated as an empty string in quiet references. (cf. http://velocity.apache.org/engine/devel/user-guide.html#quietreferencenotation)

#if( "$!car.fuel" == "" )
  • Note: The conditional will also pass if the result of $car.fuel is an empty String. What this approach is actually checking is whether the reference is null or empty.

BTW, just checking for empty can be achieved by:

#if( "$car.fuel" == "" )

Approach 3: Combine Approach 1 and 2. This will check for null and null only.

#if ((! $car.fuel) && ("$!car.fuel" == ""))
  • Note: The logic underlying here is that: "(null or false) and (null or > empty-string)" => if true, must be null. This is true because "false and empty-string and not null" is never true. IMHO, this makes the template too complicated to read.

Approach 4: Use a Tool that can check for null (NullTool,ViewNullTool).

#if( $null.isNull($car.fuel) )
  • Note: Of course, NullTool must be in the Context as $null in this case (in ConfiForms it is included into the context under "null" variable name).

In ConfiForms version 2.15.3+ we have extended NullTool to have 2 more convenient methods (isNullOrEmpty and isNotNullOrEmpty) to check if the value is null or empty


isNull
isNullOrEmpty
isNotNull
isNotNullOrEmpty


Approach 5: Don't check for null directly, use a self-explaining method.

#if( $car.fuelEmpty )
  • Note: This is my (Shinobu Kawai's) recommended solution. You have to implement the method, but it makes the template so easy-to-read.


public boolean isFuelEmpty()
{
  // return true if fuel is empty.
}

Approach 6: Use a custom directive. cf. IfNullDirectiveIfNotNullDirective

#ifnull( $car.fuel )
#ifnotnull( $car.fuel )
  • Note: You will have to register the directive in your velocity.properties.


userdirective = org.apache.velocity.tools.generic.directive.Ifnull
userdirective = org.apache.velocity.tools.generic.directive.Ifnotnull

Result type:

Response returned by a call to webservice is accessible directly via result name (for example, if result name is "MYRESULT")

${iftttResult_MYRESULT}

Same can be archived with 
[iftttResult_MYRESULT]
since ConfiForms version 2.11


More documentation and tutorials on ConfiForms IFTTT macro



  • No labels