Carbon Copy Plus (Premium)

Advanced-UI NOVA-UI

The Carbon Copy Plus allows to automatically populate asset information fields with values coming from node information fields. For this the fields have to have compatible types. The node values can come from an asset's parent nodes (direct trigger) or from the nodes in its node referencing fields. In case there are multiple nodes, possibly from multiple sources, there are aggregation functions to get the desired value. By specifying a scope it can be exactly defined for which assets a configured target is applicable.

An asset is updated if it is in scope and there was an asset event for it (create, update metadata, released, add to/remove from node, version add/activate/delete) or a node metadata update event where the change of the updated node leads to a change of an asset's value. However, node changes that would lead to an asset coming in scope without the node changes leading to potential asset changes cannot be detected (edge case, moving a node with some linked assets is a likely scenario that could lead to this problem, then we can either use the task or trigger a change on the assets, if the assets were moved themselves it would be detected). The value is only updated if the newly calculated value is not the same.

Properties

To be configured in {home}/appserver/conf/custom.properties

If a deprecated property (crossed out) has no description the next propery is a new version of the property and its description still applies.

By using the target name "default" default values for targets can be specified. Replaced by templates in v2+. It's as simple as specifying a template and then all its data is copied before writing the other settings. Like this we have much more flexibility, e.g. we could have more than one default or even create template trees. See *.template and *.templateOnly properties.

General

carbonCopyPlus.license

type: string, required: yes, default: -

The license key for the plugin (product: carbonCopyPlus), provided by brix.

carbonCopyPlus.threadPoolSize

type: integer, required: no, default: 4

The number of threads in the thread pool.

carbonCopyPlus.debounceTimeInSeconds

type: integer, required: no, default: 30, version: 2+

The number of seconds events for assets and nodes are collected before the changes are processed by Carbon Copy Plus.

carbonCopyPlus.{assetTypeId}.assetTypeId

type: comma-separated list of nodeTypeId, required: no, default: -, version: <2

carbonCopyPlus.assetTypeId.{assetTypeId}.assignIfLinkedToNodeTypeIds

type: comma-separated list of nodeTypeId, required: no, default: -, version: 2+

The asset type with the {assetTypeId} is automatically assigned to an asset with no asset type if it is linked to a node with any of the listed node types.

Sources

A target (essentially an information field on an asset) has to have at least one data source (an information field on a node or a tag).

The other important information on the source is the trigger. It specifies which nodes or tags are considered as data sources for an asset (either the nodes to which the asset is directly assigned or the nodes/tags in a specific node/tag referencing information field). It is called trigger because linking an asset to a node or adding a node to the specific asset information field will trigger the copy process.

Because the trigger can be a node or tag referencing information field it is possible to get data from more than one node, therefore it is important to either specify or be aware of the default aggregation function when using those. It's also possible to delay the aggregation and let the target do it. The handling of empty values can be relevant for the aggregation also.

carbonCopyPlus.source.{name}.template

type: source name, required: no, default: -, version: 2+

A source to copy all properties from before setting the other properties. Source has no targetOnly property because a source that is not used in a target is automatically only a template.

carbonCopyPlus.{targetName}.{sourceName}.source

type: information field id, required: yes, default: -, version <2

carbonCopyPlus.source.{name}.sourceFieldId

type: information field id, required: yes, default: -, version: 2+

Source node or tag (v2+) information field id. Has to have the same kind as the target field.

carbonCopyPlus.{targetName}.{sourceName}.trigger

type: information field id, required: no, default: - (direct assigned), version: <2

carbonCopyPlus.source.{name}.trigger

type: direct (literally) or node/tag reference information field id, default: direct, version: 2+

Node or tag (v2+) reference field id or direct assignment if no trigger was specified (<v2) direct (literally, v2+).

carbonCopyPlus.{targetName}.{sourceName}.recursive

type: boolean, required: no, default: false, version: <2

If there is no trigger (direct assignment) then recursive looks at all the nodes in its parent paths.

carbonCopyPlus.source.{name}.triggerRecursive

type: string, required: no, default: none, version: 2+

This specifies how to collect values from parent nodes.

  • no doesn't look at any parent nodes.
  • first takes the node or first parent where source is not empty.
  • allNonEmpty takes all the non-empty values from all parent nodes.
  • all takes all the values from all parents node. The main difference can be seen if emptyValue is not set to ignore, then with "all" we can end up with several empty value substitutes for a single node but with "allNonEmpty" with at most one substitute if there was nothing found at all.
carbonCopyPlus.source.{name}.aggregation

type: string, required: yes, default: default, version: 2+

The aggregation function to use. For many of the aggregation functions the emptyValue property is very important.

Special values (always applicable):

  • default uses or for boolean fields, concatenate for text fields, any for dropdowns, max for dates, union for tag or node referencing fields and sum for numbers.
  • delay collects the values without aggregation and lets the target do it.
  • any takes a random single non-empty value (if there is any). Most useful for dropdowns.

Boolean fields (checkboxes):

  • and
  • or

Node and tag referencing information fields:

  • union
  • intersect

Text information fields (including text area and their localized version, localized just handles each language independently):

  • concatenate

Number information fields (long and double):

  • sum
  • multiply
  • min
  • max
  • average

Dates:

  • min
  • max
carbonCopyPlus.source.{name}.emptyValue

type: string, required: no, default: ignore, version: 2+

What to do with empty (blank) values:

  • ignore (default)
  • default (0 for numbers and dropdowns, false for checkboxes, empty string for text fields and empty set for tag/node referencing fields)
  • {replacement} (item id for dropdowns, integer for number fields, double for double fields, true/false for checkboxes, comma-separated list of tag/node ids for tag/node referencing information fields, string for text fields)
carbonCopyPlus.source.{name}.delimiter

type: string, required: no, default: ,<SPACE>, version: 2+

The delimiter to use for string concatenation. Only relevant for text fields and aggregation function not delay.

White-spaces at the start or the end are ignored in properties files, that's why there are the following substitutes available:

  • <SPACE>
  • <TAB>
  • <LINEBREAK>
carbonCopyPlus.source.{name}.order

type: asc or desc, required: no, default: asc, version: 2+

How to sort the individual parts before concatenating strings.

carbonCopyPlus.source.{name}.shortenSingleLineText

type: comma-separated list of options, required: no, default: before, ellipsis, trim, version: 2+

This defines how to shorten strings for (localized) text fields (max 255 characters).

  • after cuts everything after the 255th character (after concatenation), which is the opposite of before (they are mutually exclusive). Use one of those to reset the other options.
  • before cuts the parts before concatenation
  • ellipsis adds ... at the end if something is cut
  • trim before concatenating and adding the ellipsis (prevents white-spaces before the ellipsis)
carbonCopyPlus.source.{name}.shortenMinLength

type: integer, required: no, default: 10, version: 2+

The minimal length a text can be shortened to, if the string is still too long it will add as many texts as possible and force a delimiter and ellipsis at the end.

carbonCopyPlus.source.{name}.modes

type: comma-separated list of modes, required: no, default: none, version: 2+

Additional modes that can be specified:

  • none can only be used alone, it mainly exists to be able to reset the modes
  • distinct remove duplicate values, only relevant for text

Targets

Targets have an asset information fields to which the data from the specified sources is written. Scopes are also defined on the target. Other than that most properties are similar to the ones of the sources to handle the aggregation of sources.

carbonCopyPlus.target.{name}.template

type: target name, required: no, default: -, version: 2+

The target from which all properties are copied before setting the other ones. This property is not inherited from the template.

carbonCopyPlus.target.{name}.templateOnly

type: boolean, required: no, default: false, version: 2+

If this is set to true then the target is not executed and just used as template for others. This property is not inherited from the template.

carbonCopyPlus.{targetName}.target

type: information field id, required: yes, default: -, version: <2

carbonCopyPlus.target.{name}.informationFieldId

type: information field id, required: yes, default: -, version: 2+

The target asset information field id.

carbonCopyPlus.target.{name}.infoFieldUserId

type: user id, required: no, default: API User, version: 2+

The user ID of the user used to write the target information field.

carbonCopyPlus.target.{name}.sources

type: comma-separated list of source names, required: yes, default: -, version: 2+

The sources for the target.

carbonCopyPlus.target.{name}.scope

type: search util 2 expression, required: no, default: assetId >= 1, version: 2+

Carbon Copy Plus is only triggered on assets within the specified scope.

This does not apply to the reapply task, be sure to set it there as well

carbonCopyPlus.target.{name}.scopeUserId

type: user id, required: no, default: API User, version: 2+

The user ID of the user used to check whether an asset is in scope or not. This allows for additional filter possibilities through permissions.

carbonCopyPlus.target.{name}.aggregation

type: string, required: yes, default: default, version: 2+

The aggregation function to use. Same as for source except that delay is not allowed.

carbonCopyPlus.target.{name}.emptyValue

type: string, required: no, default: ignore, version: 2+

What to do with empty (blank) values when aggregating the values from the sources. Same possible values as for sources.

carbonCopyPlus.{targetName}.delimiter

type: string, required: no, default: ,<SPACE>, version: <2

carbonCopyPlus.target.{name}.delimiter

type: string, required: no, default: ;<SPACE>, version: 2+

Delimiter for text concatenation of the values from the sources, special values: <SPACE>, <TAB>, <LINEBREAK>

carbonCopyPlus.target.{name}.order

type: asc or desc, required: no, default: asc, version: 2+

How to sort the data from the sources before concatenating strings.

carbonCopyPlus.target.{name}.shortenSingleLineText

type: comma-separated list of options, required: no, default: before, ellipsis, trim, version: 2+

This defines how to shorten strings for (localized) text fields, same as for sources.

carbonCopyPlus.target.{name}.shortenMinLength

type: integer, required: no, default: 10, version: 2+

The minimal length a text can be shortened to, if the string is still too long it will add as many texts as possible and force a delimiter and ellipsis at the end.

carbonCopyPlus.target.{name}.modes

type: comma-separated list of modes, required: no, default: none, version: 2+

Additional modes for the target.

  • none is used to reset the modes (can only be used alone)
  • distinct discards duplicates before concatenation
  • keep only writes target fields if they are empty
  • noClear does not clear information fields (very dubious property, not recommended, the task on the other hand has the same property which can be useful)
  • append noderef and tag fields only (since v2.3)
carbonCopyPlus.{targetName}.keep

type: boolean, required:no, default: false, version: <2

Only change value if the target field is empty.

carbonCopyPlus.{targetName}.mode

type: string, required: yes, default: -, version: <2

How to collect values if the target has several sources or trigger fields with multiple nodes in it.

  • INTERSECT, UNION: for node referencing and text information fields
  • AND, OR: for boolean field target, i.e. checkboxes
  • MIN, MAX, SUM: for numbers and dates (no sum for dates)

Task

A task to re-apply the carbon copy initially or after node values have changed.

carbonCopyPlus.task.enabled

type: boolean, required: no, default: true, version: 2+

Set this property to false to disable the completely, this prevents someone from accidentally starting the task.

carbonCopyPlus.task.targets

type: comma-separated list of target names, required: no, default: - (all targets except templates), version: 2+

The targets which should be executed. It is possible to define special targets just used in tasks by defining them as templateOnly and then listing them explicitly.

carbonCopyPlus.task.scope

type: search util 2 expression, required: no, default: assetId >= 1, version: 2+

Define a scope for the task. This property and targets can be useful if there are a lot of assets to only update what is really needed and not everything.

carbonCopyPlus.task.scopeUserId

type: user id, required: no, default: API User, version: 2+

The user ID of the user used to check whether an asset is in scope or not. This allows for additional filter possibilities through permissions.

carbonCopyPlus.task.modes

type: comma-separated list of modes, required: no, default: noClear, version: 2+

  • clear or noClear: the latter prevents the task from clearing information fields, this can be useful because there might never have been any triggers and the target field was maintained manually, in this case the field shouldn't be cleared (on the other hand if we actively remove a trigger the field should be cleared, this would be prevented by the noClear mode on the target and has nothing to do with the task)
carbonCopyPlus.{targetName}.clearInformationFields

type: boolean, required: no, default: true, version: <2

Clear information fields when a trigger becomes empty.

carbonCopyPlus.taskOnlyFiresNonEmptyTriggers

type: boolean, required: no, default: true, version: <2

If this property is set to true then the system task only triggers assets and targets if the target has direct assigned (recursive) sources or the target has sources with non-empty asset trigger fields.

Template (v2)

There are a lot of properties, but most of them usually don't need to be changed. Some hints for a basic configuration:

  • only one source per target
  • aggregation, empty value, trigger recursive and modes (e.g. distinct) is only set on the source (if needed at all) and not on the target
  • source field and target field are the same field (source on node, target on asset)
  • the scope is set on the target (optionally)
carbonCopyPlus.license=
carbonCopyPlus.threadPoolSize=4
carbonCopyPlus.debounceTimeInSeconds=30
carbonCopyPlus.assetTypeId.{assetTypeId}.assignIfLinkedToNodeTypeIds=

carbonCopyPlus.source.{name}.template=
carbonCopyPlus.source.{name}.sourceFieldId=
carbonCopyPlus.source.{name}.trigger=direct
carbonCopyPlus.source.{name}.triggerRecursive=no
carbonCopyPlus.source.{name}.aggregation=default
carbonCopyPlus.source.{name}.emptyValue=ignore
carbonCopyPlus.source.{name}.delimiter=,<SPACE>
carbonCopyPlus.source.{name}.order=asc
carbonCopyPlus.source.{name}.shortenSingleLineText=before,ellipsis,trim
carbonCopyPlus.source.{name}.shortenMinLength=10
carbonCopyPlus.source.{name}.modes=none

carbonCopyPlus.target.{name}.template=
carbonCopyPlus.target.{name}.templateOnly=false
carbonCopyPlus.target.{name}.informationFieldId=
carbonCopyPlus.target.{name}.infoFieldUserId=
carbonCopyPlus.target.{name}.sources=
carbonCopyPlus.target.{name}.scope=assetId >= 1
carbonCopyPlus.target.{name}.sopeUserId=
carbonCopyPlus.target.{name}.aggregation=default
carbonCopyPlus.target.{name}.emptyValue=ignore
carbonCopyPlus.target.{name}.delimiter=;<SPACE>
carbonCopyPlus.target.{name}.order=asc
carbonCopyPlus.target.{name}.shortenSingleLineText=before,ellipsis,trim
carbonCopyPlus.target.{name}.shortenMinLength=10
carbonCopyPlus.target.{name}.modes=none

carbonCopyPlus.task.enabled=true
carbonCopyPlus.task.targets=
carbonCopyPlus.task.scope=assetId >= 1
carbonCopyPlus.task.scopeUserId=
carbonCopyPlus.task.modes=noClear

Example (v1)

carbonCopyPlus.license=...
carbonCopyPlus.actionMenuEnabled=false
carbonCopyPlus.default.delimiter=;<SPACE>
carbonCopyPlus.default.mode=UNION
carbonCopyPlus.default.clearInformationFields=true

# Copy field 104 when assigned through noderef 106
carbonCopyPlus.1.target=104
carbonCopyPlus.1.1.source=104
carbonCopyPlus.1.1.trigger=106
# Copy field 136 when assigned through noderef 106
carbonCopyPlus.2.target=136
carbonCopyPlus.2.1.source=136
carbonCopyPlus.2.1.trigger=106
# Copy from 135 to 149 when assigned through noderef 150
carbonCopyPlus.3.target=149
carbonCopyPlus.3.1.source=135
carbonCopyPlus.3.1.trigger=150

Compatibility Matrix

Carbon Copy Plus CELUM (min. version)
1.0.0 6.4
2.0.0 6.4

Release Notes

1.0.0

Released 2022-08-25

Initial version

2.0.0

Released 2022-12-08

  • All field types are supported as sources and targets
  • Parents, nodes in node referencing fields and tags in tag fields are supported as triggers
  • Assets are updated automatically on asset changes and on node changes that would lead to a different information field value for an asset, but not if only the scope changes and nothing of the previously mentioned properties.
  • Support for various aggregations
  • More flexible configuration supporting inheritance
  • ...
2.1.0

Released 2023-02-16

  • Fixed recursive triggers