JSON object to reference

Case

Assume there is a field that has a JSON object as the value which contains the ID of a related asset. We want to migrate both the asset and the content. But the content needs a proper relationship/reference field to the asset, instead of a JSON object.

We need to be able to:

  1. Migrate the asset

  2. Migrate the content

  3. Convert a JSON object with data into a relationship field

Solution

ImpulseSync can do this using the Liquid field manipulator and the idMap filter.

First setup both the asset job and the content job.

In this example, the asset job is a standard with no manipulators or mappings. And the source connector is drupal7 so the contentype is set to "IMPULSE_ASSET"

The second job does have a mapping and manipulators as appropriate to migrate the content. In this example we'll be looking specifically at using the liquid manipulator.

JSON object
{
  "alt": "Head shot of Karen D. Schwartz",
  "entity_modified": "1595540124",
  "fid": "751752",
  "field_file_image_alt_text": {
    "und": [
      {
        "format": null,
        "safe_value": "Head shot of Karen D. Schwartz",
        "value": "Head shot of Karen D. Schwartz"
      }
    ]
  },
  "field_file_image_title_text": {
    "und": [
      {
        "format": null,
        "safe_value": "",
        "value": ""
      }
    ]
  },
  "field_target_site": {
    "und": [
      {
        "revision_id": "2678357",
        "value": "1382747"
      },
      {
        "revision_id": "2678361",
        "value": "1382749"
      }
    ]
  },
  "filemime": "image/jpeg",
  "filename": "Karen_Schwartz.jpg",
  "filesize": "30107",
  "height": 400,
  "metadata": {
    "height": 400,
    "width": 400
  },
  "status": "1",
  "timestamp": "1595540124",
  "type": "image",
  "uid": "12811",
  "uri": "public://Karen_Schwartz.jpg",
  "url": "https://cet.informabi.com/sites/cetbi.com/files/Karen_Schwartz.jpg",
  "uuid": "46ff7743-3132-49a9-80dd-ad12e8cc4cd5",
  "width": 400
}
Liquid template
{% assign assetId = content.und.fields.picture.value | jq: '.fid' | section: '[', ']' | prepend: 'IMPULSE_ASSET::' | idMap: 'content.id', 'IMPULSE_ASSET', 'IMPULSE_ASSET' %}
[{"relations":{"parentIds":{"value":"{{content.id}}"}, "childIds":{"value":"{{assetId}}"}}}]

The JSON object has an attribute fid this is the ID of the content from the source system, but the drupal7 connector combines both the content type and the ID of the content for ID Maps. So, we need to format the ID value as appropriate for the system before using the idMap filter.

The liquid template uses the jq filter to parse out the fid value. And the section filter to clean up the value as necessary by removing the brackets around the value. Then it prepends the content type for the job "IMPULSE_ASSET". Once the formatted ID value is obtained, the idMap filter can be used. The ID map path is set to "content.id" and the source and destination content types are set as "IMPULSE_ASSET" based on the source content type set in the asset job, and the fact that there was no mapping for that job. (If there was a mapping for the job, the destination content type would match the mapped content type.) The returned ID map value is then captured in a variable.

Since the template has the proper destination ID value, we can use the liquid template to build a relationship field to sync. Setting the assetId variable as the value for the childId . Be sure to set the optional config option "Impulse Field Value" for the liquid manipulator to impulseValue. This way the manipulator knows the liquid template is actually a full field, and not just a value of a field.

Once the jobs are configured, you can run the asset job to migrate the dependent asset. Then run the content job to migrate the content and have a relationship field referencing the asset.

Last updated