I am working on getting the Data Exchange Framework to update xDB contacts. I have it working for email and phone numbers, but now I have some properties that I'd like to store in the contacts' tags. I have tried different setups with a Facet Collection Property Value Accessor and a Facet Indexer Property Value Accessor, but that results in failed mappings. Is there anyone who has managed to update the contacts visitor tags with DEF?
-
Tags in Mongo on the contact record are for list associstions. Sounds like what you want is to create a custom contact facet.– Pete Navarra ♦Apr 17, 2017 at 9:33
-
Historically we have a lot of component personalization configured in the site using vistor tags and we would like to levarage the existing configuration. Do I understand correctly that you are saying tags on a contact record have a different use case than visitor tags had in SC7?– Ben VerheesApr 17, 2017 at 14:49
-
When you talk about tags do you mean this one? coreblimeysitecore.com/blog/…– Vlad ShpakApr 17, 2017 at 20:58
-
No, that's not what I mean, I mean the Tags collection on the Contact class as described here: doc.sitecore.net/sitecore_experience_platform/…– Ben VerheesApr 17, 2017 at 22:02
-
1You can develop ContactTagReader: IValueReader and ContactValueWriter:IValueWriter and certain converter to convert ValueAccessor with these reader and writer.– Vlad ShpakApr 18, 2017 at 10:09
2 Answers
After much debugging and decompiling I found the answer.
This can be done by implementing a ValueAccessor that uses PropertyValueReader("Tags")
and IndexerPropertyValueWriter("tagname")
.
I was on the wrong track for long because the class structure of the tags seems related to how email addresses and phone numbers are implemented, however reading and setting them using DEF is completely different.
When running a repeating import, be aware that visitor tags are timestamped values, so be sure to add an "Objects Are Different Mapping Rule", which comes with the Sitecore provider, to prevent the contact tags filling with useless duplicate values.
One more approach how to map tag value by tag name. The example shows only a writer.
Writer:
public class ContactTagValueWriter : IValueWriter
{
public string TagName { get; set; }
public CanWriteResult CanWrite(object target, object value, DataAccessContext context)
{
var contact = target as Contact;
if (contact == null || value == null || string.IsNullOrEmpty(this.TagName))
{
return CanWriteResult.NegativeResult();
}
return CanWriteResult.PositiveResult();
}
public bool Write(object target, object value, DataAccessContext context)
{
if (!this.CanWrite(target, value, context).CanWriteValue)
{
return false;
}
var contact = target as Contact;
contact.Tags.Set(this.TagName, value.ToString());
return true;
}
}
Converter:
- Create a template based on Value Accessor.
- Add field: FieldName:"TagName", Type: Single-Line Text.
- Change [custom template id] according to created template id.
[SupportedIds("[custom template id]")]
public class ContactTagValueAccessorConverter : ValueAccessorConverter
{
public ContactTagValueAccessorConverter(IItemModelRepository repository) : base(repository)
{
}
public override IValueAccessor Convert(ItemModel source)
{
var valueAccessor = base.Convert(source);
if (valueAccessor.ValueWriter!=null)
{
return valueAccessor;
}
valueAccessor.ValueWriter = new ContactTagValueWriter() {TagName = source["TagName"].ToString()};
return valueAccessor;
}
}