protected override LensFinderViewModel ViewModel(SocketEventContext model, ModelShapeContext context) { var viewModel = new LensFinderViewModel(); PopulateLensFinderModel(model, viewModel, context.Prefix, context.Updater); return(viewModel); }
public override ModelDriverResult Run(ModelShapeContext context) { var describe = _formulaService.DescribeModel(context.Model); var bits = describe.Fields.Select(f => ChainShape(f.Model(context), context.Prefix + "." + f.Name, null)); return(Combined(bits.ToArray())); }
protected override void Update(SocketDisplayContext model, dynamic shapeHelper, IUpdateModel updater, ModelShapeContext context) { }
protected override ModelDriverResult Build(LensViewModel model, LensQueryTextViewModel viewModel, dynamic shapeHelper, ModelShapeContext context) { var prefix = FullPrefix(context); return(ModelShape("Lens_Filters_QueryText", () => shapeHelper.Lens_Filters_QueryText(Model: viewModel, Prefix: prefix))); }
protected override ModelDriverResult Build(SocketEventContext model, LensFinderViewModel viewModel, dynamic shapeHelper, ModelShapeContext context) { var prefix = FullPrefix(context); return(ModelShape("Socket_Finders_LensSearch", () => { return shapeHelper.EditorTemplate(TemplateName: "Socket.Finders.LensSearch", Model: viewModel, Prefix: prefix); })); }
protected override ModelDriverResult Editor(SocketEventContext model, dynamic shapeHelper, ModelShapeContext context) { return(Update(model, shapeHelper, null, context)); }
private void BindPlacement(BuildShapeContext context, string displayType, string stereotype, ModelShapeContext modelContext) { 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 = modelContext, 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 }; var placement = descriptor.Placement(placementContext); if (placement != null) { placement.Source = placementContext.Source; return(placement); } } // Default return(new PlacementInfo { Location = defaultLocation, Source = String.Empty }); }; }
protected override ModelDriverResult Build(IContent model, dynamic shapeHelper, ModelShapeContext context) { if (context.Mode == "Editor") { if (context.Updater != null) { var updater = context.Updater; // If there's a parent prefix we can inject it now if (!String.IsNullOrWhiteSpace(context.Prefix)) { updater = new PrefixedUpdateModel(context.Prefix, context.Updater); } var workContext = _workContextAccessor.GetContext(_requestContext.HttpContext); var theme = workContext.CurrentTheme; var shapeTable = _shapeTableLocator.Value.Lookup(theme.Id); var context2 = new UpdateContentEditorContext(context.Shape, model, context.DisplayType, updater, context.GroupId, shapeHelper, shapeTable, context); BindPlacement(context2, context.DisplayType, context.Stereotype, context); _handlers.Value.Invoke(handler => handler.UpdateEditor(context2), Logger); } else { var context2 = new BuildContentEditorContext(context.Shape, model, context.DisplayType, context.GroupId, shapeHelper, context); BindPlacement(context2, context.DisplayType, context.Stereotype, context); _handlers.Value.Invoke(handler => handler.BuildEditor(context2), Logger); } } else { var context2 = new BuildContentDisplayContext(context.Shape, model, context.DisplayType, context.GroupId, shapeHelper, context); BindPlacement(context2, context.DisplayType, context.Stereotype, context); _handlers.Value.Invoke(handler => handler.BuildDisplay(context2), Logger); } return(null); }
private dynamic BuildDisplayDelegate(SocketDisplayContext socketContext, ModelShapeContext context) { var prefix = FullPrefix(context, socketContext.Connector.Definition.Name); // Set up display text socketContext.SocketMetadata.SocketTitle = String.IsNullOrWhiteSpace(socketContext.Connector.Settings.SocketDisplayName) ? (socketContext.Connector.Definition.DisplayName + (socketContext.Connector.Settings.AllowMany ? "s" : "")) : socketContext.Connector.Settings.SocketDisplayName; socketContext.SocketMetadata.DisplayHint = socketContext.Connector.Settings.SocketDisplayHint; socketContext.SocketMetadata.EditorHint = socketContext.Connector.Settings.SocketEditorHint; // Content querying and filtration process // TODO: Fully review and profile all this (and places where the lazies are accessed) socketContext.Query = socketContext.Left.ContentPart.Sockets.Socket(socketContext.Name); // Build a socket shape dynamic socket; if (context.Mode == "Editor") { _socketHandlers.Value.Invoke(s => s.Editing(socketContext), Logger); if (!socketContext.RenderSocket) { return(null); } socket = context.New.Socket_Edit(Prefix: prefix, ConnectorType: socketContext.Connector.Definition.Name, ContentItem: socketContext.Left.ContentItem); } else { _socketHandlers.Value.Invoke(s => s.Displaying(socketContext), Logger); if (!socketContext.RenderSocket) { return(null); } socket = context.New.Socket() .ConnectorType(socketContext.Connector.Name) .ContentItem(socketContext.Left.ContentItem); }; string displayType = socketContext.Left.DisplayType; if (!String.IsNullOrWhiteSpace(socketContext.Connector.DisplayType)) { displayType = socketContext.Connector.DisplayType; } socket.Metadata.DisplayType = displayType; if (context.Mode == "Editor") { // Edit/update handlers if (context.Updater == null) { _socketHandlers.Value.Invoke(s => s.Editor(socketContext), Logger); } else { _socketHandlers.Value.Invoke(s => s.Updating(socketContext), Logger); } if (!socketContext.RenderSocket) { return(null); } // Build the editor shape var builder1 = _origami.Value.BuildEditorShape(socketContext, context.Updater, prefix, displayType, "Socket", socketContext.Left.ContentType, context) .WithParadigms(socketContext.Paradigms); _origami.Value.Build(builder1, socket); if (context.Updater != null) { _socketHandlers.Value.Invoke(s => s.Updated(socketContext), Logger); } } else { // Build the display shape var builder = _origami.Value.BuildDisplayShape(socketContext, prefix, displayType, "Socket", socketContext.Left.ContentType, context) .WithParadigms(socketContext.Paradigms); _origami.Value.Build(builder, socket); } return(socket); }
protected override ModelDriverResult Update(ConnectorEventContext model, dynamic shapeHelper, Orchard.ContentManagement.IUpdateModel updater, ModelShapeContext context) { var prefix = FullPrefix(context); var part = model.ConnectorContent.As <SequencePart>(); if (part != null) { if (updater != null && updater.TryUpdateModel(part, prefix, null, null)) { // TODO: Adjust sequence of other items? } return(ModelShape("Connector_Editors_Sequence", () => shapeHelper.EditorTemplate(TemplateName: "Connector.Editors.Sequence", Model: part, Prefix: prefix))); } return(null); }
protected override ModelDriverResult Update(SocketEventContext model, dynamic shapeHelper, Orchard.ContentManagement.IUpdateModel updater, ModelShapeContext context) { return(Combined( ModelShape("Socket_Finders_SingleChoiceList", () => { var prefix = FullPrefix(context, "Single"); var viewModel = BuildSingleChoiceModel(model, prefix, updater); if (updater != null) { updater.TryUpdateModel(viewModel, prefix, null, null); UpdatedSingleChoiceModel(model, viewModel, prefix, updater); // Rebuild model viewModel = BuildSingleChoiceModel(model, prefix, updater); } return shapeHelper.EditorTemplate(TemplateName: "Socket.Finders.SingleChoiceList", Model: viewModel, Prefix: prefix); }), ModelShape("Socket_Finders_MultipleChoiceList", () => { var prefix = FullPrefix(context, "Multiple"); var viewModel = BuildMultipleChoiceModel(model, prefix, updater); if (updater != null) { updater.TryUpdateModel(viewModel, prefix, null, null); UpdatedMultipleChoiceModel(model, viewModel, prefix, updater); // Rebuild model viewModel = BuildMultipleChoiceModel(model, prefix, updater); } return shapeHelper.EditorTemplate(TemplateName: "Socket.Finders.MultipleChoiceList", Model: viewModel, Prefix: prefix); } ))); }
protected override void Update(LensResultsViewModel model, dynamic shapeHelper, Orchard.ContentManagement.IUpdateModel updater, ModelShapeContext context) { // This model runs after the first LensViewModel, so we've collected filters etc. }
protected override ModelDriverResult Build(LensResultsViewModel model, dynamic shapeHelper, ModelShapeContext context) { return(null); }
protected override ModelDriverResult Build(SocketEventContext model, dynamic shapeHelper, ModelShapeContext context) { return(ModelShape("Socket_Creators_AddNewLinks", () => { var data = model.Connector.Settings.ListAllowedContentRight().Select(c => _contentDefinitionManager.GetTypeDefinition(c)).Select(d => new { RouteValues = new { area = "Contents", controller = "Admin", action = "Create", socket_populate_name = d.Name, socket_populate_id = model.Left.ContentItem.Id }, Name = d.DisplayName }); return shapeHelper.Socket_Creators_AddNewLinks(Links: data); })); }
private IEnumerable <dynamic> MapContentList(SocketDisplayContext model, ModelShapeContext context, Func <ConnectorDisplayContext, string, dynamic> rootShapeFactory, Action <ConnectorDisplayContext, dynamic, string> buildDisplay) { // HACK: Invoke filter delegate model.Filtering(); // Build filters etc. starting with a delegate we'll compose // TODO: Need access to some filter functionality outside for Alchemy (part of Alchemy, Lens, or some other system?) Func <IContentQuery, IContentQuery> baseDelegate = q => q; baseDelegate = model.SocketFilters.Aggregate(baseDelegate, (d, f) => (q => f.Apply(d(q)))); baseDelegate = model.SocketSorters.Aggregate(baseDelegate, (d, f) => (q => f.Apply(d(q)))); IEnumerable <IConnector> list; list = (model.SocketPager == null? model.Query.Connectors.List(baseDelegate) : model.Query.Connectors.List(baseDelegate, model.SocketPager)); var items = new List <dynamic>(); foreach (var c in list) { if (c.RightContent == null) { continue; } var connectorContext = new ConnectorDisplayContext(c, String.IsNullOrWhiteSpace(model.Connector.DisplayType)?context.DisplayType:model.Connector.DisplayType, model); if (context.Mode == "Editor") { _connectorHandlers.Value.Invoke(ch => ch.Editing(connectorContext, context), Logger); } else { _connectorHandlers.Value.Invoke(ch => ch.Displaying(connectorContext, context), Logger); } if (!connectorContext.RenderConnector) { continue; } // TODO: This prefix won't work if you add multiple connectors to the same item... var prefix = FullPrefix(context, c.Id == 0 ? ("New" + c.RightContentItemId.ToString()) : c.Id.ToString()); var shape = rootShapeFactory.Invoke(connectorContext, prefix); shape.Metadata.DisplayType = connectorContext.Right.DisplayType; shape.Metadata.Prefix = prefix; if (context.Mode == "Editor") { _connectorHandlers.Value.Invoke(ch => ch.Edit(connectorContext, shape, context), Logger); } else { _connectorHandlers.Value.Invoke(ch => ch.Display(connectorContext, shape, context), Logger); } buildDisplay.Invoke(connectorContext, shape, prefix); items.Add(shape); } ; return(items); }
protected override ModelDriverResult Build(SocketEventContext model, dynamic shapeHelper, ModelShapeContext context) { return(Combined( ModelShape("Sockets_SocketTitle", () => shapeHelper.Sockets_SocketTitle(SocketTitle: model.SocketMetadata.SocketTitle ?? "", SocketHint: model.SocketMetadata.DisplayHint)), ModelShape("Sockets_SocketTitle_Edit", () => shapeHelper.Sockets_SocketTitle_Edit(SocketTitle: model.SocketMetadata.SocketTitle ?? "", SocketHint: model.SocketMetadata.EditorHint)) )); }
protected override void Update(SocketEventContext model, dynamic shapeHelper, Orchard.ContentManagement.IUpdateModel updater, ModelShapeContext context) { }
protected override void Update(SocketsModel model, dynamic shapeHelper, Orchard.ContentManagement.IUpdateModel updater, ModelShapeContext context) { // Handled in Build }
protected override void Update(IContent model, dynamic dynamic, IUpdateModel iUpdateModel, ModelShapeContext context) { }
protected override ModelDriverResult Build(SocketsModel model, dynamic shapeHelper, ModelShapeContext context) { // HACK: Check for pre-populated sockets // We need a better way to get day into here, we might want to populate other stuff, will need a custom controller string prepopulateSocket = null; int? prepopulateId = null; if (Services.WorkContext.HttpContext != null) { if (Services.WorkContext.HttpContext.Request.QueryString["socket_populate_name"] != null) { prepopulateSocket = Services.WorkContext.HttpContext.Request.QueryString["socket_populate_name"]; prepopulateId = Services.WorkContext.HttpContext.Request.QueryString["socket_populate_id"].ParseInt(); } } // Get all types of Connector var result = new List <ModelDriverResult>(); foreach (var t in model.LeftContent.As <SocketsPart>().Sockets.Allowed) { // TODO: Even this constructor performs some non-trivial work; since it could run a lot of times for a detailed request // we should simplify it a lot var socketContext = new SocketDisplayContext(model.LeftContent, t, context.DisplayType, model) { ModelContext = context }; if (!String.IsNullOrWhiteSpace(socketContext.Connector.Settings.DefaultParadigms)) { socketContext.Paradigms.Add(socketContext.Connector.Settings.DefaultParadigms.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)); } else { socketContext.Paradigms.Add(context.Paradigms.All()); } socketContext.Paradigms.Add("Socket"); _socketHandlers.Value.Invoke(s => s.Preparing(socketContext), Logger); if (!socketContext.RenderSocket) { continue; } // HACK: The way this delegate works is pretty awful and needs revision. It can also get called multiple times (e.g. rendering two different types of socket contents) // which is why I'm clearing the filters. Really it needs to work completely differently so we can sort and filter directly on the SocketQuery. socketContext.Filtering = () => { socketContext.SocketFilters.Clear(); socketContext.SocketSorters.Clear(); _socketHandlers.Value.Invoke(s => s.Filtering(socketContext), Logger); }; // From this point on, all the handling needs to happen in a factory so it'll only get executed if placement says so // Otherwise, we start running into exponential performance problems as we get more and more connections happening. // Place in layout? // TODO: LayoutPlacement is completely redundant now we have ZoneProxy and Alchemy methods. Paperclip could still be used for the placement-per-item scenario. // TODO: Cache therefore needs fixing to work on normal sockets. if (!String.IsNullOrWhiteSpace(socketContext.LayoutPlacement)) { dynamic display; if (socketContext.CacheSocket) { var key = new SocketCacheKey(model.LeftContent.Id, t.Name, context.DisplayType, Services.WorkContext.HttpContext.Request.Path); var cacheResult = _cacheManager.Get <SocketCacheKey, SocketCacheResult>(key, ctx => { // Set up cache terms ctx.Monitor(_signals.When(new ContentItemSignal(key.Id))); ctx.Monitor(_signals.When("Mechanics_Cache_AllContent")); // Build shape var socket = BuildDisplayDelegate(socketContext, context); // Sockets can still not render at this point and we want to avoid an error in core shapes return(new SocketCacheResult() { Display = socket }); }); display = shapeHelper.SocketCache(Cache: cacheResult); } else { display = BuildDisplayDelegate(socketContext, context); } // Figure out exact placement var placementBits = socketContext.LayoutPlacement.Split(':'); if (placementBits.Length > 1) { // Zone with position Services.WorkContext.Layout.Zones[placementBits[0]].Add(display, placementBits[1]); } else { // Zone without position Services.WorkContext.Layout.Zones[placementBits[0]].Add(display); } } else { var socketResult = new SocketsDriverResult("Socket", "" /*FullPrefix(context)*/, socketContext, BuildDisplayDelegate).Differentiator(t.Name); // TODO: Hack for Site Settings to show sockets on group pages. We can do more with groups than this; support group-by-placement and have tabbed group zones if (model.LeftContent.ContentItem.ContentType == "Site") { // TODO: Allow this (and other settings) to be mutated during the handler pipeline var groupId = socketContext.Connector.Settings.SocketGroupName; socketResult.OnGroup(groupId); } result.Add(socketResult); } } return(Combined(result.ToArray())); }
protected override ModelDriverResult Display(SocketEventContext model, dynamic shapeHelper, ModelShapeContext context) { return(null); }
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 override ModelDriverResult Update(SocketEventContext model, dynamic shapeHelper, Orchard.ContentManagement.IUpdateModel updater, ModelShapeContext context) { var prefix = FullPrefix(context); var viewModel = new ConnectorBatchOperationViewModel() { BatchCommandList = new[] { new SelectListItem() { Selected = true, Text = "(nothing)", Value = "" }, new SelectListItem() { Selected = false, Text = "Remove", Value = "Delete" }, } }; if (updater != null) { if (updater.TryUpdateModel(viewModel, prefix, null, null)) { if (!String.IsNullOrWhiteSpace(viewModel.BatchCommand)) { context.OnUpdated(updated => { switch (viewModel.BatchCommand) { case "Delete": // Delete all selected foreach (var selector in model.Query.Connectors.State <ConnectorSelector>()) { model.Query.Connectors.Remove(selector.Item1); } break; } }); } } } return(ModelShape("Socket_Creators_BatchOperation", () => shapeHelper.EditorTemplate(TemplateName: "Socket.Creators.BatchOperation", Prefix: prefix, Model: viewModel))); }
protected override ModelDriverResult Display(ConnectorEventContext model, dynamic shapeHelper, ModelShapeContext context) { // TODO: For display purposes we might want to group roles and display "Moderators: username, username; Admins: username, username" // Actually that could be done more easily with different connectors for each role rather than crazy grouping scenarios... return(new ModelDriverResult()); }
protected override void Update(SocketEventContext model, LensFinderViewModel viewModel, dynamic shapeHelper, IUpdateModel updater, ModelShapeContext context) { var prefix = FullPrefix(context); if (updater != null) { updater.TryUpdateModel(viewModel, prefix, null, null); UpdatedLensViewModel(model, viewModel, prefix, updater); } }
protected override ModelDriverResult Editor(ConnectorEventContext model, dynamic shapeHelper, ModelShapeContext context) { var part = model.ConnectorContent.As <EffectiveRolesPart>(); if (part == null) { return(new ModelDriverResult()); } var viewModel = BuildViewModel(part); return(ModelShape("Connector_Editors_EffectiveRoles", () => shapeHelper.EditorTemplate(TemplateName: "Connector.Editors.EffectiveRoles", Model: viewModel, Prefix: FullPrefix(context)))); }
protected override LensQueryTextViewModel ViewModel(LensViewModel model, ModelShapeContext context) { return(new LensQueryTextViewModel()); }
protected override ModelDriverResult Update(ConnectorEventContext model, dynamic shapeHelper, Orchard.ContentManagement.IUpdateModel updater, ModelShapeContext context) { var part = model.ConnectorContent.As <EffectiveRolesPart>(); if (part == null) { return(new ModelDriverResult()); } var viewModel = BuildViewModel(part); var prefix = FullPrefix(context); if (updater.TryUpdateModel(viewModel, prefix, null, null)) { // TODO: Check role exists and user is allowed permission part.EffectiveRoles = String.Join(" ", viewModel.SelectRoles.ToArray()); } else { _notifier.Error(T("Error updating Effective Roles.")); } return(ModelShape("Connector_Editors_EffectiveRoles", () => shapeHelper.EditorTemplate(TemplateName: "Connector.Editors.EffectiveRoles", Model: viewModel, Prefix: prefix))); }
protected override void Update(LensViewModel model, LensQueryTextViewModel viewModel, dynamic shapeHelper, Orchard.ContentManagement.IUpdateModel updater, ModelShapeContext context) { updater.TryUpdateModel(model, FullPrefix(context), null, null); }
protected override ModelDriverResult Build(SocketDisplayContext model, dynamic shapeHelper, ModelShapeContext context) { var results = new List <ModelDriverResult>(); // TODO: Pagers return(Combined( ModelShape( "Sockets_Contents_Connectors", () => { var items = MapContentList(model, context, (c, prefix) => { return shapeHelper.Connector(ConnectorType: c.Descriptor.Name, ContentItem: c.ConnectorContent.ContentItem); }, (c, shape, prefix) => { var builder = _origami.Value.BuildDisplayShape(c, prefix, c.Right.DisplayType, context.Stereotype, model.Connector.Name, context).WithParadigms(model.Paradigms); _origami.Value.Build(builder, shape); }); var root = shapeHelper.Sockets_Contents(Contents: items); return root; }), ModelShape( "Sockets_Contents_Right", () => { var items = MapContentList(model, context, (c, prefix) => { // Build content shape // TODO: Might want to use different display types / paradigms for content shape and connector? return _origami.Value.ContentShape(c.Right.Content, c.Right.DisplayType, prefix: prefix); }, (c, shape, prefix) => { var builder = _origami.Value.BuildDisplayShape(c.Right.Content, prefix, c.Right.DisplayType, context.Stereotype, c.Right.ContentType, context) // TODO: Need mode and updater in here to work properly for editors .WithParadigms(model.Paradigms).WithParadigms(new[] { "Nested" }); _origami.Value.Build(builder, shape); }); var root = shapeHelper.Sockets_Contents(Contents: items); return root; }), ModelShape( "Sockets_Contents_Flat", () => { var items = MapContentList(model, context, (c, prefix) => { // Build content shape var shape = _origami.Value.ContentShape(c.ConnectorContent.ContentItem, c.Right.DisplayType, prefix: prefix); shape.ContentConnector = c.ConnectorContent.ContentItem; shape.ContentRight = c.Right.Content.ContentItem; shape.ContentLeft = c.SocketContext.Left.ContentItem; return shape; }, (c, shape, prefix) => { // TODO: Need mode and updater in here to work properly for editors var builder = _origami.Value.BuildDisplayShape(c.ConnectorContent, prefix, c.Right.DisplayType, context.Stereotype, model.Connector.Name, context) .WithParadigms(model.Paradigms) .WithParadigms(new[] { "Nested" }); _origami.Value.Build(builder, shape); var builder2 = _origami.Value.BuildDisplayShape(c.Right.Content, prefix, c.Right.DisplayType, context.Stereotype, c.Right.ContentType, context) .WithParadigms(model.Paradigms) .WithParadigms(new[] { "Nested" }); _origami.Value.Build(builder2, shape); }); var root = shapeHelper.Sockets_Contents(Contents: items); return root; }), ModelShape( "Sockets_Contents_Edit", () => { var items = MapContentList(model, context, (c, prefix) => { return shapeHelper.Connector_Edit(ContentItem: c.SocketContext.Left.ContentItem, RightContentItem: c.Right.Content, ConnectorType: c.Descriptor.Name, RightContentType: c.Right.ContentType, LeftContentType: c.SocketContext.Left.ContentType); }, (c, shape, prefix) => { var builder = _origami.Value.BuildEditorShape(c, context.Updater, prefix, c.Right.DisplayType, context.Stereotype, model.Connector.Name, context).WithMode("Editor").WithParadigms(model.Paradigms); _origami.Value.Build(builder, shape); }); var root = shapeHelper.Sockets_Contents(Contents: items); return root; }), ModelShape( "Sockets_Contents_Links", () => { var items = MapContentList(model, context, (c, prefix) => { return shapeHelper.Link(); }, (c, shape, prefix) => { // TODO: I *think* it's best to only populate the shape's properties here; so they can definitely be adjusted in content events first, and // it prevents processing if the connector isn't displayed. On the other hand, maybe it'd be better to let connector events alter the // shape directly instead .. var metadata = c.Right.Metadata; if (metadata.DisplayRouteValues != null) { shape.Text = metadata.DisplayText; shape.Values = metadata.DisplayRouteValues; } ; }); var root = shapeHelper.SeparatorList(Items: items); return root; }) )); }