For an upgrade to Web 8.5 and DXA 1.7 (and not using the default TBBs), it is not possible to edit linked Components as XPM can only edit Component Presentations, not Components. This is discussed in forum thread "Are Component Links supported for inline edit in XPM?".
The workaround employed for this is to use a dummy Component Template URI to refer to a Component Presentation, which was the second option suggested in the second answer to the forum thread. However, after adding the workaround to a CustomModelBuilder
as below, images in the linked Components are not being rendered. When code is explicitly added to render the images, they do appear, but inline editing for linked Components is not possible. The component template code added to display images as below.
Additonal details:
- Both the image and the tested page are from the same hardcoded publication id.
- No error is thrown and the entire image tag did not render.
Component Template snippet w/code to render images
if (entityModel is Link)
{
Link link = (Link)entityModel;
if (String.IsNullOrEmpty(link.Url))
{
link.Url = SiteConfiguration.LinkResolver.ResolveLink(component.Id);
}
}
//// Linked component XPM metadata code
//if (localization.IsStaging)
//{
// entityModel.XpmMetadata = GetXpmMetadata(component);
//}
// Set the Entity Model's default View (if any) after it has been fully initialized.
entityModel.MvcData = entityModel.GetDefaultView(localization);
CustomModelBuilder
namespace Sdl.Web.Tridion.Mapping
{
public class CustomModelBuilder : DefaultModelBuilder
{
override public void BuildEntityModel(ref EntityModel entityModel, IComponent component, Type baseModelType, Localization localization)
{
using (new Tracer(entityModel, component, baseModelType, localization))
{
string[] schemaTcmUriParts = component.Schema.Id.Split('-');
SemanticSchema semanticSchema = SemanticMapping.GetSchema(schemaTcmUriParts[1], localization);
// The semantic mapping may resolve to a more specific model type than specified by the View Model itself (e.g. Image instead of just MediaItem for Teaser.Media)
Type modelType = semanticSchema.GetModelTypeFromSemanticMapping(baseModelType);
MappingData mappingData = new MappingData
{
SemanticSchema = semanticSchema,
EntityNames = semanticSchema.GetEntityNames(),
TargetEntitiesByPrefix = GetEntityDataFromType(modelType),
Content = component.Fields,
Meta = component.MetadataFields,
TargetType = modelType,
SourceEntity = component,
Localization = localization
};
entityModel = (EntityModel)CreateViewModel(mappingData);
entityModel.Id = GetDxaIdentifierFromTcmUri(component.Id);
if (localization.IsStaging)
{
entityModel.XpmMetadata = GetXpmMetadata(component);
}
// Set the Entity Model’s default View (if any) after it has been fully initialized.
entityModel.MvcData = entityModel.GetDefaultView(localization);
}
}
internal new static string GetDxaIdentifierFromTcmUri(string tcmUri, string templateTcmUri = null)
{
// Return the Item (Reference) ID part of the TCM URI.
string result = tcmUri.Split('-')[1];
if (templateTcmUri != null)
{
result += "-" + templateTcmUri.Split('-')[1];
}
return result;
}
protected virtual IDictionary<string, object> GetXpmMetadata(IComponent cp)
{
IDictionary<string, object> result = new Dictionary<string, object>();
result.Add("ComponentID", cp.Id);
result.Add("ComponentModified", cp.RevisionDate.ToString("yyyy - MM - ddTHH:mm: ss"));
result.Add("ComponentTemplateID", "tcm:10-194307-32" /*cp.ComponentTemplate.Id*/);//set to dummy template id. -- 10-194307-32 ----10-164516-32
result.Add("ComponentTemplateModified", "2018-03-21T10: 39:58" /*cp.ComponentTemplate.RevisionDate.ToString(“yyyy-MM-ddTHH:mm:ss”)*/); //set to dummy timestamp
result.Add("IsRepositoryPublished", false);
return result;
}
}
}
Any thoughts on what changes might be necessary to both enable inline editing for linked Components and render images?