Copied to clipboard

Flag this post as spam?

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


  • Hefin Jones 39 posts 161 karma points
    Mar 05, 2014 @ 17:57
    Hefin Jones
    0

    Custom Context Menu Items

    I'm trying to implement a custom context menu item in my Umbraco 7 site.  A brief overview of the site:

    I have a multi-lingual site, which is currently setup with two Languages - English and Welsh.  I've created an event using ContentService_Published, where if Content is created on the English site it is automatically copied across to the Welsh site on publish.  This works perfectly well.  So what I'm trying to implement now is a context menu item on each node "Go to related" which when clicked will take the user to the related node.

    e.g. If I'm viewing the "Home" node on the English site, click the "Go to related" menu item - Umbraco then displays the "Home" node on the Welsh site.  

    So far I've managed to do this:

    void ContentTreeController_MenuRendering(Umbraco.Web.Trees.TreeControllerBase sender, Umbraco.Web.Trees.MenuRenderingEventArgs e)
    {
    if (sender.TreeAlias == "content")
    {
    var rs = ApplicationContext.Current.Services.RelationService;
                    if (rs.GetByParentOrChildId(Convert.ToInt16(e.NodeId)).Where(x => x.RelationType.Alias == "relateDocumentOnCopy").Any())
    {
    var relation = rs.GetByParentOrChildId(Convert.ToInt16(e.NodeId)).Where(x => x.RelationType.Alias == "relateDocumentOnCopy").FirstOrDefault();

    int relatedNodeID = (Convert.ToInt16(e.NodeId) == relation.ParentId ? relation.ChildId : relation.ParentId);
    //creates a menu action that will open /umbraco/currentSection/goToRelated.html
    var i = new Umbraco.Web.Models.Trees.MenuItem("goToRelated", "Go To Related : " + relatedNodeID.ToString());
    i.Icon = "wine-glass";
    i.SeperatorBefore = true;
    e.Menu.Items.Insert(e.Menu.Items.Count - 1, i);
    }
    }
    }

    This creates the menu item, and I get the related Page ID displayed as the title of the menu item (as a test so that I'm sure I can get the ID of the related page) ....

    • But how to I redirect to the related page after the item has been clicked?  
    • Do I need a view, as I don't really want to display anything just redirect?  
    • Can I just execute code of a controller?  
    Any help would be greatly appreciated :)

  • Brian Williams 12 posts 33 karma points
    Dec 17, 2014 @ 16:05
    Brian Williams
    0

    I know this is old, but for posterity. The MenuItem Class has methods for configuring this.

            //
        // Summary:
        //     Sets the menu item to display a dialog based on a url path in an iframe
        //
        // Parameters:
        //   url:
        //
        //   dialogTitle:
        public void LaunchDialogUrl(string url, string dialogTitle);
        //
        // Summary:
        //     Sets the menu item to display a dialog based on an angular view path
        //
        // Parameters:
        //   view:
        //
        //   dialogTitle:
        public void LaunchDialogView(string view, string dialogTitle);
        //
        // Summary:
        //     Sets the menu item to navigate to the specified angular route path
        //
        // Parameters:
        //   route:
        public void NavigateToRoute(string route);
    
  • Ryios 122 posts 263 karma points
    Jul 22, 2015 @ 20:19
    Ryios
    2

    On top of the MenuItem class... There is what I consider a better way in Umbraco 7.

    ActionMenuItem and ActionMenuItemAttribute.

    Basically, create a class for your menu item and derive from ActionMenuItem.

    In the constructor set the alias for the menu item, whether to have a separator, etc.

    Than decorate it with the ActionMenuItemAttribute class, E.g.

    [ActionMenuItem("tlckbMenuActions", "HelloWorld")]
    public class EditContentPermissionAction : ActionMenuItem
    {
        private TLCKBNodeType nodeType = TLCKBNodeType.Root;
    
        public EditContentPermissionAction(TLCKBNodeType nodeType)
        {
            this.nodeType = nodeType;
            this.Alias = "tlckb_EditNodePermissions_" + nodeType.ToString();
            this.Icon = "icon-lock";
            this.Name = "KB Permissions";
            this.SeperatorBefore = true;
        }
    }
    

    Now in your menu rendering code, you can attach that ActionMenuItem to any TreeController and or specific menu node.

    For example, here's mine,

        //Add the KB Edit Content Permission Menu Items to the Content Menu.  Only add the menu item to the content menu if the node being explored
        //is a KB Root Node, KB Category Node, or KB Article Node.
        void TreeControllerBase_MenuRendering(TreeControllerBase sender, MenuRenderingEventArgs e)
        {
            string treeAlias = sender.TreeAlias; string nodeId = e.NodeId;
            if (string.IsNullOrEmpty(treeAlias))
                treeAlias = e.QueryStrings.Get("TreeType");
            if (string.IsNullOrEmpty(treeAlias) || nodeId == "-1")
                return; 
            //get the content of the clicked on node to get it's content type
            var currentNode = ApplicationContext.Current.Services.ContentService.GetById(Convert.ToInt32(e.NodeId));
            string contentType = currentNode != null ? currentNode.ContentType.Alias : string.Empty;
            switch (treeAlias)
            {
                case "content": //the clicked on node is in the content tree, this is the section we are interested in
                    //now determine if the clicked on node is a KB node, if so, add the menu item for that node.  We have 3 different views for permissions of the different node types.
                    if (contentType == KBApplicationCore.KBRootContentType.Alias)
                        e.Menu.Items.Add(KBMenuItems.RootEditPermissionAction);
                    if (contentType == KBApplicationCore.KBCategoryContentType.Alias)
                        e.Menu.Items.Add(KBMenuItems.CategoryEditPermissionAction);
                    if (contentType == KBApplicationCore.KBArticleContentType.Alias)
                        e.Menu.Items.Add(KBMenuItems.ArticleEditPermissionAction); 
                        break;
                default:
                    break;
            }
        }
    

    That adds my Action to the menu of any node that is based on 1 of three content types and only in the content tree controller.

    So my action only shows up when users are looking at content for the Knowledge Base.

    Now, the attribute specific a service and a method name. This needs to be an angular service defined in the umbraco module. And the method name is a method on said service.

    Umbraco has one already called umbracoMenuActions. You might be able to leverage the out of the box service to do things.

    However for me, I needed a custom menu action service.

    So I create a fodler for my knowledge base in App_Plugins and gave it a sub folder called XYZPlugin (change name).

    In there I created a package manifest and added my custom javascript to it.

    {
       javascript: [
           '/App_Plugins/XYZPlugin/backoffice/js/services/menuItems.js'
       ]
    }
    

    Then you just need to define your service in menuItems.js

    angular.module("umbraco").factory('xyzMenuActions', ['$http', '$q', 'treeService', '$location', 'navigationService', 'appState', function ($http, $q, treeService, $location, navigationService, appState) {
        var factory = new function () {
            this.HelloWorld = function () {
                alert('Hello!!! From menuActions Service!');
            }
        };
        return factory;
    }]);
    

    I copied the service dependencies from umbraco's out of the box menuAction service which is located in /umbraco/js/umbraco.services.js

    All said and done, when I click on a KB specific node in the content tree and go to "Do Something Else" I see "KB Permissions" and when I click it

    "Hello!!! From menuActions Service!"

  • peter 13 posts 144 karma points
    Mar 24, 2017 @ 14:45
    peter
    0

    Sorry to open this topic up again. I was searching for the same kind of functionality and it works, however in the console i get the Error: $apply already in progress.

    Did you have this error as well and if so, how did you fix it?

    Thank you

    Btw im working on umb v7

Please Sign in or register to post replies

Write your reply to:

Draft