How can a node id be mapped to the id of its translated version?
I have a custom control that stores node ids with the following data structure.
[{id: 4864, label: "Test", type: "internal"}]
I have the mapper for this working so it is sent off correctly to translation, but it doesn't update the id to point to the translated version when the translation is approved. I'm unsure how to connect to this though, as it's not covered in the documentation. I tried writing code based on what I can see in the dll references, but it doesn't trigger.
public class FlexibleLinkResolver : LinkMapperBase {
public string Name => "Flexible Link V2";
public string[] Editors => new string[] { "FlexibleLinkV2" };
private LinkResolver _resolver;
public FlexibleLinkResolver(IContentService contentService, IRelationService relationService) : base(contentService, relationService) {
_resolver = new LinkResolver(contentService, relationService, TranslationManagerContext.Current.SetService);
}
public object UpdateLinkValues(TranslationSet set, int targetSiteId, object sourceValue, object targetValue) {
if (sourceValue == null) {
return null;
}
var sources = (List<FlexibleLinkModel>)sourceValue;
var targets = (List<FlexibleLinkModel>)targetValue;
for (var i=0; i<sources.Count(); i++) {
var source = sources[i];
var target = targets[i];
if (source.Id != 0 && source.Type != "media" && source.Id == target.Id) {
target.Id = _resolver.ResolveLink(set, targetSiteId, source.Id);
}
}
return targets;
}
}
Is this feature extendable and if so, what class should I be extending to tie into it?
The only thing that I think will cause an issue is your class doesn't Explicitly implement ILinkMapper - so the link mapper won't be discovered by Translation Manager when it startup.
and if you are using the LinkMapper base, you can call this.GetLinkResolver(); to get the underlying link resolver when you need it (although that function is just doing the as you are in the class constructor of your class)
Adding the ILinkMapper got it to trigger. I did run into a couple of issues though.
GetLinkResolver isn't defined when I extend LinkMapperBase. When I inspect the class in visual studio, it just has the constructor and no other method. Is it an internal method? I ended up just creating a new resolver in the class instead of using that one.
The target value was a string instead of a JArray. This is because the mapper is serializing the raw value in order to work with nested content, as the nested content mapper expects strings. There may not be anything that can be done about that, but it did throw me off a little.
I was able to work around these issues, so they aren't blockers for me, but just letting you know. For reference, this is the working version of the link resolver.
using Jumoo.TranslationManager.Core;
using Jumoo.TranslationManager.Core.Models;
using Jumoo.TranslationManager.LinkUpdater;
using Jumoo.TranslationManager.LinkUpdater.LinkMappers;
using Newtonsoft.Json.Linq;
using System.Linq;
using Umbraco.Core.Services;
namespace FlexibleLinkV2.TranslationMappers {
public class FlexibleLinkResolver : LinkMapperBase, ILinkMapper {
public string Name => "Flexible Link V2";
public string[] Editors => new string[] { "FlexibleLinkV2" };
private LinkResolver _resolver;
public FlexibleLinkResolver(IContentService contentService, IRelationService relationService) : base(contentService, relationService) {
_resolver = new LinkResolver(contentService, relationService, TranslationManagerContext.Current.SetService);
}
public object UpdateLinkValues(TranslationSet set, int targetSiteId, object sourceValue, object targetValue) {
if (sourceValue == null) {
return null;
}
var sources = (JArray)sourceValue;
var targets = JArray.Parse((string)((JValue)targetValue).Value);
for (var i=0; i<sources.Count(); i++) {
var source = sources[i];
var target = targets[i];
var sourceId = source.Value<int>("id");
if (sourceId != 0 && source.Value<string>("type") != "media" && sourceId == target.Value<int>("id")) {
target["id"] = _resolver.ResolveLink(set, targetSiteId, sourceId);
}
}
return targets;
}
}
}
How can a node id be mapped to the id of its translated version?
I have a custom control that stores node ids with the following data structure.
I have the mapper for this working so it is sent off correctly to translation, but it doesn't update the id to point to the translated version when the translation is approved. I'm unsure how to connect to this though, as it's not covered in the documentation. I tried writing code based on what I can see in the dll references, but it doesn't trigger.
Is this feature extendable and if so, what class should I be extending to tie into it?
Hi Jesse,
yeah, we added the link mapper after some requests from customers, but we haven't documented it - sorry that's on us.
although I think you've done a good detective job and i think it is almost right.
For reference: I created a gist of the internal ID Mapper (the one we use for ContentPickers, and (legacy) MultiNodeTreePickers.
https://gist.github.com/KevinJump/34e28162b169e1b62e76e7251f307d82
The only thing that I think will cause an issue is your class doesn't Explicitly implement
ILinkMapper
- so the link mapper won't be discovered by Translation Manager when it startup.and if you are using the LinkMapper base, you can call
this.GetLinkResolver();
to get the underlying link resolver when you need it (although that function is just doing the as you are in the class constructor of your class)Thanks for the feedback Kevin.
Adding the ILinkMapper got it to trigger. I did run into a couple of issues though.
I was able to work around these issues, so they aren't blockers for me, but just letting you know. For reference, this is the working version of the link resolver.
is working on a reply...