Data transformation
Data transformation lets you create computed attributes that don't exist as-is in Akeneo, and use them in your native field and metafield mappings exactly like a native PIM attribute. A computed attribute can hold a simple constant value, or a value derived from one or more Akeneo attributes through an expression.
Please note that Data transformation is being rolled out progressively. If the Data Transformation tab doesn't appear in your app yet, please contact our support team via this link.
What is a data transformation attribute?
A data transformation attribute is a virtual attribute that you define directly in the app, in the Data Transformation tab. Once created, it behaves like any other Akeneo attribute in your mapping screens: you can select it as the source of a native field, or a metafield - both at the product, product model, and variant level.
You define your data transformation attributes by writing a JSON list directly in the app's editor, in the Data Transformation tab - there's no drag-and-drop form for this yet.
Each data transformation attribute has:
- A Default value, used whenever no transformation is configured, or whenever a transformation returns an empty result.
- An optional Transformation, a rule that computes the attribute's value from one or more Akeneo attributes each time a product is synchronized.
This lets you cover two use cases:
- Constant values that have no equivalent Akeneo attribute (for example, a fixed compliance label to push to every product).
- Computed values built from existing Akeneo attributes (for example, combining a product's name with a reference data label into a single text value).
Supported attribute types
This is the type of the data transformation attribute itself, that is, the value your transformation produces as output. Today, it is always Text.
| Type | Code | Description |
|---|---|---|
| Text | pim_catalog_text |
A simple text attribute. |
Transformation rules
A transformation rule reuses the same transformation service that powers the Transformation block of Akeneo's Catalogs for apps: it computes an attribute's value from one or more Akeneo attributes using that service's expression language. The expression is evaluated by Akeneo on real product data every time the app fetches the attribute's value.
| Transformation type | Code | Description |
|---|---|---|
| Value transformation rule | value_transformation_rule |
Converts a value based on one or more Akeneo attributes and an expression. |
Supported Akeneo attribute types for transformations
Each transformation rule lists, in a pim_attributes array, the Akeneo attributes its expression is allowed to use as input. Unlike the output of the transformation, which is always Text (see Supported attribute types above), these source attributes can be of several types. The following table lists which Akeneo attribute types can currently be referenced this way.
| PIM attribute type | Supported? |
|---|---|
| Text | Yes |
| Text area | Yes |
| Boolean | Yes |
| Simple select | Yes |
| Multi-select | Yes |
| Number | Yes |
| Date and time | Yes |
| Table | Yes |
| Reference entity simple link | No |
| Reference entity multiple links | No |
| Measurement | No |
| Price | No |
Scopable and/or localizable attributes are not supported yet.
Writing an expression
An expression references the Akeneo attributes declared in pim_attributes - not to be confused with the code you set on the data transformation attribute itself in Step 2 below. In the expression, each entry of pim_attributes is referenced by its alias when one is set, or by the Akeneo attribute's own code otherwise. An alias is only required when the same Akeneo attribute is listed more than once, for example once to read its code and once its label (see the example further down). Expressions combine these references using functions. The following functions are available:
| Function | Syntax | Description |
|---|---|---|
CONCATENATE |
CONCATENATE(text1, [text2, ...]) |
Appends several text values together into a single value. |
MERGE |
MERGE(array) |
Joins the values of an array into a single text value, separated by commas. |
FIRST |
FIRST(array) |
Returns the first item of an array or table. |
SPLIT |
SPLIT(text, delimiter, [split_by_each], [remove_empty_text]) |
Splits a text value into an array of text values around a delimiter. |
UPPER |
UPPER(text) |
Converts text to uppercase. |
LOWER |
LOWER(text) |
Converts text to lowercase. |
PROPER |
PROPER(text) |
Capitalizes the first letter of each word. |
DATEFORMAT |
DATEFORMAT(datetime, format) |
Converts a date and time value into a text value with the given format. |
LEFT |
LEFT(text, [number_of_characters]) |
Extracts characters from the beginning of a text value. |
TRIM |
TRIM(text) |
Removes leading, trailing, and repeated spaces. |
REGEXREPLACE |
REGEXREPLACE(text, regular_expression, replacement) |
Replaces the parts of a text value matching a regular expression. |
REGEXEXTRACT |
REGEXEXTRACT(text, regular_expression) |
Extracts the first substring matching a regular expression. |
CLEANHTML |
CLEANHTML(text) |
Removes HTML markup from a text or text area attribute. |
IFS |
IFS(condition1, value1, [condition2, value2, ...]) |
Returns the value tied to the first condition that evaluates to true. |
ISEMPTY |
ISEMPTY(value) |
Tests whether a value is empty or null. |
ROUND |
ROUND(value, [places]) |
Rounds a number to the given number of decimal places. |
TOTEXT |
TOTEXT(number|boolean) |
Converts a number or boolean value into a text value. |
VALUE |
VALUE(text|number) |
Converts a text value or number into a decimal number. |
INT |
INT(text|number) |
Converts a text value or number into an integer. |
MEASUREMENT |
MEASUREMENT(value, unit) |
Creates a measurement value from a number and a unit. Measurement attributes can't be used as a source in this app yet (see Supported Akeneo attribute types for transformations above). |
ARRAYELEMENT |
ARRAYELEMENT(array, index) |
Extracts the element at the given index from an array. |
ARRAYSORT |
ARRAYSORT(array, column_code, [direction]) |
Sorts a table attribute's rows by the values of one of its columns. |
ENTITYRECORDATTRIBUTEVALUE |
ENTITYRECORDATTRIBUTEVALUE(reference_entity_code, record_code, attribute_code, [channel], [locale]) |
Extracts the value of an attribute from a reference entity record. Reference entity attributes can't be used as a source in this app yet (see Supported Akeneo attribute types for transformations above). |
TABLESELECTOPTIONLABEL |
TABLESELECTOPTIONLABEL(table_attribute_code, column_code, option_code, locale) |
Extracts the translated label of a select option from a column of a table attribute. |
TABLEEXTRACT |
TABLEEXTRACT(value) |
Converts a table attribute's value into a JSON text value. |
Functions can be nested; the most deeply nested function is evaluated first, for example CONCATENATE(name, ': ', CLEANHTML(description)).
For more details on each function, see the Akeneo function list. For tips on building an expression step by step, see best practices to onboard the DSL transformation block easily.
Prepare your mapping
Step 1: Open the Data Transformation tab
In your Shopify app, go to the Data Transformation tab, located between Configuration and Products.
Step 2: Define a data transformation attribute
Open the configuration helper panel and use its Attribute tab to see the supported attribute types, view a JSON example, and copy a ready-to-use template into the editor with Add template. Then edit the generated entry:
- Set a unique
codefor the attribute (lowercase letters, digits, and underscores only). - Set the
type(currentlypim_catalog_text). - Optionally set a
labeland adefault_value.
Step 3: Add a transformation rule (optional)
To compute the attribute's value instead of relying only on the default value, use the Transformations tab of the configuration helper. From there you can view the transformation's properties, copy a template with Copy template, or use Add template with Value transformation rule directly next to an attribute template. Then edit the generated transformations entry:
- List the Akeneo attributes the expression needs in
pim_attributes, each with acode. - Add an
aliaswhen an attribute is referenced more than once, or when you need a clearer name to use in the expression. - Add a
propertywhen you need a sub-value of the attribute instead of its raw value, for example thecodeorlabelof a simple or multi select option. - Write the
expression, referencing each attribute by itsalias(or itscodeif no alias is set).
Step 4: Save your mapping
Click Save. The app validates your JSON mapping before saving it. The following rules apply:
- Each attribute
codemust be unique, and eachlabel, when set, must be unique. - An attribute can have at most one transformation.
- An attribute that is already used in a Product, Product variant, or Metafield mapping cannot be removed or have its
codechanged. - Each transformation rule is tested against a sample product; a rule that the expression engine rejects (for example, an invalid expression, or a referenced attribute that doesn't exist) blocks saving until it's fixed.
JSON mapping template
[
{
"code": "",
"type": "pim_catalog_text",
"label": "",
"default_value": "",
"transformations": [
{
"type": "value_transformation_rule",
"pim_attributes": [
{ "code": "" }
],
"expression": ""
}
]
}
]
JSON mapping example
The example below defines two data transformation attributes: a constant value with no transformation, and a computed value built from the product's name and the code and label of a country_of_origin simple select attribute.
[
{
"code": "compliance_label",
"type": "pim_catalog_text",
"label": "Compliance label",
"default_value": "N/A"
},
{
"code": "origin_summary",
"type": "pim_catalog_text",
"label": "Origin summary",
"default_value": "N/A",
"transformations": [
{
"type": "value_transformation_rule",
"pim_attributes": [
{ "code": "name" },
{ "alias": "country_code", "code": "country_of_origin", "property": "code" },
{ "alias": "country_label", "code": "country_of_origin", "property": "label" }
],
"expression": "CONCATENATE(name, ' - ', country_code, ' - ', country_label)"
}
]
}
]
Field descriptions
| Field | Required? | Description |
|---|---|---|
code |
Yes | The attribute code. Lowercase letters, digits, and underscores only (max 57 characters). Must be unique across your data transformation mapping. |
type |
Yes | The attribute type. Must be pim_catalog_text. |
label |
No | A human-readable label for the attribute. Must be unique when set. |
default_value |
No | The value applied when no transformation is configured, or when the transformation returns an empty result. |
transformations |
No | A list of at most one transformation that computes the attribute's value. |
transformations[].type |
Yes* | The transformation type. Must be value_transformation_rule. Required when transformations is set. |
transformations[].pim_attributes |
Yes* | The list of Akeneo attributes referenced by the expression. Required when transformations is set. |
transformations[].pim_attributes[].code |
Yes | The Akeneo attribute code to read the value from. |
transformations[].pim_attributes[].alias |
No | The identifier used in the expression. Defaults to code; required to disambiguate an attribute referenced several times, and must be unique within the rule. |
transformations[].pim_attributes[].property |
No | A sub-property of the attribute to read instead of its raw value, for example code or label of a simple or multi select option. |
transformations[].expression |
Yes* | The expression to apply, referencing the attributes by their alias (or code). Required when transformations is set. |
Use your data transformation attributes in mapping
Once saved, a data transformation attribute appears in the attribute picker of your Products, Products with variants, and Metafields mapping screens, next to your regular Akeneo attributes. Select it as the source of any field or metafield exactly as you would a native PIM attribute, then save your mapping as usual.
The transformation is recomputed on each synchronization, so the value pushed to Shopify always reflects the current Akeneo data.
If the transformation can't be computed for a product during a synchronization (for example, a temporary connectivity issue with Akeneo), the app falls back to the attribute's default_value for that product and reports the synchronization with a warning instead of failing it.