Skip to end of metadata
Go to start of metadata

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

Compare with Current View Page History

« Previous Version 6 Next »

 Table of contents

Introduction

If you need to add a field at runtime or change its content, you can use the field processor inside a source.
Field processors are based on handlebars and allow you to use simple methods for manipulating fields.

Field processors can be used inside a source and can either create a new field, or overwrite an existing.

Create a new field (excerpt):

sources:
  source:
    - id: 'MySource'
      fieldProcessor:
        - field: MyNewField
          value: '{{sourceValue}}'

Overwrite an existing field (excerpt):

sources:
  source:
    - id: 'MySource'
      fieldProcessor:
        - field: MyExistingField
          value: '{{MyExistingField}}-SOME_SUFFIX'

It is very advisable to use parantheses inside the configuration for handlebar values:

Good Practice:

      fieldProcessor:
        - field: MyExistingField
          value: '{{MyExistingField}}-SOME_SUFFIX'

Bad Practice:

      fieldProcessor:
        - field: MyExistingField
          value: {{MyExistingField}}-SOME_SUFFIX

Inside an ELO source, handlebars can also be used inside maps/tables - see below examples.

Nesting/Combination of multiple Functions

You can nest multiple functions using “()”

Example:

- field: CLOSE_TO_EXPIRATION
  value: '{{#if (gt (remainingTimeUnit (currentDateTime) (parseDateTime P_LICENSE_M_VALID_TO "yyyy-MM-dd") "days") 30)}}false{{else}}true{{/if}}'

equivalents pseudocode:

function CLOSE_TO_EXPIRATION():
  currentDateTime = currentDateTime() #First Helper
  parsedDateTime = parseDateTime(P_LICENSE_M_VALID_TO, "yyyy-MM-dd")
  remainingDays = remainingTimeUnit(currentDateTime, parsedDateTime, "days")
  if remainingDays > 30:
    return false
  else:
    return true

Working with numbers

If you need the output as number (for example if you use a math operator) the type attribute needs to be added:

      fieldProcessor:
        - field: numberField
          value: {{NumberField}}
          type: number
        - field: BudgetLeft
          value: {{sub BudgetPlanned BudgetLeft}}
          type: number

Format:

The expected number format is in locale en. So "," for decimal comma and optional "." for thousand separator". If there is an issue in the number format or an empty string is given a fallback to decimal zero (0) is in place. When your output of the handlebar is not in this format consider to use "numberFormat" method before.

String

Decimal Value

1,000.00

1000.00

1000.00

1000.00

1 000.00

1000.00

NotANumber

0.0

““ (blank string)

0.0

Working with boolean

If you need the output as boolean the type boolean attribute can be added:

      fieldProcessor:
        - field: BudgetLeft
          value: '{{gt Amount 0}}'
          type: BOOLEAN

Here are some examples on the interpretation

  • TRUEtrue

  • truetrue

  • tRuEtrue

  • Falsefalse

  • notAValidValuefalse

  • (blank) → false

Boolean Helper

In Helper

https://portrait.atlassian.net/wiki/spaces/PA7/pages/1029114243/Field+Processors#IN-Helper

Helper Functions

The following helper functions and their documentation are implemented and based on handlebars.java.

String Helpers

capitalizeFirst

Capitalizes the first character of the value.

{{capitalizeFirst value}}

If the value is “handlebars.java”, the output will be “Handlebars.java".

center

Centers the value in a field of a given width.

{{center value size=19 [pad="char"] }}

If the value is "Handlebars.java", the output will be " Handlebars.java "

cut

Removes all values of arg from the given string.

{{cut value [" "]}}

If the value is "String with spaces", the output will be "Stringwithspaces".


If you need to cut more characters, use it nested and without [ ]:

"{{ cut (cut P_LICENSE_M_LICENSETYPE_RELATION ')' ) '(' }}"

It truncates the “( )” from the GUID.

defaultIfEmpty

If value evaluates to False, uses the given default. Otherwise, uses the value.

{{defaultIfEmpty value "it is empty" }}

If the value is "" (the empty string), the output will be nothing.

join

Joins an array, iterator or an iterable with a string.

{{join value " // " [prefix=""] [suffix=""]}}

If the value is the list ['a', 'b', 'c'], the output will be the string "a // b // c".

ljust

Left-aligns the value in a field of a given width. Argument: field size

{{ljust value 20 [pad=" "] }}

If the value is Handlebars.java, the output will be "Handlebars.java “

rjust

Right-aligns the value in a field of a given width. Argument: field size

{{rjust value 20 [pad=" "] }}

If the value is Handlebars.java, the output will be " Handlebars.java".

substring

Returns a new CharSequence that is a subsequence of this sequence. The subsequence starts with the char value at the specified index and ends with the char value at index end - 1. Arguments: start offset, end offset.

{{substring value 11 }}

If the value is Handlebars.java, the output will be "java".

{{substring value 0 10 }}

If the value is Handlebars.java, the output will be "Handlebars".

{{substring value 5 9 }}

If the value is Handlebars.java, the output will be "bars".

lower

Converts a string into all lowercase.

{{lower value}}

If the value is 'Still MAD At Yoko', the output will be 'still mad at yoko'.

upper

Converts a string into all uppercase.

{{upper value}}

If the value is 'Hello', the output will be 'HELLO'.

slugify

Converts to lowercase, removes non-word characters (alphanumerics and underscores) and converts spaces to hyphens. Also strips leading and trailing whitespace.

{{slugify value}}

If the value is "Joel is a slug", the output will be "joel-is-a-slug".

stringFormat

Formats the variable according to the argument, a string formatting specifier.

{{stringFormat string param0 param1 ... paramN}}

If the value is "Hello %s" "handlebars.java", the output will be * "Hello handlebars.java".

stripTags

Strips all [X]HTML tags.

{{stripTags value}}

capitalize

Capitalizes all the whitespace separated words in a String.

{{ capitalize value [fully=false]}}

If the value is "my first post", the output will be "My First Post".

abbreviate

Truncates a string if it is longer than the specified number of characters. Truncated strings will end with a translatable ellipsis sequence ("..."). Argument: Number of characters to truncate to

{{abbreviate value 13 }}

If the value is "Handlebars rocks", the output will be "Handlebars...".

wordWrap

Wraps words at specified line length.
Argument: number of characters at which to wrap the text

{{ wordWrap value 5 }}

If value is Joel is a slug, the output would be:

Joel
is a
slug

replace

Replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence.

{{ replace value "..." "rocks" }}

If the value is "Handlebars ...", the output will be "Handlebars rocks".

yesNo

Maps values for true, false and (optionally) null, to the strings "yes", * "no", "maybe".

{{yesno value [yes="yes"] [no="no"] maybe=["maybe"] }}

dateFormat

The default date styles.

{{dateFormat date ["format"] [format="format"][tz=timeZone|timeZoneId]}}

Format parameters is one of:

  • "full": full date format. For example: Tuesday, June 19, 2012

  • "long": long date format. For example: June 19, 2012

  • "medium": medium date format. For example: Jun 19, 2012

  • "short": short date format. For example: 6/19/12

  • "pattern": a date pattern.

Otherwise, the default formatter will be used. The format option can be specified as a parameter or hash (a.k.a. named parameter).

numberFormat

Usage:

{{numberFormat number ["format"] [locale=default]}}

Format parameters is one of:

  • "integer": the integer number format

  • "percent": the percent number format

  • "currency": the decimal number format

  • "pattern": a decimal pattern.

Otherwise, the default formatter will be used.

More options:

  • groupingUsed: Set whether or not grouping will be used in this format.

  • maximumFractionDigits: Sets the maximum number of digits allowed in the fraction portion of a number.

  • maximumIntegerDigits: Sets the maximum number of digits allowed in the integer portion of a number

  • minimumFractionDigits: Sets the minimum number of digits allowed in the fraction portion of a number

  • minimumIntegerDigits: Sets the minimum number of digits allowed in the integer portion of a number.

  • parseIntegerOnly: Sets whether or not numbers should be parsed as integers only.

  • roundingMode: Sets the {@link java.math.RoundingMode} used in this NumberFormat.

toFloat

Formats a number value with fixed fractional digits:

{{toFloat PERCENTAGE_VALUE 4}}

now

Print the current date. Usage:

{{now ["format"] [tz=timeZone|timeZoneId]}}

Format parameters is one of:

  • "full": full date format. For example: Tuesday, June 19, 2012

  • "long": long date format. For example: June 19, 2012

  • "medium": medium date format. For example: Jun 19, 2012

  • "short": short date format. For example: 6/19/12

  • "pattern": a date pattern.

Otherwise, the default formatter will be used.

split

Use split functions to generate a list of a single string value.

{{splitByComma PARENT_IDS}}

Input: “1,2,3” Output: "[1,2,3]“ which will be added as an actual JSON array to the index. Useful for Organigram for example. saved JSON

"data": {
  "PARENT_IDS": "4,5",
  "PARENT_IDS_SPLIT": [
      "4",
      "5"
  ],

Following operation are available

splitBySemicolon

regex: ";"

splitByComma

regex: ","

splitByNewLine

regex: "\n"

splitBySpace

regex: " "

splitByPilcrow

regex: "¶"

Mathematics Operations

Use the following functions to apply basic mathematics operations.

If you need the results as number, you need to set the type accordingly!

See the chapter Working with numbers

Addition

Add values:

{{add value1 value2}}

If the value1 is 8 and value2 is 5 the output will be 13.

Subtract

Subtract values:

{{sub value1 value2}}

If the value1 is 8 and value2 is 5 the output will be 3.

Multiply

Multiply values:

{{mul value1 value2}}

If the value1 is 8 and value2 is 5 the output will be 40.

Divide

Multiply values:

{{div value1 value2}}

If the value1 is 8 and value2 is 5 the output will be 1.6.

Date Helpers

These Helpers handle DateTime Objects. This means they always have an included time, in case nothing is provided 00:00:00.

parseDateTime

{{parseDateTime PORTRAIT_DATE "dd.MM.yyyy"}}

formatDateTime

{{formatDateTime PORTRAIT_DATE "dd.MM.yyyy"}}

currentDateTime

{{currentDateTime}}

remainingTimeUnit

{{remainingTimeUnit (currentDateTime) (parseDateTime P_LICENSE_M_VALID_TO "yyyy-MM-dd") "days"}}

The following Time units are supported:

  • seconds

  • minutes

  • hours

  • days

  • weeks

  • months

  • years

List Helper

In combination with split you can use simple loops to create more complex structures.

Details:

https://handlebarsjs.com/guide/builtin-helpers.html#each

Geo-Coding

addressToLatLng

Convert a human readable address into coordinates for showing the address on a map.

{{{addressToLatLng FULL_ADDRESS}}}

If the input is ‘Stephansplatz 1, 1010 Wien’, the output will be ‘48.208710, 16.372670’

Since the Map view expects the field Coordinates, a full example would be:

sources:
  source:
    - id: 'MySource'
      fieldProcessor:
        - field: Coordinates
          value: '{{{addressToLatLng FULL_ADDRESS}}}'

Always use the 3-bracket style.

Geocoding must be configured in the application yaml and relies on a paid external service. See: Geocoding

Conditional Helpers

equals

Test if two elements are equals.

Render 'yes' or 'no':

{{#eq a b}} yes {{else}} no {{/eq}}

Render 'true' or 'false':

{{eq a b}}

Render 'y' or 'n':

{{eq a b yes='y' no='n'}}

not equals

Test if two elements are NOT equals.

Render 'yes' or 'no':

{{#neq a b}} yes {{else}} no {{/neq}}

Render 'true' or 'false':

{{neq a b}}

Render 'y' or 'n':

{{neq a b yes='y' no='n'}}

In

Check if a given value is contained in a given list of other values

{{in SELECT_VACATION_STATUS 'GENEHMIGT' 'ABGELEHNT'}}

Returns a boolean which can be chained

{{and (in SELECT_VACATION_STATUS 'GENEHMIGT' 'ABGELEHNT') (eq CURRENT_STATUS 'OFFEN')}}

Also a combination with various split methods is possible

{{in PORTRAIT_USER_EMAIL (splitBySemicolon EVENT_PARTICIPANTS) 'admin@portrait.com'}}

greater than

Greater operator (arguments must be comparable elements).

Render 'yes' or 'no':

{{#gt a b}} yes {{else}} no {{/gt}}

Render 'true' or 'false':

{gt a b}}

Render 'y' or 'n':

{{neq a b yes='y' no='n'}}

greater or equal

Greater or equal operator (arguments must be comparable) elements.

Render 'yes' or 'no':

{{#gte a b}} yes {{else}} no {{/gte}}

Render 'true' or 'false':

{{gte a b}}

Render 'y' or 'n':

{{gte a b yes='y' no='n'}}

less than

Less than operator (arguments must be comparable elements).

Render 'yes' or 'no':

{{#lt a b}} yes {{else}} no {{/lt}}

Render 'true' or 'false':

{{lt a b}}

Render 'y' or 'n':

{{lt a b yes='y' no='n'}}

less or equal

Less or equal operator (arguments must be {@link Comparable} elements.

Render 'yes' or 'no':

{{#lte a b}} yes {{else}} no {{/lte}}

Render 'true' or 'false':

{{lte a b}}

Render 'y' or 'n':

{{lte a b yes='y' no='n'}}

and

Truthiness of arguments is determined by isEmpty(Object), so this helper can be used with non-boolean values.

Render 'yes' or 'no'

{#and a b}} yes {{else}} no {{/and}}

Multiple arguments are supported too:

{{#and a b c d}} yes {{else}} no {{/and}}

Render 'true' or 'false':

{{and a b}}

Render 'y' or 'n':

{{and a b yes='y' no='n'}}

or

Truthiness of arguments is determined by isEmpty(Object), so this helper can be used with non-boolean values.
Render 'yes' or 'no':

{{#or a b}} yes {{else}} no {{/or}}

Multiple arguments are supported too:

{{#or a b c d}} yes {{else}} no {{/or}

Render 'true' or 'false':

{{or a b}

Render 'y' or 'n':

{{or a b yes='y' no='n'}}

not

Truthiness of arguments is determined by isEmpty(Object) so this helper can be used with non-boolean values.

Render 'yes' or 'no':

{{#not a}} yes {{else}} no {{/not}}

Render 'true' or 'false':

{{not a}}

Render 'y' or 'n':

{{not a yes='y' no='n'}}

Examples

The following examples are embedded in the config.yml annotation:

Call to Actions

If you want to provide a Call-To-Action, but the URI is not given in the source data, you can create your own:

Call

sources:
  source:
    - id: 'MySource'
      fieldProcessor:
        - field: ctaTel
          value: 'tel://{{tel}}'

{{tel}} is the telephone number from the source data in readable format

E-mail

sources:
  source:
    - id: 'MySource'
      fieldProcessor:
        - field: ctaMail
          value: 'mailto://{{email}'

Source data contains the e-mail address in the field {{email}}}

URL’s (Google Maps)

sources:
  source:
    - id: 'MySource'
      fieldProcessor:
        - field: googleMapsCta
          value: 'https://maps.google.at?q={{address}}'

{{adress}} being the Address field from the source data

Replace empty values

sources:
  source:
    - id: 'MySource'
      fieldProcessor:
        - field: ResponsibilityCenter
          value: '{{defaultIfEmpty ResponsibilityCenter "Vienna" }}'

{{ResponsibilityCenter}} is sometimes empty in the source data. This field processor sets “Vienna”, in case the value would have been empty.

Build a Google Maps link based on meta data

The full address of your business partner is available in the source data in the field bp_address (in case of ELO this is the internal group name of the index field = BP_ADDRESS). You want to create a link that can later on used on the UI as an action-button:

sources:
  source:
    - id: 'MySource'
      fieldProcessor:
        - field: googleMapsCta
          value: 'https://maps.google.at?q={{bp_address}}'

Add a field

In this case we need a disclaimer inside Portrait which is not given in the source data. By defining a field name, which is not yet existing, the field disclaimer will be added to each entry:

sources:
  source:
    - id: 'MySource'
      fieldProcessor:
        - field: disclaimer
          value: |
            Objects in the mirror are closer than they appear.

Excerpt - fieldProcessor can be used in a source.

Build a link inside a table

This example shows how to use a fieldProcessor inside an ELO mapping table. This configuration snippet will create a link to an external site, but will only be shown if the field MYAPP_REF_NR is not empty:

        maps:
          - domain: objekte
            name: MYAPP
            type: table
            fieldProcessor:
              - field: LINK_TO_WEBSHOP
                value: '{{#if MYAPP_REF_NR}}[Shop now](https://www.company.com/search?sSearch={{MYAPP_REF_NR}}){{/if}}'

Excerpt - fieldProcessor can be used in a elo map table.

Build a link for ELO Web Client

This example takes the unique key of Portrait (which is in fact the GUID for ELO sources) and embeds into an ELO web Client link:

sources:
  source:
    - id: 'MySource'
      fieldProcessor:
        - field: ctaWebClient
          value: 'http://eloserver:9090/web-Archive/#/archive/{{key}}/'

Build a link for ELO Java Client

This example takes the unique key of Portrait (which is in fact the GUID for ELO sources) and embeds into an ELO Java Client protocol handler link:

sources:
  source:
    - id: 'MySource'
      fieldProcessor:
        - field: ctaJavaClient
          value: 'elodms://({{key}})'

Remove brackets from GUID

In case your GUID is stored with leading trailing brackets, you can remove them with substring.
Example inside a table:

        maps:
          - domain: objekte
            name: MYAPP
            type: table
            fieldProcessor:
              - field: MYAPP_ELOGUID_WO_BRACKETS
                value: '{{substring MYAPP_ELOGUID 1 37 }}'

Shape for Orgchart view | Chained If-Else (aka. case or switch statement)

The Orgchart view supports a rounded shape. The shape should be rounded, if the field CM_TYPE is has two specific values, otherwise use the default - which is rectangle. This is a common issue in case of ELO Business Solutions. The same attribute can have two or more different values, due to the translated labels, which are part of the value. In the example the following logic should be realized:

Input

Output

M - Manager

rounded

M - Vorgesetzter

rounded

T - Teammitglied

rectangle

S - Stellvertreter

rectangle

sources:
  source:
    - id: 'MySource'
      fieldProcessor:
        - field: shape
          value: "{{#eq TYPE 'M - Manager'}}rounded{{ else }}{{#eq TYPE 'V - Vorgesetzter'}}rounded{{ else }}rectangular{{/eq}}{{/eq}}"

This example checks two values - you can extend this as you wish.

Colored Highlights

All views (List view, Orgchart view, Map view and Timeline view) support customizing the highlight color of the entries. Depending on the view different elements are colored. The field key is required to be highlight the value as the hex code of the wanted color e.g. #ff0000
One way to achieve this is with a nested if else statement:

sources:
  source:
    - id: 'MySource'
      fieldProcessor:
        - field: highlight
          value: "{{#eq COUNTRY 'AUT'}}#ff0000{{ else }}{{#eq COUNTRY 'NLD'}}#4287f5{{ else }}#000000{{/eq}}{{/eq}}"

  • No labels