示例#1
0
 protected override void Preparing(SocketDisplayContext context)
 {
     if (context.ModelContext.Mode == "Display" && context.Paradigms.Has("Navigation") && context.ModelContext.DisplayType == "Navigation")
     {
         context.Connector.DisplayType = "Navigation";
     }
 }
        protected override void Displaying(SocketDisplayContext context)
        {
            // Set a paradigm for empty sockets
            if (context.Query.TotalCount == 0)
            {
                context.Paradigms.Add("Empty");
                if (!context.Paradigms.Has("ShowEmpty"))
                {
                    context.RenderSocket = false;
                }
                // TODO: A pure-placement method didn't work because Displaying happens after Placement. But we don't want to execute the count for every single connector type
                // because a lot will already be decided against in advance. Either a) cache the current count on SocketsPartRecord or b) find another way, e.g. a delegate that
                // will only run if placement hasn't already been denied.
//                context.Paradigms.Add("Empty");
            }

            // Do some default display type mapping
            // TODO: Could be done in placement now?
            if (String.IsNullOrWhiteSpace(context.Connector.DisplayType))
            {
                switch (context.Left.DisplayType)
                {
                case "Detail":
                    context.Connector.DisplayType = "Summary";
                    break;

                case "Summary":
                    context.Connector.DisplayType = "SummaryTiny";
                    context.Paradigms.Add("ConnectorsFlatten");
                    break;

                case "SummaryAdmin":
                    context.Connector.DisplayType = "Link";
                    context.Paradigms.Add("ConnectorsFlatten");
                    break;

                case "SummaryTiny":
                    // Prevent further recursion by default
                    context.RenderSocket = false;
                    break;

                case "Link":
                    // Prevent further recursion by default
                    context.RenderSocket = false;
                    break;

                default:
                    // Any other situtations we don't understand, just use links.
                    context.Connector.DisplayType = "Link";
                    break;
                }
            }
        }
示例#3
0
 protected override void Displaying(SocketDisplayContext context)
 {
     // TODO: Optionally expose a unified feed comprised of all applicable connector types.
     // TODO: We could feasibly want to register the feed on other display types
     if (context.Left.DisplayType == "Detail")
     {
         var settings = context.Connector.PartDefinition.Settings.GetModel <AggregationTypePartSettings>();
         if (settings != null && settings.ExposeFeed)
         {
             _feedManager.Register(context.Left.ContentItem.GetTitle() + " - " + context.SocketMetadata.SocketTitle, "rss", new RouteValueDictionary {
                 { "id", context.Left.ContentItem.Id }, { "connector", context.Connector.Name }
             });
         }
     }
 }
 protected override void Preparing(SocketDisplayContext context)
 {
     context.ModelContext.With <DrillFilterData>(df => {
         if (context.Connector.Name == df.DrillType)
         {
             context.Paradigms.Add("DrillSummary");
             if (df.Id.HasValue)
             {
                 context.ModelContext.Paradigms.Add("DrillDetail");
             }
         }
         else
         {
             context.Paradigms.Add("DrillExclude");
         }
     });
 }
        protected override void Preparing(SocketDisplayContext context)
        {
            if (context.Left.DisplayType == "Detail")
            {
                var clipPart = context.Connector.Definition.Parts.FirstOrDefault(p => p.PartDefinition.Name == "PaperclipPart");
                if (clipPart != null)
                {
                    // Get actual part model from item
                    var settings = clipPart.Settings.GetModel <PaperclipTypePartSettings>();
                    if (!String.IsNullOrWhiteSpace(settings.DefaultPlacement))
                    {
                        context.LayoutPlacement = settings.DefaultPlacement;
                    }

                    if (!String.IsNullOrWhiteSpace(settings.DefaultDisplayType))
                    {
                        context.Connector.DisplayType = settings.DefaultDisplayType;
                    }
                }
            }
        }
        protected override void Editing(SocketDisplayContext context)
        {
            context.Left.DisplayType      = "Editor";
            context.Connector.DisplayType = "EditorConnector";

            if (context.Query.TotalCount == 0)
            {
                context.Paradigms.Add("Empty");
            }

            // Check box list or drop down list?
            context.Paradigms.Add(context.Connector.Settings.AllowMany ? "Many" : "One");
            context.Paradigms.Add(context.Connector.Settings.AllowDuplicates ? "DuplicatesPossible" : "Unique");

            // Outright hide editor. Typically used when we have an inverse connector and we only
            // actually want to work with one end of the connector in UI.
            if (context.Paradigms.Has("Hidden"))
            {
                context.RenderSocket = false;
            }
        }
示例#7
0
        protected override void Displaying(SocketDisplayContext context)
        {
            if (context.RootModel.DisplayType == "Detail")
            {
                switch (context.Connector.Name)
                {
                case "CountryToTown":
                    context.Left.DisplayType = context.Connector.DisplayType = "Directory";
                    // TODO: In migration add to settings
                    context.Paradigms.Add("Count");
                    break;

                case "TownToAddress":
                    context.Left.DisplayType = context.Connector.DisplayType = "Listing";
                    // TODO: In migration add to settings
                    context.Paradigms.Add("Collapse");
                    break;
                }
            }

            // From DirectoryController, we get a bunch of Address items in Summary mode
            if (context.RootModel.DisplayType == "Summary")
            {
                switch (context.Connector.Name)
                {
                case "AddressToUser":
                    context.Left.DisplayType = context.Connector.DisplayType = "Listing";
                    break;

                case "AddressToTown":
                    context.Left.DisplayType = context.Connector.DisplayType = "Listing";
                    break;
                }
            }

            if (context.RootModel.DisplayType == "Listing")
            {
                // ...
            }
        }
示例#8
0
 public SocketsDriverResult(string shapeType, string prefix, Framework.SocketDisplayContext socketContext, Func <SocketDisplayContext, ModelShapeContext, dynamic> factory)
     : base(shapeType, prefix, (c) => factory(socketContext, c))
 {
     SocketContext = socketContext;
 }
示例#9
0
        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()));
        }
示例#10
0
        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);
        }
示例#11
0
 protected override void Displaying(SocketDisplayContext context)
 {
 }