Petal
Import Additional Data to Existing Content Items

Import additional data to already existing content items

Do you have your SEO data in an external system and wish to import it into your existing items? If this is your case, learn how to do it in just a couple of steps.


Matus UsiakPublished on Apr 27, 2021

In this article, we’re going to take a look at how data from an external system can be imported into already existing items. For the sake of this sample, SEO data is going to be used, but this approach works for pretty much any data coming from an external source. This sample is going to work with data in CSV format, which should reflect the structure of the content type in Kontent. 

1. Prepare the content type

With existing items, the content type they are based on already has some elements. Update this type with new fields that reflect the structure of the external system. You have three options to perform this:

curl --request PATCH\
'https://manage.kontent.ai/v2/projects/ProjectId/types/codename/TypeCodename' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YourApiKey' \
--data-raw '[
    {
        "op": "addInto",
        "path": "/elements",
        "value": {
            "name": "Meta title",
            "type": "text"
        }
    },
    {
        "op": "addInto",
        "path": "/elements",
        "value": {
            "name": "Meta description",
            "type": "text"
        }
    },
    {
        "op": "addInto",
        "path": "/elements",
        "value": {
            "name": "Meta keywords",
            "type": "text"
        }
    }
]'
client.modifyContentType()
  //.byTypeId("0be13600-e57c-577d-8108-c8d860330985")
  .byTypeCodename("coffeemaker")
  // .byTypeExternalId("my-article-id")
  .withData(
    [
      {
        op: "addInto",
        path: "/elements",
        value: {
			"name": "Meta title",
			"type": "text"
			}
		},
	  
	  {
        op: "addInto",
        path: "/elements",
        value: {
			"name": "Meta description",
			"type": "text"
			}
		},
	  
	  {
        op: "addInto",
        path: "/elements",
        value: {
			"name": "Meta keywords",
			"type": "text"
			}
		},
    ]
  )
  .toObservable()
  .subscribe((response) => {
    console.log(response);
  },
    (error) => {
      console.log(error);
    });

2. Pair the external data

Inside the CSV file, each row represents one item in Kontent. Pair the correct row with the corresponding item. To ensure this goes smoothly and with no mistakes, you need to decide on an identifier. Using this identifier, you will be able to construct the correct pairs. 

The codenames on the Kontent side are good identifiers as they are always unique. When it comes to the external data, you get to decide based on what the data looks like. It would be best to find a column that corresponds with the codename in Kontent. One thing to look out for is that the chosen column needs to contain unique values.

In the diagram below, you can see how the data can be matched and what it might look like. I’m using a sample where the existing items represent cafe locations in different cities. There is metadata for each city in an external system, which can be seen on the right side. In this case, I’d take the item’s codename property and the CSV’s name property as the identifiers.

Kontent's item vs CSV file's row

If the already existing items were imported via the Management API and not created manually, they might have an external ID assigned to them already. This ID will likely correspond with an ID from the external system, which can be used to get the pairs.

3. Import the external data to Kontent

For the import itself, you can either use the Management API directly or you can make use of the Javascript SDK.
The whole import can be broken down into a few sections, which are as follows:

  • Get the language variants of items using their codenames. Here, take a look at the workflow_step object and note its id
  • Get the IDs of the 'draft' and 'published' workflow steps.
    The code samples below show how the IDs can be obtained via the Javascript SDK. 
// Gets the 'draft' step ID
client.listWorkflowSteps()
  .toObservable()
  .subscribe((response) => {
	for (index in response.data) {
		var workflowStep = response.data[index];
		if (item.name === "Draft") {
			console.log(item.id);
		}
	}
    
  },
    (error) => {
      console.log(error);
    });
// Gets the 'published' step ID
client.listWorkflowSteps()
  .toObservable()
  .subscribe((response) => {
	for (index in response.data) {
		var workflowStep = response.data[index];
		if (item.name === "Published") {
			console.log(item.id);
		}
	}
    
  },
    (error) => {
      console.log(error);
    });
  • Check whether the variant is published or not by comparing the workflow step IDs. Take the 'published' ID from the previous step, and compare it with that included in the variant’s JSON response (first point).
    • If the two IDs match, it means the variant is published and you need to create a new version. Once the new version is created, you can update it and finally publish the new version.
    • If the two IDs do not match, then the variant is not published. Make sure that the item is in the 'draft' workflow step. Once you’ve established that, go ahead with the update. Publish the item if you want it to be public right away or keep it in the 'draft' step based on your preferences.
    • If the variant is not in the 'draft' step, you need to move it to that step before you can update it. 

Results and possible stumbling blocks

After the import is done and everything runs smoothly, you will see the items updated with the new data. If possible, check the items for any duplicates and also to see that they all were updated with the intended data.

One issue you might run into is when Kontent can’t process the imported data. This might happen if, for example, you’re trying to import rich-text data directly to Kontent’s rich text element. Kontent’s rich text element works only with certain HTML tags, attributes, and elements. You can find the specifics in our API reference.

On the other hand, such markup can provide additional formatting or functionality. One of the ways to deal with such data is to create components. Then in your front-end application, you would detect the type of the component and display its contents as desired.

To do this, create a content type for each of those components, and later use them within a Rich text element. The original syntax also needs to be replaced with the new one to match the component. However, keep the business scenario at the forefront of your thinking. When formatting overshadows your content model conception, it creates an overcomplicated content model.

Written by

Matus Usiak

I’m Support Engineer at Kentico who loves to help others to achieve their goal. 

More articles from Matus