After digging around some SugarCRM code, I ran across an interesting jQuery plugin in /includes/javascript/jquery/jquery.SugarMenu.js. After exploring where this plugin is used throughout the codebase, I learned that it actually powers all of those cool buttons you see on all of the views throughout SugarCRM: above and below list views, above detail views, in every subpanel, etc. Another interesting thing in the plugin is that it is well-documented, thanks to John Barlow and Justin Park at SugarCRM whenever they wrote the plugin! Because of this, I was able to easily see the handy addItem() method that comes with the plugin.

So... on to the good stuff: the easiest way to add items to buttons throughout SugarCRM. You simply use jQuery to select the parent <ul> and tell the plugin to add an item:

The great thing about this and the modularization of SugarCRM is that the underlying markup for the standard views is pretty much the same for all modules: a subpanel is subpanel, a list view is a list view, etc. Because of this, we can reliably use jQuery selectors to select and modify any button that uses this plugin. In all of the base view tpls (such as /includes/ListView/ListViewGeneric.tpl) you'll see that for every page in SugarCRM any unordered list elements with the class clickMenu will be transformed to a sugarActionMenu via this plugin.

For all of the most common action menus throughout SugarCRM, I've created a file of example javascript that it will take to add a menu item:

Now that we have the required javascript needed to add items to the various buttons, we need a reliable way to add the javascript into the pages we have menu buttons we want to modify. The best way I've found to do this is by using the after_ui_frame logic hook. To do that, we simply add an entry to a specific module's or global logic hook. I use the Accounts module for the following examples.

Now we need to create the php script that executes for when this logic hook is triggered. I've called the class AccountButtons and the method add(). The after_ui_frame logic hook will fire for all views for the module you're using, so you need to be sure to only add your relevant javascript to the views that you want. In the code below, I add several buttons to the detail view and list view. To get the javascript to execute in the specific views, you simply need to echo the javascript code.

And that's it!

If you're wanting to dig deeper into the code, you may find it easier to digest on Github