public async Task BuildEditorAsync(ContentItem contentItem, BuildEditorContext context) { var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); if (contentTypeDefinition == null) { return; } var contentShape = context.Shape as IZoneHolding; var partsShape = await context.ShapeFactory.CreateAsync("ContentZone", Arguments.From(new { Identifier = contentItem.ContentItemId })); contentShape.Zones["Parts"] = partsShape; foreach (var displayDriver in _displayDrivers) { try { var result = await displayDriver.BuildEditorAsync(contentItem, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, _logger, displayDriver.GetType().Name, nameof(BuildEditorAsync)); } } foreach (var typePartDefinition in contentTypeDefinition.Parts) { var partTypeName = typePartDefinition.PartDefinition.Name; var partName = typePartDefinition.Name; var contentType = typePartDefinition.ContentTypeDefinition.Name; var activator = _contentPartFactory.GetTypeActivator(partTypeName); var part = (ContentPart)contentItem.Get(activator.Type, partName) ?? activator.CreateInstance(); var partPosition = typePartDefinition.GetSettings <ContentTypePartSettings>().Position ?? "before"; part.ContentItem = contentItem; // Create a custom shape to render all the part shapes into it var typePartShapeResult = CreateShapeResult(context.GroupId, partTypeName, contentType, typePartDefinition, partPosition); await typePartShapeResult.ApplyAsync(context); var typePartShape = typePartShapeResult.Shape; if (typePartShape == null) { // Part is explicitly noop in placement then stop rendering execution continue; } typePartShape.Properties["ContentPart"] = part; typePartShape.Properties["ContentTypePartDefinition"] = typePartDefinition; partsShape.Properties[partName] = typePartShape; context.DefaultZone = $"Parts.{partName}"; context.DefaultPosition = partPosition; var partDisplayDrivers = _contentPartDisplayDriverResolver.GetEditorDrivers(partTypeName, typePartDefinition.Editor()); await partDisplayDrivers.InvokeAsync(async (driver, part, typePartDefinition, context) => { var result = await driver.BuildEditorAsync(part, typePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } }, part, typePartDefinition, context, _logger); foreach (var partFieldDefinition in typePartDefinition.PartDefinition.Fields) { var fieldName = partFieldDefinition.Name; var fieldPosition = partFieldDefinition.GetSettings <ContentPartFieldSettings>().Position ?? "before"; context.DefaultZone = $"Parts.{partName}:{fieldPosition}"; var fieldDisplayDrivers = _contentFieldDisplayDriverResolver.GetEditorDrivers(partFieldDefinition.FieldDefinition.Name, partFieldDefinition.Editor()); await fieldDisplayDrivers.InvokeAsync(async (driver, part, partFieldDefinition, typePartDefinition, context) => { var result = await driver.BuildEditorAsync(part, partFieldDefinition, typePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } }, part, partFieldDefinition, typePartDefinition, context, _logger); } } }
public async Task BuildEditorAsync(ContentItem contentItem, BuildEditorContext context) { var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); if (contentTypeDefinition == null) { return; } dynamic contentShape = context.Shape; dynamic partsShape = await context.ShapeFactory.CreateAsync("ContentZone", Arguments.From(new { ContentItem = contentItem })); contentShape.Zones["Parts"] = partsShape; foreach (var displayDriver in _displayDrivers) { try { var result = await displayDriver.BuildEditorAsync(contentItem, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, nameof(BuildEditorAsync)); } } foreach (var typePartDefinition in contentTypeDefinition.Parts) { var partTypeName = typePartDefinition.PartDefinition.Name; var activator = _contentPartFactory.GetTypeActivator(partTypeName); var part = (ContentPart)contentItem.Get(activator.Type, typePartDefinition.Name) ?? activator.CreateInstance(); part.ContentItem = contentItem; // Create a custom shape to render all the part shapes into it dynamic typePartShape = await context.ShapeFactory.CreateAsync("ContentPart_Edit"); typePartShape.ContentPart = part; typePartShape.ContentTypePartDefinition = typePartDefinition; var partPosition = typePartDefinition.GetSettings <ContentTypePartSettings>().Position ?? "before"; partsShape.Add(typePartShape, partPosition); partsShape[typePartDefinition.Name] = typePartShape; context.DefaultZone = $"Parts.{typePartDefinition.Name}"; context.DefaultPosition = partPosition; var partDisplayDrivers = _contentPartDisplayDriverResolver.GetEditorDrivers(partTypeName, typePartDefinition.Editor()); await partDisplayDrivers.InvokeAsync(async (driver, part, typePartDefinition, context) => { var result = await driver.BuildEditorAsync(part, typePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } }, part, typePartDefinition, context, Logger); // TODO: This can be removed in a future release as the recommended way is to use ContentOptions. // Iteratate existing driver registrations as multiple drivers maybe not be registered with ContentOptions. await _partDisplayDrivers.InvokeAsync(async (driver, part, typePartDefinition, context) => { var result = await driver.BuildEditorAsync(part, typePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } }, part, typePartDefinition, context, Logger); foreach (var partFieldDefinition in typePartDefinition.PartDefinition.Fields) { var fieldName = partFieldDefinition.Name; var fieldPosition = partFieldDefinition.GetSettings <ContentPartFieldSettings>().Position ?? "before"; context.DefaultZone = $"Parts.{typePartDefinition.Name}:{fieldPosition}"; var fieldDisplayDrivers = _contentFieldDisplayDriverResolver.GetEditorDrivers(partFieldDefinition.FieldDefinition.Name, partFieldDefinition.Editor()); await fieldDisplayDrivers.InvokeAsync(async (driver, part, partFieldDefinition, typePartDefinition, context) => { var result = await driver.BuildEditorAsync(part, partFieldDefinition, typePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } }, part, partFieldDefinition, typePartDefinition, context, Logger); // TODO: This can be removed in a future release as the recommended way is to use ContentOptions. // Iteratate existing driver registrations as multiple drivers maybe not be registered with ContentOptions. await _fieldDisplayDrivers.InvokeAsync(async (driver, part, partFieldDefinition, typePartDefinition, context) => { var result = await driver.BuildEditorAsync(part, partFieldDefinition, typePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } }, part, partFieldDefinition, typePartDefinition, context, Logger); } } }