public override void Apply(ModelShapeContext context) { foreach (var result in _results) { result.Apply(context); } }
private void BindPlacement(ModelShapeContext context, string displayType, string stereotype) { context.FindPlacement = (partShapeType, differentiator, defaultLocation) => { var theme = _themeService.Value.GetRequestTheme(_requestContext); var shapeTable = _shapeTableManager.GetShapeTable(theme.Id); var request = _requestContext.HttpContext.Request; ShapeDescriptor descriptor; if (shapeTable.Descriptors.TryGetValue(partShapeType, out descriptor)) { var placementContext = new ShapePlacementContext { Stereotype = stereotype, DisplayType = displayType, Differentiator = differentiator, Path = VirtualPathUtility.AppendTrailingSlash(VirtualPathUtility.ToAppRelative(request.Path)) // get the current app-relative path, i.e. ~/my-blog/foo }; var placement = descriptor.Placement(placementContext); if (placement != null) { placement.Source = placementContext.Source; return(placement); } } return(new PlacementInfo { Location = defaultLocation, Source = String.Empty }); }; }
public void BuildEditorShape(object model, dynamic root, Orchard.ContentManagement.IUpdateModel updater, string prefix, string displayType, string stereotype, ModelShapeContext parentContext = null) { var context = new ModelEditorShapeContext(model, root, Shape, prefix, displayType, updater, parentContext); BindPlacement(context, displayType, stereotype); foreach (var driver in Drivers) { ModelDriverResult result = null; if (updater != null) { result = driver.UpdateEditor(context); } else { result = driver.BuildEditor(context); } // Null check, there must be a performance advantage to not instancing loads of empty ModelDriverResults if (result != null) { result.Apply(context); } } // Chain sub results? // They are applied to the same base object (as opposed to rendering an entirely new shape with its own zones) foreach (var chain in context.ChainedResults) { BuildEditorShape(chain.Model, chain.Root ?? root, updater, chain.Prefix, chain.DisplayType ?? displayType, stereotype, context); // Fire an event so parent shape can perform work after the update chain.OnCompleted(context); } // Invoke Updated event now all drivers have been executed if (updater != null) { context.InvokeUpdated(); } // Done }
protected override void Display(ConnectorDisplayContext model, dynamic shape, ModelShapeContext context) { if (context.Paradigms.Has("Navigation")) { model.SocketDisplayContext.Paradigms.Add("NavigationChild"); context.Paradigms.Add("NavigationChild"); bool isCurrent = false; string rightUrl = ""; // HACK: Better than before but still a bit hackish if (model.Right.Content != null) { // TODO: Make absolute var url = new UrlHelper(_requestContext); rightUrl = url.ItemDisplayUrl(model.Right.Content); // Check if it's a current page or parent var work = _workContextAccessor.GetContext(); string modelUrl = rightUrl.Replace(work.HttpContext.Request.ApplicationPath, string.Empty).TrimEnd('/').ToUpperInvariant(); isCurrent = ((!string.IsNullOrEmpty(modelUrl) && RequestUrl.StartsWith(modelUrl)) || RequestUrl == modelUrl); // Add Current paradigm so we can modify display if (isCurrent) { context.Paradigms.Add("Current"); } else { context.Paradigms.Remove("Current"); } } (shape.Metadata as ShapeMetadata).OnDisplaying(displaying => { displaying.Shape.IsCurrent = isCurrent; // Store display url displaying.Shape.Url = rightUrl; }); } }
public void OnCompleted(ModelShapeContext context) { if (Completed != null) { Completed(context); } }
ModelDriverResult BuildDisplay(ModelShapeContext context) { if (context.Model is T) { return(Display((T)context.Model, context.New, context)); } return(null); }
ModelDriverResult BuildEditor(ModelShapeContext context) { if (context.Model is T) { return(Editor((T)context.Model, context.New, context)); } return(null); }
ModelDriverResult UpdateEditor(ModelShapeContext context) { if (context.Model is T) { return(Update((T)context.Model, context.New, context.Updater, context)); } return(null); }
protected ModelShapeContext(object model, IShape shape, String displayType, IShapeFactory shapeFactory, ModelShapeContext parentContext) { Model = model; Shape = shape; New = shapeFactory; FindPlacement = (partType, differentiator, defaultLocation) => new PlacementInfo {Location = defaultLocation, Source = String.Empty}; ParentContext = parentContext; DisplayType = displayType; }
public static ModelShapeBuilder BuildEditorShape(this IOrigamiService origami, object model, IUpdateModel updater, string prefix, string displayType, string stereotype, string contentType = null, ModelShapeContext parentContext = null) { var builder = origami.Builder(model) .WithMode("Editor") .WithUpdater(updater, prefix) .WithDisplayType(displayType) .WithStereotype(stereotype) .WithContentType(contentType) .WithParent(parentContext); return builder; }
public override void Apply(ModelShapeContext context) { var chain = new ModelChainContext() { Model = _model, Prefix = _prefix }; if (_onCompleted != null) { chain.Completed += _onCompleted; } context.ChainedResults.Add(chain); }
protected override dynamic BuildShape(ModelShapeContext context) { var chain = new ModelChainContext() { Model = _model, ShapeType = _shapeType, Prefix = _prefix }; chain.Root = _shape(chain); context.ChainedResults.Add(chain); return chain.Root; }
/// <summary> /// Build prefix for template, using parent prefix if available /// TODO: Somehow force its usage instead of relying on callers /// </summary> /// <param name="context"></param> /// <returns></returns> protected String FullPrefix(ModelShapeContext context, string fieldName = null) { var prefix = Prefix; if (!String.IsNullOrWhiteSpace(context.Prefix)) { prefix = context.Prefix + "." + prefix; } if (!String.IsNullOrWhiteSpace(fieldName)) { prefix = prefix + "." + fieldName; } return prefix; }
protected ModelShapeContext(object model, IShape shape, String displayType, IShapeFactory shapeFactory, ModelShapeContext parentContext) { Model = model; Shape = shape; New = shapeFactory; FindPlacement = (partType, differentiator, defaultLocation) => new PlacementInfo { Location = defaultLocation, Source = String.Empty }; ParentContext = parentContext; DisplayType = displayType; }
public static ModelShapeBuilder WithParent(this ModelShapeBuilder builder, ModelShapeContext parent) { if (parent == null) { builder.Context.ParentContext = null; builder.Context.CustomContext = null; } else { builder.Context.ParentContext = parent; builder.Context.CustomContext = parent.CustomContext; } return builder; }
protected override dynamic BuildShape(ModelShapeContext context) { var chain = new ModelChainContext() { Model = _model, ShapeType = _shapeType, Prefix = _prefix }; chain.Root = _shape(chain); context.ChainedResults.Add(chain); return(chain.Root); }
public static ModelShapeBuilder WithParent(this ModelShapeBuilder builder, ModelShapeContext parent) { if (parent == null) { builder.Context.ParentContext = null; builder.Context.CustomContext = null; } else { builder.Context.ParentContext = parent; builder.Context.CustomContext = parent.CustomContext; } return(builder); }
/// <summary> /// Build prefix for template, using parent prefix if available /// TODO: Somehow force its usage instead of relying on callers /// </summary> /// <param name="context"></param> /// <returns></returns> protected String FullPrefix(ModelShapeContext context, string fieldName = null) { var prefix = Prefix; if (!String.IsNullOrWhiteSpace(context.Prefix)) { prefix = context.Prefix + "." + prefix; } if (!String.IsNullOrWhiteSpace(fieldName)) { prefix = prefix + "." + fieldName; } return(prefix); }
private void ApplyImplementation(ModelShapeContext context, string displayType) { // if (!string.Equals(context.GroupId ?? "", _groupId ?? "", StringComparison.OrdinalIgnoreCase)) // return; var placement = context.FindPlacement(_shapeType, _differentiator, _defaultLocation); if (string.IsNullOrEmpty(placement.Location) || placement.Location == "-") return; dynamic parentShape = context.Shape; var newShape = _shapeBuilder(context); // Handle null shape without an error if (newShape == null) return; ShapeMetadata newShapeMetadata = newShape.Metadata; newShapeMetadata.Prefix = _prefix; // Display type might have already been set (so we're not forced to use the one from the context) if (string.IsNullOrWhiteSpace(newShapeMetadata.DisplayType)) { 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(); } foreach (var alternate in placement.Alternates) { newShapeMetadata.Alternates.Add(alternate); } foreach (var wrapper in placement.Wrappers) { newShapeMetadata.Wrappers.Add(wrapper); } var delimiterIndex = placement.Location.IndexOf(':'); if (delimiterIndex < 0) { parentShape.Zones[placement.Location].Add(newShape); } else { var zoneName = placement.Location.Substring(0, delimiterIndex); var position = placement.Location.Substring(delimiterIndex + 1); parentShape.Zones[zoneName].Add(newShape, position); } }
public override ModelDriverResult Run(ModelShapeContext context) { switch (context.Mode) { case "Editor": if (context.Updater != null) { return(UpdateEditor(context)); } return(BuildEditor(context)); case "Display": // TODO: Maybe run BuildDisplay for all non-Editor modes? ... Or just convert legacies ... return(BuildDisplay(context)); } return(null); }
private void BindPlacement(ModelShapeContext context, string displayType, string stereotype, string contentType) { context.FindPlacement = (partShapeType, differentiator, defaultLocation) => { var theme = _themeService.Value.GetRequestTheme(_requestContext); var shapeTable = _shapeTableManager.GetShapeTable(theme.Id); var request = _requestContext.HttpContext.Request; ShapeDescriptor descriptor; if (shapeTable.Descriptors.TryGetValue(partShapeType, out descriptor)) { var placementContext = new ModelShapePlacementContext { ModelContext = context, Stereotype = stereotype, DisplayType = displayType, Differentiator = differentiator, ContentType = String.IsNullOrWhiteSpace(contentType)?context.Model.GetType().Name:contentType, // Get the current app-relative path, i.e. ~/my-blog/foo // TODO: This is for Url placement to work. It'd be far better if we could just inject any old strings into a properties dictionary, // or even a dictionary of LazyFields, so work like this doesn't have to happen. Not sure how long ToAppRelative takes but it's // getting called for every single placement op and might never get used... Path = VirtualPathUtility.AppendTrailingSlash(_virtualPathProvider.ToAppRelative(request.Path)) }; var placement = descriptor.Placement(placementContext); if (placement != null) { placement.Source = placementContext.Source; return(placement); } } return(new PlacementInfo { Location = defaultLocation, Source = String.Empty }); }; }
public void BuildDisplayShape(object model, dynamic root, string displayType, string stereotype, ModelShapeContext parentContext = null) { var context = new ModelDisplayShapeContext(model, root, displayType, Shape, parentContext) { Stereotype = stereotype }; //, prefix); BindPlacement(context, displayType, stereotype); foreach (var driver in Drivers) { var result = driver.BuildDisplay(context); if (result != null) { result.Apply(context); } } // Chain sub results? // They are applied to the same base object (as opposed to rendering an entirely new shape with its own zones) // TODO: Could be nice to chain from displays to editors and back (although then we'd always need the updater)... foreach (var chain in context.ChainedResults) { BuildDisplayShape(chain.Model, chain.Root ?? root, chain.DisplayType ?? displayType, stereotype, context); // Fire an event so parent shape can perform work after the update chain.OnCompleted(context); } // Done }
public ModelDisplayShapeContext(object model, IShape root, string displayType, IShapeFactory shapeFactory, ModelShapeContext parentContext) : base(model, root, displayType, shapeFactory, parentContext) { ChainedResults = new List <ModelChainContext>(); }
public UpdateContentEditorContext(IShape model, IContent content, string displayType, IUpdateModel updater, string groupId, IShapeFactory shapeFactory, ShapeTable shapeTable, ModelShapeContext parentContext = null) : base(model, content, updater, groupId, shapeFactory, shapeTable) { DisplayType = displayType; ParentContext = parentContext; }
protected virtual void Editing(ConnectorDisplayContext model, ModelShapeContext context) { }
private static object CreateShape(ModelShapeContext context, string shapeType) { IShapeFactory shapeFactory = context.New; return(shapeFactory.Create(shapeType)); }
public abstract ModelDriverResult Run(ModelShapeContext context);
void IConnectorHandler.Display(ConnectorDisplayContext model, dynamic shape, ModelShapeContext context) { Display(model, shape, context); }
private void BindPlacement(ModelShapeContext context, string displayType, string stereotype) { context.FindPlacement = (partShapeType, differentiator, defaultLocation) => { var theme = _themeService.Value.GetRequestTheme(_requestContext); var shapeTable = _shapeTableManager.GetShapeTable(theme.Id); var request = _requestContext.HttpContext.Request; ShapeDescriptor descriptor; if (shapeTable.Descriptors.TryGetValue(partShapeType, out descriptor)) { var placementContext = new ShapePlacementContext { Stereotype = stereotype, DisplayType = displayType, Differentiator = differentiator, Path = VirtualPathUtility.AppendTrailingSlash(VirtualPathUtility.ToAppRelative(request.Path)) // get the current app-relative path, i.e. ~/my-blog/foo }; var placement = descriptor.Placement(placementContext); if (placement != null) { placement.Source = placementContext.Source; return placement; } } return new PlacementInfo { Location = defaultLocation, Source = String.Empty }; }; }
void IConnectorHandler.Editing(ConnectorDisplayContext model, ModelShapeContext context) { Editing(model, context); }
public BuildContentEditorContext(IShape model, IContent content, string displayType, string groupId, IShapeFactory shapeFactory, ModelShapeContext parentContext = null) : base(model, content, groupId, shapeFactory) { DisplayType = displayType; ParentContext = parentContext; }
private void ApplyImplementation(ModelShapeContext context, string displayType) { // if (!string.Equals(context.GroupId ?? "", _groupId ?? "", StringComparison.OrdinalIgnoreCase)) // return; var placement = context.FindPlacement(_shapeType, _differentiator, _defaultLocation); if (string.IsNullOrEmpty(placement.Location) || placement.Location == "-") { return; } dynamic parentShape = context.Shape; var newShape = _shapeBuilder(context); // Handle null shape without an error if (newShape == null) { return; } ShapeMetadata newShapeMetadata = newShape.Metadata; newShapeMetadata.Prefix = _prefix; // Display type might have already been set (so we're not forced to use the one from the context) if (string.IsNullOrWhiteSpace(newShapeMetadata.DisplayType)) { 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(); } foreach (var alternate in placement.Alternates) { newShapeMetadata.Alternates.Add(alternate); } foreach (var wrapper in placement.Wrappers) { newShapeMetadata.Wrappers.Add(wrapper); } var delimiterIndex = placement.Location.IndexOf(':'); if (delimiterIndex < 0) { parentShape.Zones[placement.Location].Add(newShape); } else { var zoneName = placement.Location.Substring(0, delimiterIndex); var position = placement.Location.Substring(delimiterIndex + 1); parentShape.Zones[zoneName].Add(newShape, position); } }
public virtual void Apply(ModelShapeContext context) { }
private void BindPlacement(ModelShapeContext context, string displayType, string stereotype, string contentType) { context.FindPlacement = (partShapeType, differentiator, defaultLocation) => { var theme = _themeService.Value.GetRequestTheme(_requestContext); var shapeTable = _shapeTableManager.GetShapeTable(theme.Id); var request = _requestContext.HttpContext.Request; ShapeDescriptor descriptor; if (shapeTable.Descriptors.TryGetValue(partShapeType, out descriptor)) { var placementContext = new ModelShapePlacementContext { ModelContext = context, Stereotype = stereotype, DisplayType = displayType, Differentiator = differentiator, ContentType = String.IsNullOrWhiteSpace(contentType)?context.Model.GetType().Name:contentType, // Get the current app-relative path, i.e. ~/my-blog/foo // TODO: This is for Url placement to work. It'd be far better if we could just inject any old strings into a properties dictionary, // or even a dictionary of LazyFields, so work like this doesn't have to happen. Not sure how long ToAppRelative takes but it's // getting called for every single placement op and might never get used... Path = VirtualPathUtility.AppendTrailingSlash(_virtualPathProvider.ToAppRelative(request.Path)) }; var placement = descriptor.Placement(placementContext); if (placement != null) { placement.Source = placementContext.Source; return placement; } } return new PlacementInfo { Location = defaultLocation, Source = String.Empty }; }; }
void IConnectorHandler.UpdatingInverse(ConnectorDisplayContext model, ModelShapeContext context) { UpdatingInverse(model, context); }
public ModelEditorShapeContext(object model, IShape shape, IShapeFactory shapeFactory, string prefix, string displayType, IUpdateModel updater = null, ModelShapeContext parentContext = null) : base(model, shape, displayType, shapeFactory, parentContext) { Updater = updater; Prefix = prefix; }
protected ModelDriverResult EditorShape(string shapeType, object model, ModelShapeContext context) { return(ContentShapeImplementation(shapeType, FullPrefix(context), (ctx) => context.New.EditorTemplate(TemplateName: shapeType.Replace('_', '.'), Model: model, Prefix: FullPrefix(context)))); }
protected virtual void UpdatingInverse(ConnectorDisplayContext model, ModelShapeContext context) { }
void IConnectorHandler.Updated(ConnectorDisplayContext model, ModelShapeContext context) { Updated(model,context); }
public dynamic BuildContentShape(string mode, IContent content, string displayType, string groupId, dynamic itemShape = null, IUpdateModel updater = null, ModelShapeContext parentContext = null) { // TODO: This is all very well. But we *still* haven't found a way to sanitize Prefix for child editors :( ... perhaps with a Clay behaviour on shapeFactory? var actualDisplayType = string.IsNullOrWhiteSpace(displayType) ? "Detail" : displayType; var builder = ContentBuilder(content) .WithMode(mode) .WithDisplayType(actualDisplayType) ; if (itemShape == null) { var actualShapeType = builder.Context.Stereotype; // Slight Editor hack if (mode == "Editor") { actualShapeType = builder.Context.Stereotype + "_Edit"; } itemShape = CreateItemShape(actualShapeType); itemShape.ContentItem = content.ContentItem; itemShape.Metadata.DisplayType = actualDisplayType; } if (parentContext != null) { builder.WithParent(parentContext) .WithParadigms(parentContext.Paradigms); } if (updater != null) { builder.WithUpdater(updater, parentContext == null?"Content":parentContext.Prefix + ".Content"); } // Origami build (ContentHandlerModelDriver will delegate to ContentPartDrivers and everything else...) Build(builder, itemShape); return(itemShape); }
protected virtual void Display(ConnectorDisplayContext model, dynamic shape, ModelShapeContext context) { }
protected abstract ModelDriverResult Editor(T model, dynamic shapeHelper, ModelShapeContext context);
public ModelDisplayShapeContext(object model, IShape root, string displayType, IShapeFactory shapeFactory, ModelShapeContext parentContext) : base(model,root,displayType,shapeFactory,parentContext) { ChainedResults = new List<ModelChainContext>(); }
protected override dynamic BuildShape(ModelShapeContext context) { return(_shapeBuilder(context)); }
public static ModelShapeBuilder BuildEditorShape(this IOrigamiService origami, object model, IUpdateModel updater, string prefix, string displayType, string stereotype, string contentType = null, ModelShapeContext parentContext = null) { var builder = origami.Builder(model) .WithMode("Editor") .WithUpdater(updater, prefix) .WithDisplayType(displayType) .WithStereotype(stereotype) .WithContentType(contentType) .WithParent(parentContext); return(builder); }
public dynamic BuildContentDisplay(IContent content, string displayType, string groupId, IUpdateModel updater = null, ModelShapeContext parentContext = null) { return(BuildContentShape("Display", content, displayType, groupId, null, null, parentContext)); }
public override void Apply(ModelShapeContext context) { ApplyImplementation(context, context.DisplayType); }
protected abstract ModelDriverResult Update(T model, dynamic shapeHelper, IUpdateModel updater, ModelShapeContext context);
protected abstract dynamic BuildShape(ModelShapeContext context);
private void ApplyImplementation(ModelShapeContext context, string displayType) { // Match groups // TODO: Technically this can be achieved thru placement matches now ... if (context.GroupId != null) { if (!String.Equals(context.GroupId, _groupId ?? "", StringComparison.OrdinalIgnoreCase)) { return; } } var placement = context.FindPlacement(_shapeType, _differentiator, _defaultLocation); if (string.IsNullOrEmpty(placement.Location) || placement.Location == "-") { return; } dynamic parentShape = context.Shape; var newShape = BuildShape(context); // Handle null shape without an error if (newShape == null) { return; } ShapeMetadata newShapeMetadata = newShape.Metadata; newShapeMetadata.Prefix = _prefix; // Display type might have already been set (so we're not forced to use the one from the context) if (string.IsNullOrWhiteSpace(newShapeMetadata.DisplayType)) { 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(); } foreach (var alternate in placement.Alternates) { newShapeMetadata.Alternates.Add(alternate); } foreach (var wrapper in placement.Wrappers) { newShapeMetadata.Wrappers.Add(wrapper); } // TODO: One use of mutators is to add a new paradigm; might not be much use if the paradigm is added *after* placement has processed var modelPlacement = placement as ModelPlacementInfo; if (modelPlacement != null) { foreach (var mutator in modelPlacement.Mutators) { mutator.Invoke(modelPlacement, parentShape, newShape, newShapeMetadata, context); } } var delimiterIndex = placement.Location.IndexOf(':'); if (delimiterIndex < 0) { parentShape.Zones[placement.Location].Add(newShape); } else { var zoneName = placement.Location.Substring(0, delimiterIndex); var position = placement.Location.Substring(delimiterIndex + 1); parentShape.Zones[zoneName].Add(newShape, position); } }
public ModelShapeBuilder(object model, IShapeFactory factory) { Context = new ModelShapeContext(model, factory); }
protected virtual void Edit(ConnectorDisplayContext connectorContext, dynamic shape, ModelShapeContext context) { }
void IConnectorHandler.Edit(ConnectorDisplayContext connectorContext, dynamic shape, ModelShapeContext context) { Edit(connectorContext, shape, context); }
public dynamic BuildContentDisplay(IContent content, string displayType, string groupId, IUpdateModel updater = null, ModelShapeContext parentContext = null) { return BuildContentShape("Display", content, displayType, groupId, null, null, parentContext); }
public dynamic BuildContentShape(string mode, IContent content, string displayType, string groupId, dynamic itemShape = null, IUpdateModel updater = null, ModelShapeContext parentContext = null) { // TODO: This is all very well. But we *still* haven't found a way to sanitize Prefix for child editors :( ... perhaps with a Clay behaviour on shapeFactory? var actualDisplayType = string.IsNullOrWhiteSpace(displayType) ? "Detail" : displayType; var builder = ContentBuilder(content) .WithMode(mode) .WithDisplayType(actualDisplayType) ; if (itemShape == null) { var actualShapeType = builder.Context.Stereotype; // Slight Editor hack if (mode == "Editor") { actualShapeType = builder.Context.Stereotype + "_Edit"; } itemShape = CreateItemShape(actualShapeType); itemShape.ContentItem = content.ContentItem; itemShape.Metadata.DisplayType = actualDisplayType; } if (parentContext != null) { builder.WithParent(parentContext) .WithParadigms(parentContext.Paradigms); } if (updater != null) { builder.WithUpdater(updater,parentContext==null?"Content":parentContext.Prefix+".Content"); } // Origami build (ContentHandlerModelDriver will delegate to ContentPartDrivers and everything else...) Build(builder,itemShape); return itemShape; }