CMS 10.6 Adding Custom Macros


CMS 10.6 provides functionality for administrators to run custom macros directly from the CMS UI interface without direct custom hook file access. Administrators can run custom hook code on-demand with an executable macro.

Before running a custom macro from the CMS UI, add the function to CustomHooks.cs.

Important
Keep in mind custom macros have limitations. Custom macros do not have access to HTTP.Context. Also, custom macros have the same limitations as custom hooks. For example, if the custom macro has external references, those references need to be included in the external harness project references.

To add a custom macro function to CustomHooks.cs:

  1. Prepare your custom macro. Ensure the code includes the IUserWriteSession parameter and the @CustomMacro attribute.
    Important
    Ensure the name of your new custom macro does not conflict with custom macros that already exist in your CustomHooks.cs file.

    Use the following template:

    Template
    [CustomMacro("Name", "Description")]
    public void MyFunction(IUserWriteSession session) {}

    For example, see the following custom macro for running a number count from one to twenty:

    Count Custom Macro
    [CustomMacro("Count", "Count from 1 to 20")]
            public void StartCounting(IUserWriteSession session)
            {
                foreach (var x in new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 })
                {
                    session.CustomMessenger.Alert("I am Counting", new string[] { $"Item: {x}" });
                    Thread.Sleep(1000);
                }
            }
  2. Navigate to [Drive:]\[path-to-cms-site-instance]\App_Data\xml\Custom, and open CustomHooks.cs in a text editor.
  3. Copy and paste your custom macro code in CustomHooks.cs.

    For example, the custom macros reside in CustomHooks.cs similarly to the following code snippet:

    [CustomMacro("Send a Message", "Sends a simple message to the CMS")]
            public void SendMsg(IUserWriteSession session)
            {
                IEnumerable<string> messages = new string[0];
                var lastPages = session.OperatingUser.Activities.RecentPages.Reverse();
                messages = messages.Concat(lastPages.Take(5).Select(p => p.Name));
                if (lastPages.Count() > 5)
                    messages = messages.Append("...");
                session.CustomMessenger.Alert($"{session.OperatingUser.Name}'s Recent Pages", messages.ToArray());
            }
    
    [CustomMacro("Count", "Count from 1 to 20")]
            public void StartCounting(IUserWriteSession session)
            {
                foreach (var x in new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 })
                {
                    session.CustomMessenger.Alert("I am Counting", new string[] { $"Item: {x}" });
                    Thread.Sleep(1000);
                }
            }
    
    [CustomMacro("Section Controls", "Fill in all missing section controls with the same one as homepage.")]
            public void SetEmptySectionControls(IUserWriteSession session)
            {
                var site = session.Site;
                var siteRoot = site.Page("x1");
                int outVar;
                var homePage = siteRoot.Descendants(out outVar).Where(p => p.Name == "Home").FirstOrDefault();
                if (homePage != null)
                {
                    var controlComp = (homePage.Element("SectionControl") != null) ? homePage.Element("SectionControl") : homePage.Element("SiteControl");
                    if (controlComp != null && controlComp.Value != "")
                    {
                        var sitePages = homePage.Descendants(out outVar);
                        foreach (var page in sitePages)
                        {
    
                            var pageControl = (page.Element("SectionControl") != null) ? page.Element("SectionControl") : page.Element("SiteControl");
                            if (pageControl != null && pageControl.Value == "")
                            {
                                if (!page.CheckedOut)
                                {
                                    page.CheckOut(false);
                                }
                                pageControl.Value = controlComp.Value;
                                page.Save();
                            }
                        }
                    }
                }
    
            }
    
    	}
  4. Save and close CustomHooks.cs.
  5. Recycle your CMS application pool by completing the following steps:
    Important
    We strongly recommend coordinating with your organization before recycling the application pool, as the CMS instance will not be accessible while the recycle process runs. Consider completing this action during a maintenance period.
    1. Open Internet Information Services Manager (IIS), and navigate to the CMS instance application pool.
    2. Right-click the application pool, and select Recycle.

      The CMS instance application pool recycles, and your new CustomHooks.cs changes take effect.

Next Steps: Run the custom macro from the CMS interface by clicking the Execute button in Administration > Maintenance > Custom Hooks.

Note
Custom macros interact with Web API. Consider testing macros to help minimize maintenance and to help ensure the code runs as expected before fully running your custom macros.