One of Content Hub’s biggest selling points as a DAM is its unique flexibility in being able to pull IPTC image metadata (such as the height/weight of an image) into facetable, searchable data within the DAM. But what if we’ve got asset metadata that maps back to a taxonomy item? While this requires a bit more work, we can take IPTC information, query it against known taxonomy items for a given taxonomy, and set the taxonomy item to a member that matches our query.
For our example, we’ll use photographers. We’ve got a taxonomy called “RDA.Photographers”, which contain members that frequently take photographs for our company. In our photographs, these photographer names are applied under the IPTC field name “Byline”. We can see how Content Hub accesses this data by looking in the “Settings” section of Content Hub, and looking at the “ImportMetadataConfiguration” settings under Renditions.
We can see under “byline” on the right that the byline info from the IPTC metadata can be read from the path “IPTC:By-line”. We’ll use this to access our photographer names as they are processed by Content Hub.
To be able to access our image metadata, we need to access the dictionary that contains our image metadata. We’ll use a key-value pair to access the IPTC:By-line data, then store it as a string.
Then, we need to run that string against our taxonomy labels. We’ll start by running a LINQ query against our RDA.Photographers taxonomy to find the taxonomy member label that matches our photographer’s name in the by-line. Keep in mind with our LINQ query that we need to make sure we’re accessing the appropriate culture for our taxonomy item, in this case en-US, which we’ve set beforehand.
Finally, we need to set the relation from the taxonomy item to the asset that is being processed. We have a many-to-many relation already on our M.Asset schema called “PhotographerVideographerToAsset”. We’ll find the ID of our photographer taxonomy item and then set that relation to our asset, making sure to save our asset when we’re done. We’ve got heaps of error handling throughout to make sure we diagnose any errors that may come up. This is where we wind up with our script. Please keep in mind when creating that script that it should be created as a “Metadata Processing” type script in order to work. It doesn’t need any actions or triggers associated with it to create the relation associations on the created assets.
using Newtonsoft.Json.Linq;
using Stylelabs.M.Scripting.Types.V1_0.Processing.Metadata;
using Stylelabs.M.Sdk;
using Stylelabs.M.Sdk.Contracts.Base;
using Stylelabs.M.Base.Querying;
using System.Collections.Generic;
using System.Linq;
using Stylelabs.M.Base.Querying.Linq;
using System.Threading.Tasks;
var entity = Context.Asset;
var properties = Context.MetadataProperties;
string photographerName = "";
// Fetch the photographer name from IPTC metadata
foreach (KeyValuePair<string, JToken> entry in properties)
{
if (entry.Key.Contains("IPTC:By-line"))
{
photographerName = (string)entry.Value;
MClient.Logger.Info("Byline (Photographer Name) found: " + photographerName);
break; // Assuming only one IPTC:By-line is present and relevant
}
}
if (string.IsNullOrEmpty(photographerName))
{
MClient.Logger.Warn("No photographer name found in IPTC metadata.");
}
else
{
MClient.Logger.Info("Photographer name from IPTC: " + photographerName);
}
// Attempt to find the photographer ID dynamically
if (!string.IsNullOrEmpty(photographerName))
{
MClient.Logger.Info("Starting query for photographer with DisplayName matching IPTC data...");
CultureInfo enUs = CultureInfo.GetCultureInfo("en-US");
// Query directly for photographers by display name
var photographerQuery = Query.CreateQuery(entities =>
from e in entities
where e.DefinitionName == "RDA.Photographers"
&& e.Property("TaxonomyLabel", enUs) == photographerName
select e);
var photographerItems = await MClient.Querying.QueryAsync(photographerQuery).ConfigureAwait(false);
MClient.Logger.Info($"Item count:" + photographerItems.Items.Count);
if (photographerItems.Items.Count == 0)
{
MClient.Logger.Warn("No photographer item found with the name: " + photographerName);
}
else
{
MClient.Logger.Info("Photographer item(s) found for name '" + photographerName + "', fetching the first item...");
}
var photographerItem = photographerItems.Items.FirstOrDefault();
if (photographerItem != null)
{
var photographerId = photographerItem.Id;
MClient.Logger.Info("Photographer ID found: " + photographerId);
MClient.Logger.Info("Adding photographer ID to the PhotographerVideographerToAsset relation...");
var photographerParents = entity.GetRelation<IChildToManyParentsRelation>("PhotographerVideographerToAsset").Parents;
photographerParents.Add((long)photographerId);
MClient.Logger.Info("Saving changes to the asset with photographer ID: " + photographerId);
await MClient.Entities.SaveAsync(Context.Asset).ConfigureAwait(false);
MClient.Logger.Info("Changes saved successfully.");
}
else
{
MClient.Logger.Warn("Photographer not found with the name: " + photographerName);
}
}
Some of the gotchas that came up during the creation of this to be aware of:
- If you’re trying to use ChatGPT/Claude/any other LLM to help you script C# scripts for Content Hub, they often won’t know the specifics of how Content Hub works. It often won’t know, for example, what a label is called on a taxonomy item (in this case, “TaxonomyLabel” instead of something like “DisplayName”). If you’re ever in doubt of what member to use, use the API to access a given entity ID to see the raw data: yourcontenthubinstance.com/api/entities/123
- A gentle reminder again that you need to access the TaxonomyLabel using the appropriate culture info.
- When adding the taxonomy item to the relation, be sure to cast your taxonomy ID to long.
Please keep in mind I am no developer! I make copious use of LLMs to get me to code that works, and do lots of research along the way as well. Hopefully this information helps others in setting asset metadata to taxonomy values! There’s lots of improvements that could be made, such as additional error-handling, creating taxonomy values if no existing taxonomy value is found, accessing of taxonomy synonyms as well as the TaxonomyLabel. I’d love to know if anyone comes up with more updates to the code!
Latest Blog Posts
Explore Lance Hayden’s recent blog posts.
-
Content Hub: Show Users Assets While Under Review
One common request clients have when working with the out-of-the-box asset lifecycle (that is…
-
Content Hub: Applying IPTC Metadata to Taxonomy Items
One of Content Hub’s biggest selling points as a DAM is its unique flexibility…
Leave a Reply