Copied to clipboard

Flag this post as spam?

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


  • Jon R. Humphrey 164 posts 455 karma points c-trib
    Jan 08, 2016 @ 01:38
    Jon R. Humphrey
    1

    Umbraco 7: How to put a newly created node on top

    [UPDATED]

    After finding Simon Dingley's SO post on "Umbraco 6: How to put newly created node on top" I've tried to implement the sorting but I think things have changed enough that this doesn't seem to actually work and the new node is placed at the bottom of the list of any siblings instead of at the top where I need it to be?

    Also, the duplicate check seems to be failing as multiple nodes are being created at different levels at different times if anyone can see where that's wrong?

    Here's an image as an example of the replication issue:

    enter image description here

    If the nodes are manually sorted to put the module manager at the top - the duplication doesn't happen of course as the "found" flag is triggered immediately in the loop but then is ignored as it loops through the children?

    Here's the latest code:

    using System;using System.Diagnostics;
    using System.Linq;
    using Umbraco.Core;
    using Umbraco.Core.Events;
    using Umbraco.Core.Logging;
    using Umbraco.Core.Models;
    using Umbraco.Core.Services;
    
    namespace NG.USK.Helpers
    {
      /// <summary>
      /// Check for a child page element for each of the main parent document types to enable the usage of the individual functionality module plugins
      /// </summary>
      public class CreatePageElements : ApplicationEventHandler
      {
        public CreatePageElements()
        {
          ContentService.Saved += ContentService_Saved;
        }
    
        private static void ContentService_Saved(IContentService sender, SaveEventArgs<IContent> args)
        {
          foreach (
            var node in
              args.SavedEntities.Where(
                node =>
                  node.ContentType.Alias.InvariantEquals("NG_USK_Homepage") ||
                  node.ContentType.Alias.InvariantEquals("NG_USK_StandardPage") ||
                  node.ContentType.Alias.InvariantEquals("NG_USK_StandardPageChild") ||
                  node.ContentType.Alias.InvariantEquals("NG_USK_NewsArticle") ||
                  node.ContentType.Alias.InvariantEquals("NG_USK_Downloads")
                )
            )
          {
            try
            {
              if (!node.Children().Any())
              {
                MakePageElements(node);
              }
              else
              {
                var ignore = false;
                foreach ( var child in node.Children())
                {
                  if (child.ContentType.Alias.InvariantEquals("NG_USK__PageElements"))
                  {
                    ignore = true;
                  }
                  if (ignore == false)
                  {
                    MakePageElements(node);
                  }
                }
              }
    
            }
            catch (Exception err)
            {
              // Get stack trace for the exception with source file information
              var st = new StackTrace(err, true);
              // Get the top stack frame
              var frame = st.GetFrame(0);
              // Get the line number from the stack frame
              var line = frame.GetFileLineNumber();
              LogHelper.Warn(typeof(CreatePageElements), "ERROR ON: ContentService_Saved - " + node.ContentType.Alias + " ~ " + err.Message + "[" + line + "]:" + st);
            }
          }
        }
    
        private static void MakePageElements(IContent node)
        {
          if (
              node.ContentType.Alias.InvariantEquals("NG_USK__AutoRedirect") ||
              node.ContentType.Alias.InvariantEquals("NG_USK_LandingPage")
          )
          {
            return;
          }
          var nodeName = node.Name;
          var pageModuleName = nodeName + " Modules";
          var cs = ApplicationContext.Current.Services.ContentService;
          var elementsNode = cs.CreateContent(pageModuleName, node.Id, "NG_USK__PageElements");
          //get the new node's parent
          var parentNode = elementsNode.Parent();
          //Check if parentNode.Children is greater than just the new elementNode to squish the "Sequence contains no elements" error
          if (parentNode.Children().Count() > 1)
          {
            //move the node to the first child: <-- THIS IS WHERE IT FALLS OVER!!!!
            elementsNode.SortOrder = parentNode.Children().OrderBy(n => n.SortOrder).First().SortOrder - 1;
          }
          else
          {
            elementsNode.SortOrder = 0;
          }
    
          //Get this value again for logging:
          var hider = string.Empty;
    
          //Make sure the element has the NaviHide property available
          if (elementsNode.HasProperty("umbracoNaviHide"))
          {
            //tell it to have the NaviHide Property set to true:
            elementsNode.SetValue("umbracoNaviHide", true);
            //Get this value again for logging:
            hider = elementsNode.GetValue<string>("umbracoNaviHide") == "0" ? "hide" : "show";
          }
    
          //Log this to the TraceLog
          LogHelper.Info(typeof(CreatePageElements), "DETAILS ON: " + elementsNode.Name + " is now the " + elementsNode.SortOrder + " child of " + parentNode.Name + " and set to " + hider);
    
          //save and publish
          cs.SaveAndPublishWithStatus(elementsNode);
    
        }
      }
    }
    

    Thanks everyone!

  • Marc Goodson 2140 posts 14323 karma points MVP 8x c-trib
    Jan 23, 2016 @ 13:07
    Marc Goodson
    0

    Hi Jon

    I'm wondering if you can achieve what you are after using the ContentServices Sort method ?

    https://our.umbraco.org/documentation/reference/management/services/contentservice

    the gist of which would be...

              void ContentService_Saved(IContentService sender, Umbraco.Core.Events.SaveEventArgs<IContent> e)
                    {
                        foreach (var content in e.SavedEntities
                            //Check if the content item type has a specific alias
                          //  .Where(c => c.ContentType.Alias.InvariantEquals("MyContentType"))
                            //Check if it is a new item
                            .Where(c => c.IsNewEntity()))
                        {
        // reference the content service
                            var contentService = ApplicationContext.Current.Services.ContentService;
        // get the sibling nodes but not the one that has just been saved, into a list
                            var siblingContentItems = content.Parent().Children().Where(f => f.Id != content.Id).ToList();
        // add the one being saved to the start of the list
                            siblingContentItems.Insert(0,content);
        // call contentService Sort method on the list...
                            contentService.Sort(siblingContentItems); 
    
                        }
                    }
    
  • Jon R. Humphrey 164 posts 455 karma points c-trib
    Jan 24, 2016 @ 03:08
    Jon R. Humphrey
    0

    Marc,

    Thank you so much for this, it's put me that much closer to the goal as we now have sort sorted!

    However, it seems the code is still not triggering the "ignore" flag and, therefore, is generating multiple ModuleManager nodes under the home node:

    correct sort - still multiple nodes

    Here is the new codebase:

    using System;using System.Diagnostics;
    using System.Linq;
    using Umbraco.Core;
    using Umbraco.Core.Events;
    using Umbraco.Core.Logging;
    using Umbraco.Core.Models;
    using Umbraco.Core.Services;
    
    namespace NG.USK.Helpers
    {
      /// <summary>
      /// Check for a child page element for each of the main parent document types to enable the usage of the individual functionality module plugins
      /// </summary>
      public class CreateModuleManager : ApplicationEventHandler
      {
        public CreateModuleManager()
        {
          ContentService.Saved += ContentService_Saved;
        }
    
        private static void ContentService_Saved(IContentService sender, SaveEventArgs<IContent> args)
        {
          foreach (
            var node in
              args.SavedEntities.Where(
                node =>
                  node.ContentType.Alias.InvariantEquals("NG_USK_Homepage") ||
                  node.ContentType.Alias.InvariantEquals("NG_USK_StandardPage") ||
                  node.ContentType.Alias.InvariantEquals("NG_USK_StandardPageChild") ||
                  node.ContentType.Alias.InvariantEquals("NG_USK_NewsArticle") ||
                  node.ContentType.Alias.InvariantEquals("NG_USK_Downloads")
                )
            )
          {
            try
            {
              if (!node.Children().Any())
              {
                MakeModuleManager(node);
              }
              else
              {
                var ignore = false;
                foreach ( var child in node.Children())
                {
                  if (child.ContentType.Alias.InvariantEquals("NG_USK__ModuleManager"))
                  {
                    ignore = true;
                  }
                  if (ignore == false)
                  {
                    MakeModuleManager(node);
                  }
                }
              }
    
            }
            catch (Exception err)
            {
              // Get stack trace for the exception with source file information
              var st = new StackTrace(err, true);
              // Get the top stack frame
              var frame = st.GetFrame(0);
              // Get the line number from the stack frame
              var line = frame.GetFileLineNumber();
              LogHelper.Warn(typeof(CreateModuleManager), "ERROR ON: ContentService_Saved - " + node.ContentType.Alias + " ~ " + err.Message + "[" + line + "]:" + st);
            }
          }
        }
    
        private static void MakeModuleManager(IContent node)
        {
          if (
              node.ContentType.Alias.InvariantEquals("NG_USK__AutoRedirect") ||
              node.ContentType.Alias.InvariantEquals("NG_USK_LandingPage")
          )
          {
            return;
          }
          var nodeName = node.Name;
          var moduleManagerName = nodeName + " Modules";
          var cs = ApplicationContext.Current.Services.ContentService;
          var moduleManagerNode = cs.CreateContent(moduleManagerName, node.Id, "NG_USK__ModuleManager");
          //Set this value for logging:
          var hider = string.Empty;
          //Make sure the element has the NaviHide property available
          if (moduleManagerNode.HasProperty("umbracoNaviHide"))
          {
            //tell it to have the NaviHide Property set to true:
            moduleManagerNode.SetValue("umbracoNaviHide", true);
            //Get this value again for logging:
            hider = moduleManagerNode.GetValue<string>("umbracoNaviHide") == "0" ? "hide" : "show";
          }
    
          //Log this to the TraceLog
          LogHelper.Info(typeof(CreateModuleManager), "DETAILS ON: " + moduleManagerNode.Name + " is now the " + moduleManagerNode.SortOrder + " child of " + moduleManagerNode.Parent().Name + " and set to " + hider);
    
          //save and publish
          cs.SaveAndPublishWithStatus(moduleManagerNode);
    
          if (moduleManagerNode.HasIdentity)
          {
    
            // get the sibling nodes but not the one that has just been saved, into a list
            var siblingContentItems = moduleManagerNode.Parent().Children().Where(f => f.Id != moduleManagerNode.Id).ToList();
            // add the one being saved to the start of the list
            siblingContentItems.Insert(0, moduleManagerNode);
            // call contentService Sort method on the list...
            cs.Sort(siblingContentItems);
          }
    
        }
    
    
      }
    }
    
  • Marc Goodson 2140 posts 14323 karma points MVP 8x c-trib
    Jan 24, 2016 @ 10:17
    Marc Goodson
    100

    Hi Jon

    are you able to set a break point and step through this code ? a) to see if somehow it is firing twice or b) to determine the step in the logic which is creating the additional module

    That said, could you not in your MakeModuleNode method, first check to see if there already exists a node of your ModuleManager type before creating it ??

    If an editor changes the name of a page in your site, ie to correct a typo or because they do that sometimes, wouldn't that create further Module Manager folders ?

    If there is only one folder for modules underneath each node, couldn't they all just be called modules ?

    eg

    /Text Page/Modules & /Text Page/hidden page test/Modules

    Also I'm slightly intrigued as to what the Modules are for each page; have you looked at packages such as 'nested content' ? https://our.umbraco.org/projects/backoffice-extensions/nested-content/

  • Jon R. Humphrey 164 posts 455 karma points c-trib
    Jan 24, 2016 @ 14:30
    Jon R. Humphrey
    0

    Marc,

    Thank you so much for this, it's put me that much closer to completion!

    You're thought about checking for children in the MakeModuleManager method was the ticket!!!

    Revised code below:

    using System;using System.Diagnostics;
    using System.Linq;
    using Umbraco.Core;
    using Umbraco.Core.Events;
    using Umbraco.Core.Logging;
    using Umbraco.Core.Models;
    using Umbraco.Core.Services;
    
    namespace NG.USK.Helpers
    {
      /// <summary>
      /// Check for a child page element for each of the main parent document types to enable the usage of the individual functionality module plugins
      /// </summary>
      public class CreateModuleManager : ApplicationEventHandler
      {
        public CreateModuleManager()
        {
          ContentService.Saved += ContentService_Saved;
        }
    
        private static void ContentService_Saved(IContentService sender, SaveEventArgs<IContent> args)
        {
          foreach (
            var node in
              args.SavedEntities.Where(
                node =>
                  node.ContentType.Alias.InvariantEquals("NG_USK_Homepage") ||
                  node.ContentType.Alias.InvariantEquals("NG_USK_StandardPage") ||
                  node.ContentType.Alias.InvariantEquals("NG_USK_StandardPageChild") ||
                  node.ContentType.Alias.InvariantEquals("NG_USK_NewsArticle") ||
                  node.ContentType.Alias.InvariantEquals("NG_USK_Downloads")
                )
            )
          {
            try
            {
              if (!node.Children().Any())
              {
                MakeModuleManager(node);
              }
              else
              {
                var ignore = false;
                foreach (var child in node.Children())
                {
                  if (child.ContentType.Alias.InvariantEquals("NG_USK__ModuleManager"))
                  {
                    ignore = true;
                  }
                  if (ignore == false)
                  {
                    MakeModuleManager(node);
                    break;
                  }
                }
              }
    
            }
            catch (Exception err)
            {
              // Get stack trace for the exception with source file information
              var st = new StackTrace(err, true);
              // Get the top stack frame
              var frame = st.GetFrame(0);
              // Get the line number from the stack frame
              var line = frame.GetFileLineNumber();
              LogHelper.Warn(typeof (CreateModuleManager),
                "ERROR ON: ContentService_Saved - " + node.ContentType.Alias + " ~ " + err.Message + "[" + line + "]:" + st);
            }
          }
        }
    
        private static void MakeModuleManager(IContent node)
        {
          try
          {
            if (
              node.ContentType.Alias.InvariantEquals("NG_USK__AutoRedirect") ||
              node.ContentType.Alias.InvariantEquals("NG_USK_LandingPage") || 
              node.Children().Any(x => x.ContentType.Alias.InvariantEquals("NG_USK_ModuleManager"))
              )
            {
              return;
            }
            var nodeName = node.Name;
            var moduleManagerName = nodeName + " Modules";
            var cs = ApplicationContext.Current.Services.ContentService;
            var moduleManagerNode = cs.CreateContent(moduleManagerName, node.Id, "NG_USK__ModuleManager");
            //Set this value for logging:
            var hider = string.Empty;
            //Make sure the element has the NaviHide property available
            if (moduleManagerNode.HasProperty("umbracoNaviHide"))
            {
              //tell it to have the NaviHide Property set to true:
              moduleManagerNode.SetValue("umbracoNaviHide", true);
              //Get this value again for logging:
              hider = moduleManagerNode.GetValue<string>("umbracoNaviHide") == "0" ? "hide" : "show";
            }
    
            //Log this to the TraceLog
            LogHelper.Info(typeof (CreateModuleManager),
              "DETAILS ON: " + moduleManagerNode.Name + " is now the " + moduleManagerNode.SortOrder + " child of " +
              moduleManagerNode.Parent().Name + " and set to " + hider);
    
            //save and publish
            cs.SaveAndPublishWithStatus(moduleManagerNode);
    
            if (moduleManagerNode.HasIdentity)
            {
    
              // get the sibling nodes but not the one that has just been saved, into a list
              var siblingContentItems = moduleManagerNode.Parent().Children().Where(f => f.Id != moduleManagerNode.Id).ToList();
              // add the one being saved to the start of the list
              siblingContentItems.Insert(0, moduleManagerNode);
              // call contentService Sort method on the list...
              cs.Sort(siblingContentItems);
            }
          }
          catch (Exception doh)
          {
            // Get stack trace for the exception with source file information
            var st = new StackTrace(doh, true);
            // Get the top stack frame
            var frame = st.GetFrame(0);
            // Get the line number from the stack frame
            var line = frame.GetFileLineNumber();
            LogHelper.Warn(typeof (CreateModuleManager),
              "ERROR ON: MakeModuleManager - " + node.ContentType.Alias + " ~ " + doh.Message + "[" + line + "]:" + st);
          }
        }
      }
    }
    

    Final screenshot:

    enter image description here

    #h5yr!

  • Paul Bowen 11 posts 76 karma points
    Apr 29, 2016 @ 00:33
    Paul Bowen
    4

    I've just come across this post. If all you're looking to do is add new nodes to the top of the list of siblings in Umbraco 7 then you can use the following code. It actually has an extra feature where it checks for an "Add to Top" property on the parent so it's flexible but you can remove that part of the code if you don't need it.

    Call it with something like ContentService.Saved += OnSaved; of course.

            /// <summary>
        ///  On save, if there is one item to save, if the item is new (uses IsNewEntity) and the page has the "addToTop" property set, add the item to the top.
        ///  The sort order is set to one less than the current top child in the list to ensure the content appears at the top of its node tree.
        /// </summary>
        private void OnSaved(IContentService sender, SaveEventArgs<IContent> args)
        {
            if (args.SavedEntities.Count() == 1)
            {
                var content = args.SavedEntities.First();
    
                var isNew = content.IsNewEntity();
                if (isNew)
                {
                    var parent = content.Parent();
                    if (parent != null && parent.HasProperty("addToTop") && parent.GetValue<bool>("addToTop"))
                    {
                        var sortOrder = sender.GetChildren(parent.Id).Min(o => o.SortOrder);
                        content.SortOrder = sortOrder - 1;
                        if (content.Published)
                            sender.SaveAndPublishWithStatus(content);
                        else
                            sender.Save(content);
                    }
                }
            }
        }
    
Please Sign in or register to post replies

Write your reply to:

Draft