Friday, October 21, 2011

New CRM 2011 Ribbon Editing Tool

Phew! So it's Friday night and for the past week I've been between jobs (i.e, unemployed), so I've finally had the time to create a tool that I've been wanting to build for a while.  So here is a new tool for customizing ribbons on Microsoft Dynamics CRM 2011. 

It's different from other ribbon editors available because it shows a full real-time preview of what the ribbon will look like in CRM, and it should eliminate the need to spend hours studying the ribbon XML schema in the CRM SDK before trying to add a new button to a ribbon. No more scrolling through pages of XML looking for the ID of the element you want to insert your button into. Just click "New Button", position it where you want, then define the actions and enable rules or display rules. Then click "Save" to save the changes back to CRM.



I'll post more about this project later, but for now you can find it at http://crmvisualribbonedit.codeplex.com/
It's currently in a beta state and still need alot of testing, but please check it out!

-Erik Pool

Friday, October 14, 2011

Understanding CRM Ribbon XML - Part 3: Group Templates

This is part 3 in a series of posts on customizing CRM ribbons:
- Part 3: Understanding Group Templates (this post)

How do Templates work?

Until now I’ve completely skipped over the templates section of the ribbon xml. This is because Templates can be the most difficult part of ribbon customizations to understand. Templates are used to determine how groups of controls on a ribbon are arranged. The template used will determine the order of the buttons, as well as the size of the buttons. And the template will also determine how the group shrinks when there isn’t enough room on the page for the full ribbon.

For most scenarios (such as adding a button to an existing group) you won’t even need to worry about templates, you can just add the button set it's TemplateAlias attribute to “isv” and you’re done. However, if you are creating a new Group (or a new tab), then it’s worth knowing how Templates work.
First, take a look at the buttons in the UI section. Notice how they each have a TemplateAlias attribute:


Also notice how each Group has a Template Attribute:


If we scroll down to the Templates section, we will find the Template that the group is using. Each Template will have multiple Layouts inside it with names like “LargeMedium”, or “LargeSmall”. One of these Layouts will be used to determine the arrangement of the controls inside the Group (we’ll see how CRM actually decides which layout to use in a bit).



Inside of each layout, there are two ways that the arrangement of buttons and controls can be defined...

1. Layout using OverflowSections


The most common way is using OverflowSections. Each OverflowSection will be arranged in the ribbon group horizontally from left to right, and will contain all the buttons from the group that have the specified TemplateAlias.  This image shows the "Collaborate" group, which is using the "LargeMedium" layout of the "Flexible2" template:



In the image above, all of the buttons using the "o1" templateAlias are placed before all of the buttons with the "o2" TemplateAlias, regardless of their sequence number.  But controls with the same TemplateAlias will be ordered inside the OverflowSection based on their sequence number. In this example there are no buttons currently using the “isv” TemplateAlias, so the isv OverflowSection is not shown at all.
An overflowSection with a Type of “OneRow” will have just a single row of buttons, while a Type of “ThreeRow” will have three rows of buttons stacked on top of eachother.  The DisplayMode determines what size the buttons in the OverflowSection will be. There are three sizes - Large, Medium, and Small:


Notice that all of the default templates each have an OverflowSection for the “isv” templateAlias. This is so developers can easily just add a new button to any group without having to worry about templates or layouts. If you just always use the “isv” TemplateAlias then the button will show up at the end of the group.

2. Layout using Sections and Rows

The other way that Layouts can be defined is using Sections and Rows. Sections and Rows allow the template to have much more precision than OverflowSections when defining the arrangement of controls. Each control in the Group is placed into a specific Section and Row. For example, the Activities group on the “Add Existing” tab uses Sections and Rows to get a very specific arrangement of controls:


Notice that even with the sections and rows in this Layout there are still two OverflowSections at the end of the layout for the "o1" and "isv" TemplateAliases. The Sections and Rows offer more exact control over layout but the OverflowSections off flexibility if you need to add additional custom controls to this group.

Tip: Any time you see a control with a TemplateAlias that starts with “c”, it is using Sections and Rows for layout. Any time the TemplateAlias starts with “o”, it is using OverflowSections (c = ConfrolRef, o = overflowSection).


How does CRM decide which layout to use?

Each template has multiple layouts, and each of these layouts defines how the ribbon group will look at different sizes. This is where the Scaling section comes into play. If you look at the scaling section of a Tab (way back up in the UI section of the xml file), you will see that it maps Groups to Layouts:


The MaxSize element defines which layout the group will use when the ribbon is at its full size. If the user shrinks the window size (reducing the amount of horizontal space available for the ribbon), then it will switch to the next Scale listed.

For each Tab, all of the MaxSize and Scale elements for every groups in a tab are all collected together in one single Scaling element, but if we look at only the Scales for the “Collaborate” group (ignoring all the scales for the other groups), we can see how scales change the layout of the group as horizontal size of the ribbon is decreased:


When the Ribbon is full-width, it uses the first MaxSize scale, which points to the “LargeMedium” layout. As the available width shrinks, it moves to the next Scale in the list, which uses the “LargeSmall” layout. Finally, as the width of the ribbon shrinks further, it reaches the 3rd and final Scale, which uses the “Popup” layout. If you open CRM and navigate to Accounts, you can see how the size of the “collaborate” group changes as you adjust the size of the browser window.

The last Layout in a template is usually a special “Popup” layout. The Popup layout tells CRM which layout to use when the group is shrunk down to its smallest size and becomes a popup menu. The LayoutTitle attribute in the element refers to another layout that is used to arrange the content of the popup (in this case, the popup uses the LargeMedium layout).

How to use this information?

So how do we use this information about templates and scales? Well, if you just need to add a button to an existing group it doesn’t really matter. You can just set button’s TemplateAlias to “isv” and you’re done. However, if you are creating a completely new group for the ribbon then you will need to pick a Template and define the MaxSize and Scaling elements for the group. And if none of the default Templates will work for you, then you can even define your own template in the RibbonDiffXml.


To create a new Group, you will need to do the following:
  1. Add a new Group element to the Tab’s “Groups” collection using a CustomAction.
  2. Add a new MaxSize element into the Tab’s “Scaling” collection using a CustomAction.
  3. Optionally, add additional scales to the scaling collection (it is a good idea to at least add a “Popup” scale).
  4. If you want to specify EnableRules or DisplayRules for the Group, then you will need to create a CommandDefinition for the group, otherwise you can just set the group’s command attribute to “Mscrm.Enabled” (this will make the group always enabled).
  5. Add a new LocLabel to the LocLabels section for the groups Title attribute.
  6. If you defined a Popup scale for the group, then the group should have the Image32by32Popup attribute defined (this is the image shown when the group turns into a popup button at the smallest scale).

In Conclusion...

  1. The arrangement of controls in a ribbon Group is defined by which Template the group is using, and by which TemplateAlias the controls are using.
  2. Template layouts can be defined using either OverflowSections or Sections and Rows.
  3. The layout that CRM uses for a group depends on the MaxSize and Scaling elements defined in the Tab, and also the size of the browser window.
  4. When adding a button to an existing group, you should just use the “isv” TemplateAlias, but when creating new groups you will need to select a Template and define the group’s scaling.
By the way, these posts are meant to supplement the SDK, not replace it, but if there's any part of these posts that you found difficult or confusing please let me know in the comments)

thanks,
~Erik Pool

Wednesday, October 5, 2011

Understanding CRM Ribbon XML - Part 2: updating the ribbon

This is part 2 in a series of posts about the CRM 2011 Ribbon:

How to edit a ribbon

You edit a ribbon by updating the RibbonDiffXml section of the Customizations.xml file. This file is part of the CRM solution zip file that is exported from CRM. Basically, you must create a new solution in CRM that contains the entity who’s ribbon you want to edit. Then you must export the solution and extract the customizations xml file from the exported zip file. See this page for more information on how to export and import ribbons.

Now remember, the CRM solution only contains the changes to the ribbon, so when you view the RibbonDiffXml for a solution exported from CRM, you will not see the full definition of the ribbon. In fact, if no changes to the ribbon have been made yet, it will be almost empty:


One thing that is important to realize is that the different sections of the ribbon are edited differently. To add a new CommandDefinition, EnableRule, or DisplayRule, you can simply insert the new item into the appropriate section inside the RibbonDiffXml:



CustomActions

However, to change anything in the UI section, you need to create CustomActions. Each CustomAction tells CRM to make a change to the UI section of the ribbon. A customAction could tell CRM to insert a new button into the ribbon UI. Or a CustomAction could tell CRM to remove an existing button from the UI. Essentially, each CustomAction either defines a block of XML that should be inserted into the UI section of the ribbon, or indicates which element of the XML should be removed from the ribbon.

Take a look at this example:


This CustomAction tells CRM to insert the XML inside the CommandUIDefinition element into the XML element defined by the Location attribute (highlighted in yellow). In this case the CustomAction is inserting a new Button element into the Mscrm.HomepageGrid.account.MainTab.Collaborate.Controls element.

Notice that the Location attribute has “_children” at the end of it. This is just a convention used by CRM, it means “insert the xml content into the children of the specified element”.

This is what the base ribbon xml looks like after CRM has used the CustomAction to insert the button into the “Mscrm.HomepageGrid.account.MainTab.Collaborate.Controls” element:



Removing Existing Buttons and Controls

If you want to remove an existing element from a ribbon, you can use HideCustomAction. With HideCustomAction, you just specify which element inside the ribbon UI to hide. For example, the following will hide the ExportData button on the account homepage ribbon:

<HideCustomAction Location="Mscrm.HomepageGrid.quote.MainTab.ExportData"
HideActionId="Sample.HomepageGrid.quote.MainTab.ExportData.HideAction" />

Remember, each solution only defines the actions used to change the base ribbon xml. So you could have one CRM solution that adds a ribbon button, and then another Solution layered on top of it that hides the same button.

A quick note about LocLabels

In the RibbonDiffXml from your solution, you will see a RibbonDiffXml section that doesn’t appear in the Base ribbon XML from the resources\exportedribbonxml. This is where you store the localized labels, tooltips, and descriptions for your custom ribbon buttons. Labels are defined in the LocLabels section of the RibbonDiffXml and are referenced by the controls using the “$LocLabels:” syntax:

<Button Id="Sample.account.grid.SendToOtherSystem.Button"
Command="Sample.account.grid.SendToOtherSystem.Command"
LabelText="$LocLabels:Sample.account.SendToOtherSystem.LabelText"
TemplateAlias="o1"
Image32by32="$webresource:sample_/icons/TIcon32x32.png" />

Why don’t LocLabels appear in the base ribbon xml? I suspect it’s because none of the built-in CRM buttons actually use LocLabels, instead they use their own localized resources embedded in the CRM application.


To recap:
  1. The ribbon XML definition cannot be edited directly, instead you must edit the RibbonDiffXml from the solution customizations.xml file.
  2. New CommandDefinitions, EnableRules, and DisplayRules can be added directly to the available sections in the RibbonDiffXml.
  3. New UI elements (i.e, new buttons, groups, or tabs) must be added to the ribbon using CustomActions
  4. Existing tabs, groups, and buttons can be hidden using HideCustomActions.

In the next post I will discuss how the CRM Ribbon uses Templates to determine positioning and size of ribbon controls.

Saturday, October 1, 2011

Understanding CRM Ribbon XML - Part 1: ribbon content and structure

This is part 1 in a series of posts about the CRM 2011 Ribbon:
 - Part 1 - Content and Structure of the Ribbon. (this post)

 - Part 2 - Editing the ribbon.

 - Part 3 - How Ribbon Templates work (coming soon)

Demystifying the CRM 2011 ribbon xml

The CRM 2011 SDK provides a number of walkthroughs on adding buttons and tabs to the CRM entity ribbons, but they don’t really offer an in-depth explanation of why each step is necessary, or what other options are available. In the next few posts I will attempt to explain fully how the ribbons for CRM 2011 can be customized, and explain in more detail some of the areas that the SDK only touches lightly. In this first post I will cover the basic structure and content of the ribbon XML, and in following posts we'll go over editing the ribbon and how ribbon templates work. 


Your CRM solution doesn’t contain the entire ribbon

The first thing you must know about CRM ribbons, is that a CRM solution will not contain the entire definition of a ribbon. The CRM database does contain a base ribbon definition for each entity, but this definition is not directly customizable. When you modify the ribbon, your CRM solution will only store the changes made to the ribbon. This way multiple solutions can each make changes to the same ribbon and they will all get layered on top of each other, without any solutions overwriting each other.

So when making changes to any CRM ribbon you have to keep in mind that you’re not actually editing the ribbon XML definition, you are editing an XML file (ribbondiffxml) that describes the changes made to the ribbon.

Viewing the Full Ribbon Definition

Each ribbon in CRM is defined by an xml file, and the first thing you should do when trying to understand how ribbon customization works is to look at the full ribbon xml for a CRM entity. There are two ways you can get the ribbon xml for an entity:
  1. Look in the resources\exportedribbonxml folder in the CRM SDK. This folder contains the ribbon xml for all the system entities in CRM.

  2. Or, you can export the ribbon xml for a specific entity programmatically, using the RetrieveEntityRibbonRequest message. For uncustomized system entities this will give you the same xml that is found in resources\exportedribbonxml.
Both of these methods will give you the full ribbon definition from CRM (not just the customizations you’ve added to the ribbon).


Contents of the Ribbon XML

As you look through the ribbon xml you will see four main sections: UI, Templates, CommandDefinitons, and RuleDefinitions.


  1. UI The UI section contains all the Tabs, Groups, and buttons that show up in the ribbon. This defines what you actually see in the ribbon.

  2. Templates – Templates define the layout of ribbon groups. The size of buttons and controls on a ribbon, how they are arranged, and how they collapse when the window size shrinks all depends on what templates the ribbon is using.

  3. CommandDefinitons – CommandDefinitions define what the ribbon buttons do (i.e., what actions are executed when a user clicks the button).

  4. RuleDefinitions – RuleDefinitions define when a button is displayed and when it is enabled or disabled.

UI Section

Take a look at the xml inside the UI section and you will see a hierarchy of Tabs, which contain Groups, which then contain Controls (including ribbon buttons). Each of these elements corresponds to a part of the ribbon:

For the most part, the UI section is pretty straightforward, but there are a few things worth pointing out:
  1. Notice that there are several different types of tabs: HomepageGrid, Form, and SubGrid. These tabs will be difference parts of the CRM application. Read about the different types of tabs here.

  2. Each button has a sequence number and a TemplateAlias. These are used to derermine the ordering of the buttons and the size of the button. We’ll look at how templates work in the next post.

  3. Inside each tab, in addition to a collection of Groups you will see a “Scaling” section. Ignore this section for now, we’ll get to it in a bit (essentially, it defines how the groups behave when there isn’t enough room on the screen to display the full ribbon).


Command Definitions


Look at the Buttons in the UI section:



Notice that the buttons each have a “Command” attribute. If we search the XML file for the command, we see that it’s a reference to a CommandDefinition (which is found in the commandDefinitions section, of course):


You can see that in the CommandDefinition, there is an Action, and also a number of DisplayRules and EnableRules. The Action defines what happens when the button is pressed. The Action can be either a Javascript function or a URL. In the example shown above, the action calls the “openObj” JavaScript function. See this page for more information on how to define ribbon actions.


RuleDefinitions

The EnableRules and DisplayRules in the CommandDefinition define which rules are used to determine when the button is enabled or visible. The rules you see inside the CommandDefinition are just pointers, the actual definitions of these rules are defined in the RuleDefinitions section:



There are many different kinds of rules that can be used within each EnableRule or DisplayRule, allowing you to create complex conditions for almost any kind of scenario. In the example shown above, the CreateSelectedEntityPermission rule uses an EntityPrivilegeRule to make sure that the “New Record” button is only enabled when the current user has the Create permission on the selected entity. To understand the full capability of EnableRules and DisplayRules, check out the following SDK articles: EnableRules, DisplayRules.


In Conclusion..

To recap, we have the UI section, which defines the actual visual elements that make up a ribbon. The buttons in the UI section link to a CommandDefinition, which defines what the button does. And the CommandDefinition links to multiple RuleDefinitions, which define when the button is visible or enabled. What about the Templates section? We will get to that in a future post.

In the next post, we'll see how to actually edit the ribbon.