private void ApplyImplementation(BuildShapeContext context, string displayType) { var placement = context.FindPlacement(_shapeType, _differentiator, _defaultLocation); if (string.IsNullOrEmpty(placement.Location) || placement.Location == "-") return; dynamic parentShape = context.Shape; context.ContentPart = ContentPart; var newShape = _shapeBuilder(context); // ignore it if the driver returned a null shape if(newShape == null) { return; } // add a ContentPart property to the final shape if (ContentPart != null && newShape.ContentPart == null) { newShape.ContentPart = ContentPart; } // add a ContentField property to the final shape if (ContentField != null && newShape.ContentField == null) { newShape.ContentField = ContentField; } ShapeMetadata newShapeMetadata = newShape.Metadata; newShapeMetadata.Prefix = _prefix; newShapeMetadata.DisplayType = displayType; newShapeMetadata.PlacementSource = placement.Source; // if a specific shape is provided, remove all previous alternates and wrappers if (!String.IsNullOrEmpty(placement.ShapeType)) { newShapeMetadata.Type = placement.ShapeType; newShapeMetadata.Alternates.Clear(); newShapeMetadata.Wrappers.Clear(); } // parse group placement var group = placement.GetGroup(); if (!String.IsNullOrEmpty(group)) { _groupId = group; } if (!string.Equals(context.GroupId ?? "", _groupId ?? "", StringComparison.OrdinalIgnoreCase)) return; foreach (var alternate in placement.Alternates) { newShapeMetadata.Alternates.Add(alternate); } foreach (var wrapper in placement.Wrappers) { newShapeMetadata.Wrappers.Add(wrapper); } // the zone name is in reference of Layout, e.g. /AsideSecond if (placement.IsLayoutZone()) { parentShape = context.Layout; } var position = placement.GetPosition(); var zone = placement.GetZone(); if (String.IsNullOrEmpty(position)) { parentShape.Zones[zone].Add(newShape); } else { parentShape.Zones[zone].Add(newShape, position); } }
private void BindPlacement(BuildShapeContext context, string displayType, string stereotype) { context.FindPlacement = (partShapeType, differentiator, defaultLocation) => { var workContext = _workContextAccessor.GetContext(_requestContext.HttpContext); var theme = workContext.CurrentTheme; var shapeTable = _shapeTableLocator.Value.Lookup(theme.Id); var request = _requestContext.HttpContext.Request; ShapeDescriptor descriptor; if (shapeTable.Descriptors.TryGetValue(partShapeType, out descriptor)) { var placementContext = new ShapePlacementContext { Content = context.ContentItem, ContentType = context.ContentItem.ContentType, Stereotype = stereotype, DisplayType = displayType, Differentiator = differentiator, Path = VirtualPathUtility.AppendTrailingSlash(_virtualPathProvider.ToAppRelative(request.Path)) // get the current app-relative path, i.e. ~/my-blog/foo }; // define which location should be used if none placement is hit descriptor.DefaultPlacement = defaultLocation; var placement = descriptor.Placement(placementContext); if (placement != null) { placement.Source = placementContext.Source; return placement; } } return new PlacementInfo { Location = defaultLocation, Source = String.Empty }; }; }