How to Add a Tab to the Ribbon in SharePoint Foundation

(Before he left for a week of laying on various tropical beaches with drinks in his hand, Dallas asked me to post this for him. Since I'm stuck in the rainy Northwest and had nothing better to do, I was happy to oblige him.)

The ribbon has unified the command surface inside of SharePoint. It is now the primary point of entry for working with items inside of SharePoint. As such the ribbon is extensible through the use of declarative XML in a Feature.

This post will cover how to add a new tab to the ribbon in Microsoft SharePoint Foundation 2010. It will also, by necessity, cover how to create a group, controls, template, and scaling behavior. I will build this solution in Visual Studio 2010 Beta 2 and as a sandboxed solution for the ease of deployment.

The following will appear in a future version of the SDK. It is preliminary documentation and subject to change.

First, you will want to create a new project. Click on File, New, and then Project.

Under Visual C#, choose Empty SharePoint Project and enter AddARibbonTab for the Name. Click OK.

In the SharePoint Customization Wizard, choose Deploy as a sandboxed solution. Click Finish.

In the Solution Explorer, right click on Features and choose Add Feature.

Change the Title of the Feature to Custom Ribbon Tab. Also, rename Feature1 in the Solution Explorer to CustomRibbonTab.

Right click on the AddARibbonTab project in the Solution Explorer and choose Add, New Item…

In the Add New Item dialog, choose the Empty Element template. Enter CustomRibbonTab as the Name.

In the Elements.xml file, insert the following CustomAction element. The Location attribute tells the CustomAction where to apply the customization. The following list explains the acceptable values.

Value

Description

CommandUI.Ribbon

Customization appears everywhere for the specified RegistrationId.

CommandUI.Ribbon.ListView

Customization appears when the list view Web Part is present.

CommandUI.Ribbon.EditForm

Customization appears on the edit form.

CommandUI.Ribbon.NewForm

Customization appears on the new form.

CommandUI.Ribbon.DisplayForm

Customization appears on the display form.

 

<?xml version="1.0" encoding="utf-8"?>

<Elements xmlns="https://schemas.microsoft.com/sharepoint/">

  <CustomAction

  Id="MyCustomRibbonTab"

    Location="CommandUI.Ribbon.ListView"

    RegistrationId="101"

    RegistrationType="List">

 

  </CustomAction>

</Elements>

 

Add the following elements to define the ribbon extension and tab. The Location on the CommandUIDefinition element defines where the controls inside of it will render. In this example, you reference the Tabs collection of the ribbon. The _children convention tells the ribbon to insert the following XML, whether it is a tab, group, or control, into the collection of tabs. The Sequence attribute on the Tab element defines where the tab will render in regards to other tabs. The default tabs use multiples of 100, so the Sequence attribute should not be a multiple of 100 to prevent collisions.

<CommandUIExtension>

      <CommandUIDefinitions>

        <CommandUIDefinition

          Location="Ribbon.Tabs._children">

          <Tab

            Id="Ribbon.CustomTabExample"

            Title="My Custom Tab"

            Description="This holds my custom commands!"

            Sequence="501">

 

When creating a custom tab, you must define how the tab will scale when controls are added. This is handled through the use of the Scaling element along with a GroupTemplate. The MaxSize element defines the maximum size of the controls in the group. The Scale element defines how the group will scale in different situations. The GroupId attribute associates a group with the scale size. The Size attribute is defined by the Layout element, which is defined later in this topic.

            <Scaling

              Id="Ribbon.CustomTabExample.Scaling">

              <MaxSize

                Id="Ribbon.CustomTabExample.MaxSize"

       GroupId="Ribbon.CustomTabExample.CustomGroupExample"

                Size="OneLargeTwoMedium"/>

              <Scale

                Id="Ribbon.CustomTabExample.Scaling.CustomTabScaling"

                GroupId="Ribbon.CustomTabExample.CustomGroupExample"

                Size="OneLargeTwoMedium" />

            </Scaling>

 

Now, you will define the groups of controls that will appear on the tab. The Group element contains the usual attributes along with a Template attribute. The Template attribute references the GroupTemplate that is defined later in this topic. The Controls element contains the controls that will render in the group. These can be buttons, dropdowns, and other control types. You can find a list in the SDK at this address: https://msdn.microsoft.com/en-us/library/ee537017(office.14).aspx. The controls inside the group must define the TemplateAlias and Command attributes. Like tabs, each control has a Sequence attribute that defines where they will render in the group. The default controls are based on multiples of 10, so any custom controls should not use a multiple of 10 to avoid collisions. The Command attribute is used by the CommandUIHandler defined later in this topic but is required even if the CommandUIHandler is not specified. The TemplateAlias attribute defines where the control will render in relationship to the GroupTemplate.

            <Groups Id="Ribbon.CustomTabExample.Groups">

              <Group

                Id="Ribbon.CustomTabExample.CustomGroupExample"

                Description="This is a custom group!"

                Title="Custom Group"

                Sequence="52"

            Template="Ribbon.Templates.CustomTemplateExample">

                <Controls Id="Ribbon.CustomTabExample.CustomGroupExample.Controls">

                  <Button

                    Id="Ribbon.CustomTabExample.CustomGroupExample.HelloWorld"

                    Command="CustomTabExample.HelloWorldCommand"

                    Sequence="15"

                    Description="Says Hello to the World!"

                    LabelText="Hello, World!"

                    TemplateAlias="cust1"/>

    <Button

                    Id="Ribbon.CustomTabExample.CustomGroupExample.GoodbyeWorld"

                    Command="CustomTabExample.GoodbyeWorldCommand"

                    Sequence="17"

                    Description="Says Good-bye to the World!"

                    LabelText="Good-bye, World!"

                    TemplateAlias="cust2"/>

                  <Button

                    Id="Ribbon.CustomTabExample.CustomGroupExample.LoveWorld"

                    Command="CustomTabExample.LoveWorldCommand"

                    Sequence="19"

                    Description="Says I &lt;3 the World!"

                    LabelText="I &lt;3 you, World!"

                    TemplateAlias="cust3"/>

                </Controls>

              </Group>

            </Groups>

          </Tab>

        </CommandUIDefinition>

 

With that code in place, you have finished the first CommandUIDefinition that includes the tab, groups, and controls. You need to define how the controls will render inside of the group. You do this using a GroupTemplate element in another CommandUIDefinition. The CommandUIDefinition will have a Location of Ribbon.Templates._children. This follows the pattern for Groups and Tabs.

The GroupTemplate element contains a Layout element with Section and Row elements. The Layout element has a LayoutTitle that is used for the Size attribute on the MaxSize and Scale elements. The Section elements define the position of the controls as well as how many rows will render inside that section. The Row element contains one or more ControlRef elements. ControlRef elements define how your controls will display. The DisplayMode attribute can have the following values:

Value

Description

Small

Renders as a small icon without label text.

Medium

Renders as a 16x16 icon with label text.

Large

Renders as a 32x32 icon with label text.

Text

Renders as text only.

 

The ControlRef elements also define the TemplateAlias values that you used for the TemplateAlias attribute on the buttons. Note that only one control per group can use this value. You cannot have two controls with the same TemplateAlias unless it is an OverflowArea. You can reuse the TemplateAlias across different groups though. There is also an OverflowArea element that defines how controls will render if there are too many controls in a group. The TemplateAlias attributes that refer to OverflowAreas in the GroupTemplate can be used on multiple controls.

In this example, you will define two sections for rendering the controls. One section will be a row of large buttons while the other section will contain two rows of medium-sized buttons.

        <CommandUIDefinition Location="Ribbon.Templates._children">

          <GroupTemplate Id="Ribbon.Templates.CustomTemplateExample">

            <Layout

              Title="OneLargeTwoMedium"

              LayoutTitle="OneLargeTwoMedium">

              <Section Alignment="Top" Type="OneRow">

                <Row>

                  <ControlRef DisplayMode="Large" TemplateAlias="cust1" />

                </Row>

              </Section>

              <Section Alignment="Top" Type="TwoRow">

                <Row>

                  <ControlRef DisplayMode="Medium" TemplateAlias="cust2" />

                </Row>

                <Row>

                  <ControlRef DisplayMode="Medium" TemplateAlias="cust3" />

                </Row>

              </Section>

            </Layout>

          </GroupTemplate>

        </CommandUIDefinition>

      </CommandUIDefinitions>

 

The final step is to write handlers for the buttons. These are inside CommandUIHandler elements. The Command attribute is a unique name for the command and used for the Command attribute on controls. The CommandAction attribute contains the action that is performed for the control. This can be JavaScript, an URL, or anything that was previously contained in an UrlAction element.

      <CommandUIHandlers>

        <CommandUIHandler

          Command="CustomTabExample.HelloWorldCommand"

          CommandAction="javascript:alert('Hello, world!');" />

        <CommandUIHandler

          Command="CustomTabExample.GoodbyeWorldCommand"

          CommandAction="javascript:alert('Good-bye, world!');" />

        <CommandUIHandler

          Command="CustomTabExample.LoveWorldCommand"

          CommandAction="javascript:alert('I love you, world!');" />

      </CommandUIHandlers>

    </CommandUIExtension>

 

With the addition of the CommandUIHandlers, you have finished your Elements.xml file. Press F5 to deploy your solution. Then, navigate to the Shared Documents folder. You should see the Custom Tab. Click on Custom Tab to open it. Click any of the buttons to show the associated alert.

Hopefully this walkthrough has been helpful! If you have any questions or concerns, please let me know in the comments.

 

Full Code Listing:

<?xml version="1.0" encoding="utf-8"?>

<Elements xmlns="https://schemas.microsoft.com/sharepoint/">

  <CustomAction

    Id="MyCustomRibbonTab"

    Location="CommandUI.Ribbon.ListView"

    RegistrationId="101"

    RegistrationType="List">

      <CommandUIExtension>

        <CommandUIDefinitions>

          <CommandUIDefinition

            Location="Ribbon.Tabs._children">

            <Tab

              Id="Ribbon.CustomTabExample"

              Title="My Custom Tab"

              Description="This holds my custom commands!"

              Sequence="501">

            <Scaling

              Id="Ribbon.CustomTabExample.Scaling">

            <MaxSize

                Id="Ribbon.CustomTabExample.MaxSize"

                GroupId="Ribbon.CustomTabExample.CustomGroupExample"

                Size="OneLargeTwoMedium"/>

              <Scale

                Id="Ribbon.CustomTabExample.Scaling.CustomTabScaling"

                GroupId="Ribbon.CustomTabExample.CustomGroupExample"

                Size="OneLargeTwoMedium" />

            </Scaling>

            <Groups Id="Ribbon.CustomTabExample.Groups">

            <Group

                Id="Ribbon.CustomTabExample.CustomGroupExample"

                Description="This is a custom group!"

                Title="Custom Group"

                Sequence="52"

                Template="Ribbon.Templates.CustomTemplateExample">

                <Controls Id="Ribbon.CustomTabExample.CustomGroupExample.Controls">

                  <Button

                    Id="Ribbon.CustomTabExample.CustomGroupExample.HelloWorld"

                    Command="CustomTabExample.HelloWorldCommand"

                    Sequence="15"

                    Description="Says hello to the World!"

                    LabelText="Hello, World!"

                    TemplateAlias="cust1"/>

                  <Button

                    Id="Ribbon.CustomTabExample.CustomGroupExample.GoodbyeWorld"

                    Command="CustomTabExample.GoodbyeWorldCommand"

                    Sequence="17"

                    Description="Says good-bye to the World!"

        LabelText="Good-bye, World!"

                    TemplateAlias="cust2"/>

                  <Button

                    Id="Ribbon.CustomTabExample.CustomGroupExample.LoveWorld"

                    Command="CustomTabExample.LoveWorldCommand"

                    Sequence="19"

                    Description="Says I love the World!"

                    LabelText="I love you, World!"

                    TemplateAlias="cust3"/>

                </Controls>

              </Group>

            </Groups>

          </Tab>

        </CommandUIDefinition>

        <CommandUIDefinition Location="Ribbon.Templates._children">

          <GroupTemplate Id="Ribbon.Templates.CustomTemplateExample">

            <Layout

              Title="OneLargeTwoMedium"

              LayoutTitle="OneLargeTwoMedium">

              <Section Alignment="Top" Type="OneRow">

                <Row>

                  <ControlRef DisplayMode="Large" TemplateAlias="cust1" />

                </Row>

              </Section>

              <Section Alignment="Top" Type="TwoRow">

                <Row>

                  <ControlRef DisplayMode="Medium" TemplateAlias="cust2" />

                </Row>

                <Row>

                  <ControlRef DisplayMode="Medium" TemplateAlias="cust3" />

                </Row>

              </Section>

            </Layout>

          </GroupTemplate>

        </CommandUIDefinition>

      </CommandUIDefinitions>

      <CommandUIHandlers>

        <CommandUIHandler

          Command="CustomTabExample.HelloWorldCommand"

          CommandAction="javascript:alert('Hello, world!');" />

        <CommandUIHandler

          Command="CustomTabExample.GoodbyeWorldCommand"

          CommandAction="javascript:alert('Good-bye, world!');" />

   <CommandUIHandler

          Command="CustomTabExample.LoveWorldCommand"

          CommandAction="javascript:alert('I love you, world!');" />

      </CommandUIHandlers>

    </CommandUIExtension>

  </CustomAction>

</Elements>