Skip to main content

Migration Center ANS Maps: Creating a story with related images

You can ingest a single source document into Arc XP that includes multiple related objects (for example, a story with several related images). The Migration Center ANS Maps tool supports this use case, but you must map each part of your source content (such as text and images) to the appropriate ANS templates.

This guide walks you through the required steps.

Before you begin, keep the following key concepts in mind:

  • Images and stories are separate entities in Arc XP.

  • Each has a unique ID (_id or ANS ID) and its own ANS structure.

  • Stories can reference images, and images can be reused across stories.

  • When retrieving a story through the Content API, Arc XP returns de-normalized image data automatically.

  • We recommend creating images before referencing them in a story. This is not required, but recommended.

This example shows minimum ANS for an image reference in a story:

{
    "type": "reference",
    "referent": {
        "id": "RW6FY26ERFJYVXRCUXGPIAOWHE",
        "type": "image"
    }
}

Based on the this example, to create an image reference in ANS of type story, all that is necessary is to know the _id of the image.

Because you control how ANS IDs are created in your Migration Center mapping templates, you must ensure that the method used always produces the same _id when given the same source ID. The generateArcHash function was built for this purpose.  

Provide the generateArcHash function a consistent parameter uniquely identifying the source content both when creating the ANS _id to create the image and when creating a reference to that image.  

First, create a map that maps the smallest part of the source content that represents a single image, to be transformed into ANS of type image. Migration Center then submits the transformed image ANS to Photo Center to create that content. The image ANS output when submitting to your Sandbox environment might look something like this:

{
    "id": "RW6FY26ERFJYVXRCUXGPIAOWHE",
    "version": "0.10.7",
    "type": "image",
    "owner": {
        "id": "sandbox.<yourorgid>"
    },
    "additional_properties": {
        "originalName": "imageName.jpg",
        "originalUrl": "https://example.com/imageName.jpg"          
    }
}

Then create a second ANS mapping template to generate the ANS of type story that holds a reference to the created image(s). You can reference an image in only certain parts of a story’s ANS, including promo_items.basic and content_elements. Refer to the ANS Schema for full details.

Example

As mentioned previously, you need two maps: a story and an image map.

Your story map must convert the images to something like this for the respective field you are mapping.

{
    "type": "reference",
    "referent": {
        "id": "RW6FY26ERFJYVXRCUXGPIAOWHE",
        "type": "image"
    }
}

While your image map must generate ANS that looks similar to this.

{
    "id": "RW6FY26ERFJYVXRCUXGPIAOWHE",
    "version": "0.10.7",
    "type": "image",
    "owner": {
        "id": "sandbox.<yourorgid>"
    },
    "additional_properties": {
        "originalName": "imageName.jpg",
        "originalUrl": "https://example.com/imageName.jpg"          
    }
}    

Let’s assume the script is using the source data:

{
...story metadata,
  id: 'the id of the story',
  images: []
}
import requests
from jmespath import search as jq

storyMapId = 123
imageMapId = 456

def get_content():
    url = "Your API"
    response = requests.request("GET", url)
    return response.json()

def send_source_to_mc(item, mapId):
    // assume we pass in the source fields in the url.
    url = "https://api.{orgId}.arcpublishing.com/migrations/v3/content/source?sourceId={}&sourceType={}&groupId={}".format(
        sourceId, sourceType, groupId)
    payload = json.dumps({
        "sourceContent": item,
        "sourceAdditionalProperties": {
            "transform": {
                "mapId": "{}".format(mapId),
            }
        }})
    headers = {
        'Content-Type': 'application/json',
        'Authorization': f'Bearer ${token}'
    }
    requests.request("POST", url, headers=headers, data=payload)

def submit_source_to_arc():
    response = get_content()
    images = jq("images", response)
    for image in images:
        send_source_to_mc(image, imageMapId)
    send_source_to_mc(response, storyMapId)