Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Brian Lacy 28 posts 101 karma points
    Apr 12, 2016 @ 23:14
    Brian Lacy
    0

    Manage Content Tree Sort Order via API?

    I have a particular node in my Content Tree that always needs to stay at the bottom of its group of siblings. I also have a particular document type that should always be listed at the beginning of its sibling group/level.

    Is there some way to manipulate the sort order of tree items via code?

  • Alex Skrypnyk 6163 posts 24143 karma points MVP 8x admin c-trib
    Apr 13, 2016 @ 07:18
    Alex Skrypnyk
    1

    Hi Brian,

    So you want to be sure that your nodes is in some order.

    You can subscribe on NodeCreating event, and check order of nodes.

    Read more about events - https://our.umbraco.org/documentation/Reference/Events/ContentService-Events

    Example:

            var parent = Services.ContentService.GetByLevel(1).FirstOrDefault();
    
            parent.Children().OrderBy(x => x.SortOrder);
    
            Services.ContentService.Save(parent);
    

    Thanks

  • Brian Lacy 28 posts 101 karma points
    Apr 13, 2016 @ 15:46
    Brian Lacy
    0

    I want to ensure that the nodes are ALWAYS in a specific order, not just at Create time.

    I've figured out that when someone Sorts the content tree nodes, the Saving and Saved events are called. However, there does not appear to be any reliable way to check that it's specifically a Sorting event.

    For now this is what I'm doing:

    if (e.SavedEntities.Count() > 1)
    {
        // Check that they all have the same parent
    
        var parents = e.SavedEntities.Select(n => n.ParentId).Distinct();
        if (parents.Count() == 1)
        {
            // This MIGHT be a Sort event...
    
            foreach (var entity in e.SavedEntities)
            {
                // set entity.SortOrder here ...
    
                contentService.Save(entity);
            }
        }
    }
    

    However this seems risky to me. Surely there's a better way?

  • Alex Skrypnyk 6163 posts 24143 karma points MVP 8x admin c-trib
    Apr 14, 2016 @ 14:17
    Alex Skrypnyk
    0

    Hi Brian,

    We can be sure that each sort event have to call save event, it's great stuff for us.

    Umbraco hasn't event like newOrder_event

    So saving event with checking is great way for doing it

    Thanks

  • Bendik Engebretsen 105 posts 202 karma points
    Feb 13, 2017 @ 22:41
    Bendik Engebretsen
    2

    Hi Brian,

    Your post i almost a year old, and you have probably solved your challenge here. But I came across this post while working on a similar case, so I thought I'd share my thoughts and a possible solution.

    In my case, I needed to keep all the nodes in an order determined by a property value, basically an index. So if the user created a new sibling node and gave a value to this index property which was already used by an existing node, the existing node and all its successors would have to be moved one step down. Incrementing the index value was quite straightforward, but the sort order in Umbraco was trickier. What I ended up with was this: Catch the Saved event of ContentService and sort all the sibling nodes with the ContentService.Sort method.

    Here's a little code that might help:

        public class SaveContentEventHandler : ApplicationEventHandler
        {
    
            protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
            {
                ContentService.Saved += ContentServiceSaved;
            }
    
            private void ContentServiceSaved(IContentService sender, SaveEventArgs<IContent> e)
            {
                foreach (IContent node in e.SavedEntities)
                {
                    if (node.ContentType.Alias == "Your content type alias")
                    {
                        // Sort all siblings of this node by some property value
                        sender.Sort(node.Parent().Children().OrderBy(n => n.GetValue<int>("Some property alias")), 0, false);
                    }
                 }
             }
        }
    

    This assumes you have an int property in this content type to sort by. But the key here is the first parameter of the Sort method: This is a list (IEnumerable

    Note also the last parameter to Sort set to false. This means you avoid getting a bunch of reentry calls to your ContentServiceSaved handler while the Sort method is doing its saving;-)

Please Sign in or register to post replies

Write your reply to:

Draft