public async Task BuildDisplayAsync(ContentItem contentItem, BuildDisplayContext context) { // Optimized implementation for display // For each field on the content item, invoke all IContentFieldDisplayDriver instances var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); if (contentTypeDefinition == null) { return; } var partInfos = _contentPartDrivers.Select(x => x.GetPartInfo()).ToDictionary(x => x.PartName); foreach (var contentTypePartDefinition in contentTypeDefinition.Parts) { var partName = contentTypePartDefinition.PartDefinition.Name; var partType = partInfos.ContainsKey(partName) ? partInfos[partName].Factory(contentTypePartDefinition).GetType() : null; var part = contentItem.Get(partType ?? typeof(ContentPart), partName) as ContentPart; foreach (var contentPartFieldDefinition in contentTypePartDefinition.PartDefinition.Fields) { var fieldName = contentPartFieldDefinition.Name; foreach (var displayDriver in _displayDrivers) { try { var result = await displayDriver.BuildDisplayAsync(fieldName, part, contentPartFieldDefinition, context); if (result != null) { result.Apply(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, "BuildDisplayAsync"); } } } } }
public async Task UpdateEditorAsync(ContentItem model, UpdateEditorContext context) { foreach (var displayDriver in _displayDrivers) { try { var result = await displayDriver.UpdateEditorAsync(model, context); if (result != null) { result.Apply(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, "BuildDisplayAsync"); } } }
public async Task BuildDisplayAsync(ContentItem contentItem, BuildDisplayContext context) { var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); if (contentTypeDefinition == null) { return; } foreach (var displayDriver in _displayDrivers) { try { var result = await displayDriver.BuildDisplayAsync(contentItem, context); if (result != null) { result.Apply(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, "BuildDisplayAsync"); } } foreach (var contentTypePartDefinition in contentTypeDefinition.Parts) { var partName = contentTypePartDefinition.Name; var partTypeName = contentTypePartDefinition.PartDefinition.Name; var partActivator = _contentPartFactory.GetTypeActivator(partTypeName); var part = contentItem.Get(partActivator.Type, partName) as ContentPart; if (part != null) { foreach (var displayDriver in _partDisplayDrivers) { try { var result = await displayDriver.BuildDisplayAsync(part, contentTypePartDefinition, context); if (result != null) { result.Apply(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, "BuildDisplayAsync"); } } } foreach (var contentPartFieldDefinition in contentTypePartDefinition.PartDefinition.Fields) { foreach (var displayDriver in _fieldDisplayDrivers) { try { var result = await displayDriver.BuildDisplayAsync(part, contentPartFieldDefinition, contentTypePartDefinition, context); if (result != null) { result.Apply(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, "BuildDisplayAsync"); } } } } }
public async Task UpdateEditorAsync(ContentItem contentItem, UpdateEditorContext context) { var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); if (contentTypeDefinition == null) { return; } dynamic contentShape = context.Shape; dynamic partsShape = context.ShapeFactory.Create("Zone", Arguments.Empty); contentShape.Zones["Parts"] = partsShape; foreach (var displayDriver in _displayDrivers) { try { var result = await displayDriver.UpdateEditorAsync(contentItem, context); if (result != null) { result.Apply(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, nameof(UpdateEditorAsync)); } } foreach (var typePartDefinition in contentTypeDefinition.Parts) { var activator = _contentPartFactory.GetTypeActivator(typePartDefinition.Name); 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 = context.ShapeFactory.Create("ContentPart_Edit", Arguments.Empty); typePartShape.ContentPart = part; typePartShape.ContentTypePartDefinition = typePartDefinition; var partPosition = typePartDefinition.Settings["Position"]?.ToString() ?? "before"; partsShape.Add(typePartShape, partPosition); partsShape[typePartDefinition.Name] = typePartShape; context.FindPlacement = (shapeType, differentiator, displayType, displayContext) => new PlacementInfo { Location = $"Parts.{typePartDefinition.Name}" }; await _partDisplayDrivers.InvokeAsync(async contentDisplay => { var result = await contentDisplay.UpdateEditorAsync(part, typePartDefinition, context); if (result != null) { result.Apply(context); } }, Logger); foreach (var partFieldDefinition in typePartDefinition.PartDefinition.Fields) { var fieldName = partFieldDefinition.Name; var fieldPosition = partFieldDefinition.Settings["Position"]?.ToString() ?? "before"; context.FindPlacement = (shapeType, differentiator, displayType, displayContext) => new PlacementInfo { Location = $"Parts.{typePartDefinition.Name}:{fieldPosition}" }; await _fieldDisplayDrivers.InvokeAsync(async contentDisplay => { var result = await contentDisplay.UpdateEditorAsync(part, partFieldDefinition, typePartDefinition, context); if (result != null) { result.Apply(context); } }, Logger); } } }
public async Task BuildDisplayAsync(ContentItem contentItem, BuildDisplayContext context) { var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); if (contentTypeDefinition == null) { return; } foreach (var displayDriver in _displayDrivers) { try { var result = await displayDriver.BuildDisplayAsync(contentItem, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, _logger, displayDriver.GetType().Name, nameof(BuildDisplayAsync)); } } var settings = contentTypeDefinition?.GetSettings <ContentTypeSettings>(); var stereotype = settings?.Stereotype ?? String.Empty; foreach (var contentTypePartDefinition in contentTypeDefinition.Parts) { var partName = contentTypePartDefinition.Name; var partTypeName = contentTypePartDefinition.PartDefinition.Name; var partActivator = _contentPartFactory.GetTypeActivator(partTypeName); var part = contentItem.Get(partActivator.Type, partName) as ContentPart; if (part == null) { continue; } var contentType = contentTypePartDefinition.ContentTypeDefinition.Name; var partDisplayDrivers = _contentPartDisplayDriverResolver.GetDisplayModeDrivers(partTypeName, contentTypePartDefinition.DisplayMode()); foreach (var partDisplayDriver in partDisplayDrivers) { try { var result = await partDisplayDriver.BuildDisplayAsync(part, contentTypePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, _logger, partDisplayDrivers.GetType().Name, nameof(BuildDisplayAsync)); } } var tempContext = context; // Create a custom ContentPart shape that will hold the fields for dynamic content part (not implicit parts) // This allows its fields to be grouped and templated if (part.GetType() == typeof(ContentPart) && partTypeName != contentTypePartDefinition.ContentTypeDefinition.Name) { var shapeType = context.DisplayType != "Detail" ? "ContentPart_" + context.DisplayType : "ContentPart"; var shapeResult = new ShapeResult(shapeType, ctx => ctx.ShapeFactory.CreateAsync(shapeType, () => new ValueTask <IShape>(new ZoneHolding(() => ctx.ShapeFactory.CreateAsync("Zone"))))); shapeResult.Differentiator(partName); shapeResult.Name(partName); shapeResult.Location("Content"); shapeResult.OnGroup(context.GroupId); shapeResult.Displaying(ctx => { var displayTypes = new[] { String.Empty, "_" + ctx.Shape.Metadata.DisplayType }; foreach (var displayType in displayTypes) { // eg. ServicePart, ServicePart.Summary ctx.Shape.Metadata.Alternates.Add($"{partTypeName}{displayType}"); // [ContentType]_[DisplayType]__[PartType] // e.g. LandingPage-ServicePart, LandingPage-ServicePart.Summary ctx.Shape.Metadata.Alternates.Add($"{contentType}{displayType}__{partTypeName}"); if (!String.IsNullOrEmpty(stereotype)) { // [Stereotype]_[DisplayType]__[PartType], // e.g. Widget-ServicePart ctx.Shape.Metadata.Alternates.Add($"{stereotype}{displayType}__{partTypeName}"); } } if (partTypeName == partName) { return; } foreach (var displayType in displayTypes) { // [ContentType]_[DisplayType]__[PartName] // e.g. Employee-Address1, Employee-Address2 ctx.Shape.Metadata.Alternates.Add($"{contentType}{displayType}__{partName}"); if (!String.IsNullOrEmpty(stereotype)) { // [Stereotype]_[DisplayType]__[PartType]__[PartName] // e.g. Widget-Services ctx.Shape.Metadata.Alternates.Add($"{stereotype}{displayType}__{partTypeName}__{partName}"); } } }); await shapeResult.ApplyAsync(context); var contentPartShape = shapeResult.Shape; // Make the ContentPart name property available on the shape contentPartShape.Properties[partTypeName] = part.Content; contentPartShape.Properties["ContentItem"] = part.ContentItem; context = new BuildDisplayContext(shapeResult.Shape, context.DisplayType, context.GroupId, context.ShapeFactory, context.Layout, context.Updater) { // With a new display context we have the default FindPlacementDelegate that returns null, so we reuse the delegate from the temp context. FindPlacement = tempContext.FindPlacement, }; } foreach (var contentPartFieldDefinition in contentTypePartDefinition.PartDefinition.Fields) { var fieldDisplayDrivers = _contentFieldDisplayDriverResolver.GetDisplayModeDrivers(contentPartFieldDefinition.FieldDefinition.Name, contentPartFieldDefinition.DisplayMode()); foreach (var fieldDisplayDriver in fieldDisplayDrivers) { try { var result = await fieldDisplayDriver.BuildDisplayAsync(part, contentPartFieldDefinition, contentTypePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, _logger, fieldDisplayDriver.GetType().Name, nameof(BuildDisplayAsync)); } } } context = tempContext; } }
public async Task UpdateEditorAsync(ContentItem contentItem, UpdateEditorContext context) { var contentTypeDefinition = _contentDefinitionManager.LoadTypeDefinition(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.UpdateEditorAsync(contentItem, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, _logger, displayDriver.GetType().Name, nameof(UpdateEditorAsync)); } } 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 hidden in placement then stop rendering it continue; } typePartShape.Properties["ContentPart"] = part; typePartShape.Properties["ContentTypePartDefinition"] = typePartDefinition; partsShape.Properties[partName] = typePartShape; context.DefaultZone = $"Parts.{partName}:{partPosition}"; var partDisplayDrivers = _contentPartDisplayDriverResolver.GetEditorDrivers(partTypeName, typePartDefinition.Editor()); await partDisplayDrivers.InvokeAsync(async (driver, part, typePartDefinition, context) => { var result = await driver.UpdateEditorAsync(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.UpdateEditorAsync(part, partFieldDefinition, typePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } }, part, partFieldDefinition, typePartDefinition, context, _logger); } } }
public async Task BuildDisplayAsync(ContentItem contentItem, BuildDisplayContext context) { var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); if (contentTypeDefinition == null) { return; } foreach (var displayDriver in _displayDrivers) { try { var result = await displayDriver.BuildDisplayAsync(contentItem, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, nameof(BuildDisplayAsync)); } } foreach (var contentTypePartDefinition in contentTypeDefinition.Parts) { var partName = contentTypePartDefinition.Name; var partTypeName = contentTypePartDefinition.PartDefinition.Name; var contentType = contentTypePartDefinition.ContentTypeDefinition.Name; var partActivator = _contentPartFactory.GetTypeActivator(partTypeName); var part = contentItem.Get(partActivator.Type, partName) as ContentPart; if (part != null) { var partDisplayDrivers = _contentPartDisplayDriverResolver.GetDisplayModeDrivers(partTypeName, contentTypePartDefinition.DisplayMode()); foreach (var partDisplayDriver in partDisplayDrivers) { try { var result = await partDisplayDriver.BuildDisplayAsync(part, contentTypePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, partDisplayDrivers.GetType().Name, nameof(BuildDisplayAsync)); } } // 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. foreach (var displayDriver in _partDisplayDrivers) { try { var result = await displayDriver.BuildDisplayAsync(part, contentTypePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, nameof(BuildDisplayAsync)); } } var tempContext = context; // Create a custom ContentPart shape that will hold the fields for dynamic content part (not implicit parts) // This allows its fields to be grouped and templated if (part.GetType() == typeof(ContentPart) && partTypeName != contentTypePartDefinition.ContentTypeDefinition.Name) { var shapeType = context.DisplayType != "Detail" ? "ContentPart_" + context.DisplayType : "ContentPart"; var shapeResult = new ShapeResult(shapeType, ctx => ctx.ShapeFactory.CreateAsync(shapeType, () => new ValueTask <IShape>(new ZoneHolding(() => ctx.ShapeFactory.CreateAsync("Zone"))))); shapeResult.Differentiator(partName); shapeResult.Location("Content"); await shapeResult.ApplyAsync(context); var contentPartShape = shapeResult.Shape; // Make the ContentPart name property available on the shape dynamic dynamicContentPartShape = contentPartShape; dynamicContentPartShape[partTypeName] = part.Content; dynamicContentPartShape["ContentItem"] = part.ContentItem; contentPartShape.Metadata.Alternates.Add(partTypeName); contentPartShape.Metadata.Alternates.Add($"{contentType}__{partTypeName}"); if (context.DisplayType != "Detail") { contentPartShape.Metadata.Alternates.Add($"{partTypeName}_{context.DisplayType}"); contentPartShape.Metadata.Alternates.Add($"{contentType}_{context.DisplayType}__{partTypeName}"); } if (partName != partTypeName) { contentPartShape.Metadata.Alternates.Add($"{contentType}__{partName}"); if (context.DisplayType != "Detail") { contentPartShape.Metadata.Alternates.Add($"{contentType}_{context.DisplayType}__{partName}"); } } context = new BuildDisplayContext(shapeResult.Shape, context.DisplayType, context.GroupId, context.ShapeFactory, context.Layout, context.Updater); } foreach (var contentPartFieldDefinition in contentTypePartDefinition.PartDefinition.Fields) { var fieldDisplayDrivers = _contentFieldDisplayDriverResolver.GetDisplayModeDrivers(contentPartFieldDefinition.FieldDefinition.Name, contentPartFieldDefinition.DisplayMode()); foreach (var fieldDisplayDriver in fieldDisplayDrivers) { try { var result = await fieldDisplayDriver.BuildDisplayAsync(part, contentPartFieldDefinition, contentTypePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, fieldDisplayDriver.GetType().Name, nameof(BuildDisplayAsync)); } } // 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. foreach (var displayDriver in _fieldDisplayDrivers) { try { var result = await displayDriver.BuildDisplayAsync(part, contentPartFieldDefinition, contentTypePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, nameof(BuildDisplayAsync)); } } } context = tempContext; } } }
public async Task UpdateEditorAsync(ContentItem contentItem, UpdateEditorContext context) { var contentTypeDefinition = _contentDefinitionManager.LoadTypeDefinition(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.UpdateEditorAsync(contentItem, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, nameof(UpdateEditorAsync)); } } 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}:{partPosition}"; var partDisplayDrivers = _contentPartDisplayDriverResolver.GetEditorDrivers(partTypeName, typePartDefinition.Editor()); await partDisplayDrivers.InvokeAsync(async (driver, part, typePartDefinition, context) => { var result = await driver.UpdateEditorAsync(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.UpdateEditorAsync(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.UpdateEditorAsync(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.UpdateEditorAsync(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; 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}"; 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 BuildDisplayAsync(ContentItem contentItem, BuildDisplayContext context) { var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); if (contentTypeDefinition == null) { return; } foreach (var displayDriver in _displayDrivers) { try { var result = await displayDriver.BuildDisplayAsync(contentItem, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, "BuildDisplayAsync"); } } foreach (var contentTypePartDefinition in contentTypeDefinition.Parts) { var partName = contentTypePartDefinition.Name; var partTypeName = contentTypePartDefinition.PartDefinition.Name; var partActivator = _contentPartFactory.GetTypeActivator(partTypeName); var part = contentItem.Get(partActivator.Type, partName) as ContentPart; if (part != null) { foreach (var displayDriver in _partDisplayDrivers) { try { var result = await displayDriver.BuildDisplayAsync(part, contentTypePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, "BuildDisplayAsync"); } } var tempContext = context; // Create a custom ContentPart shape that will hold the fields for dynamic content part (not implicit parts) // This allows its fields to be grouped and templated if (part.GetType() == typeof(ContentPart) && contentTypePartDefinition.PartDefinition.Name != contentTypePartDefinition.ContentTypeDefinition.Name) { var shapeType = context.DisplayType != "Detail" ? "ContentPart_" + context.DisplayType : "ContentPart"; var shapeResult = new ShapeResult(shapeType, ctx => ctx.ShapeFactory.CreateAsync(shapeType, () => Task.FromResult <IShape>(new ZoneHolding(() => ctx.ShapeFactory.CreateAsync("Zone", Arguments.Empty))))); shapeResult.Differentiator(contentTypePartDefinition.PartDefinition.Name); shapeResult.Location("Content"); await shapeResult.ApplyAsync(context); var contentPartShape = shapeResult.Shape; // Make the ContentPart name property available on the shape dynamic dynamicContentPartShape = contentPartShape; dynamicContentPartShape[contentTypePartDefinition.PartDefinition.Name] = part.Content; dynamicContentPartShape["ContentItem"] = part.ContentItem; contentPartShape.Metadata.Alternates.Add(contentTypePartDefinition.PartDefinition.Name); if (context.DisplayType != "Detail") { contentPartShape.Metadata.Alternates.Add($"{contentTypePartDefinition.PartDefinition.Name}_{context.DisplayType}"); } context = new BuildDisplayContext(shapeResult.Shape, context.DisplayType, context.GroupId, context.ShapeFactory, context.Layout, context.Updater); } foreach (var contentPartFieldDefinition in contentTypePartDefinition.PartDefinition.Fields) { foreach (var displayDriver in _fieldDisplayDrivers) { try { var result = await displayDriver.BuildDisplayAsync(part, contentPartFieldDefinition, contentTypePartDefinition, context); if (result != null) { await result.ApplyAsync(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, "BuildDisplayAsync"); } } } context = tempContext; } } }
public async Task UpdateEditorAsync(ContentItem contentItem, UpdateEditorContext context) { var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType); if (contentTypeDefinition == null) { return; } dynamic contentShape = context.Shape; dynamic partsShape = context.ShapeFactory.Create("Zone", Arguments.Empty); contentShape.Zones["Parts"] = partsShape; foreach (var displayDriver in _displayDrivers) { try { var result = await displayDriver.UpdateEditorAsync(contentItem, context); if (result != null) { result.Apply(context); } } catch (Exception ex) { InvokeExtensions.HandleException(ex, Logger, displayDriver.GetType().Name, nameof(UpdateEditorAsync)); } } var partInfos = _contentPartDrivers.Select(x => x.GetPartInfo()).ToDictionary(x => x.PartName); foreach (var typePartDefinition in contentTypeDefinition.Parts) { ContentPartInfo partInfo; ContentPart part; if (partInfos.TryGetValue(typePartDefinition.PartDefinition.Name, out partInfo)) { // It's a well-known part type, bind the data to the model part = partInfo.Factory(typePartDefinition); } else { // Generic content part model (custom part) part = new ContentPart(); } part = contentItem.GetOrCreate(part.GetType(), () => new ContentPart(), typePartDefinition.Name) as ContentPart; // Create a custom shape to render all the part shapes into it dynamic typePartShape = context.ShapeFactory.Create("ContentPart_Edit", Arguments.Empty); typePartShape.ContentPart = part; typePartShape.ContentTypePartDefinition = typePartDefinition; var partPosition = typePartDefinition.Settings["Position"]?.ToString() ?? "before"; partsShape.Add(typePartShape, partPosition); partsShape[typePartDefinition.Name] = typePartShape; context.FindPlacement = (shape, differentiator, displayType) => new PlacementInfo { Location = $"Parts.{typePartDefinition.Name}" }; await _partDisplayDrivers.InvokeAsync(async contentDisplay => { var result = await contentDisplay.UpdateEditorAsync(part, typePartDefinition, context); if (result != null) { result.Apply(context); } }, Logger); foreach (var partFieldDefinition in typePartDefinition.PartDefinition.Fields) { var fieldName = partFieldDefinition.Name; var fieldPosition = partFieldDefinition.Settings["Position"]?.ToString() ?? "before"; context.FindPlacement = (shape, differentiator, displayType) => new PlacementInfo { Location = $"Parts.{typePartDefinition.Name}:{fieldPosition}" }; await _fieldDisplayDrivers.InvokeAsync(async contentDisplay => { var result = await contentDisplay.UpdateEditorAsync(part, partFieldDefinition, typePartDefinition, context); if (result != null) { result.Apply(context); } }, Logger); } } }
/// <summary> /// This could be bound directly in XAML with the use of Blend Behaviours, but we have to invoke it on the UI thread, and I dont want that inside my viewmodels /// </summary> private void OnLoadError(object sender, LoadErrorEventArgs e) { InvokeExtensions.OnUIThread(() => { m_webBrowserViewModel.OnLoadError(e); }); }
/// <summary> /// This could be bound directly in XAML with the use of Blend Behaviours, but we have to invoke it on the UI thread, and I dont want that inside my viewmodels /// </summary> private void OnLoadingStateChanged(object sender, LoadingStateChangedEventArgs loadingStateChangedEventArgs) { InvokeExtensions.OnUIThread(() => { m_webBrowserViewModel.OnFinishedLoading(loadingStateChangedEventArgs); }); }