SP 2013: Some new DelegateControl additions to the SharePoint 2013 master pages

Author: Tobias Zimmergren
http://www.zimmergren.net | http://www.tozit.com | @zimmergren

Introduction

In this post we’ll take a quick look at some of the new DelegateControls I’ve discovered for SharePoint 2013 and how you can replace or add information to your new master pages using these new controls, without modifying the master pages. This is done exactly the same way as you would do it back in the 2010 projects (and 2007), the only addition in this case are a few new controls that we’ll investigate.

New DelegateControls

Searching through the main master page, Seattle.master, I’ve found these three new DelegateControls:

  • PromotedActions
  • SuiteBarBrandingDelegate
  • SuiteLinksDelegate

So let’s take a look at where these controls are placed on the Master page and how we can replace them.

PromotedActions Delegate Control

The PromotedActions delegate control allows you to add your own content to the following area on a SharePoint site in the top-right section of the page:

image

An example of adding an additional link may look like this:

image

So what does the files look like for these parts of the project?

Elements.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    
  <!-- DelegateControl reference to the PromotedActions Delegate Control -->
  <Control ControlSrc="/_controltemplates/15/Zimmergren.DelegateControls/PromotedAction.ascx"
           Id="PromotedActions"
           Sequence="1" />
  
</Elements>

PromotedActions.aspx (User Control)

<!-- Note: I've removed the actual Facebook-logic from this snippet for easier overview of the structure. -->
<a title="Share on Facebook" class="ms-promotedActionButton" style="display: inline-block;" href="#">
    <span class="s4-clust ms-promotedActionButton-icon" style="width: 16px; height: 16px; overflow: hidden; display: inline-block; position: relative;">
        <img style="top: 0px; position: absolute;" alt="Share" src="/_layouts/15/images/Zimmergren.DelegateControls/facebookshare.png"/>
    </span>
    <span class="ms-promotedActionButton-text">Post on Facebook</span>
</a>

SuiteBarBrandingDelegate Delegate Control

This DelegateControl will allow you to override the content that is displayed in the top-left corner of every site. Normally, there’s a text reading "SharePoint" like this:

image

If we override this control we can easily replace the content here. For example, most people would probably like to add either a logo or at least make the link clickable so you can return to your Site Collection root web. Let’s take a look at what it can look like if we’ve customized it (this is also a clickable logo):

image

So what does the files look like for this project?

Elements.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    
  <!-- SuiteBarBrandingDelegate (the top-left "SharePoint" text on a page) -->
  <Control ControlSrc="/_controltemplates/15/Zimmergren.DelegateControls/SuiteBarBrandingDelegate.ascx"
           Id="SuiteBarBrandingDelegate"
           Sequence="1" />
  
</Elements>

SuiteBarBrandingDelegate.ascx (User Control)

This is the only content in my User Control markup:

<div class="ms-core-brandingText" id="BrandingTextControl" runat="server" />

SuiteBarBrandingDelegate.ascx.cx (User Control Code Behind)

protected void Page_Load(object sender, EventArgs e)
{
    BrandingTextControl.Controls.Add(new Literal
    {
        Text = string.Format("<a href='{0}'><img src='{1}' alt='{2}' /></a>", 
        SPContext.Current.Site.Url,
        "/_layouts/15/images/Zimmergren.DelegateControls/tozit36light.png",
        SPContext.Current.Site.RootWeb.Title)
    });
}

SuiteLinksDelegate Delegate Control

The SuiteLinksDelegate control will allow us to modify the default links, and to add our own links, in the "suit links" section:

image

By adding a custom link to the collection of controls, it can perhaps look like this:

image

What does the project files look like for modifying the SuiteLinksDelegate? Well, here’s an example:

Elements.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  
  <!-- DelegateControl reference to the SuiteLinksDelegate Delegate Control -->
  <Control ControlSrc="/_controltemplates/15/Zimmergren.DelegateControls/SuiteLinksDelegate.ascx"
           Id="SuiteLinksDelegate"
           Sequence="1" />
  
</Elements>

 

SuiteLinksDelegate.aspx.cs (User Control Code Behind)

public partial class SuiteLinksDelegate : MySuiteLinksUserControl
{
    protected override void Render(HtmlTextWriter writer)
    {
        writer.RenderBeginTag(HtmlTextWriterTag.Style);
        writer.Write(".ms-core-suiteLinkList {display: inline-block;}");
        writer.RenderEndTag();
        writer.AddAttribute(HtmlTextWriterAttribute.Class, "ms-core-suiteLinkList");
        writer.RenderBeginTag(HtmlTextWriterTag.Ul);
            
        // The true/false parameter means if it should be the active link or not - since I'm shooting off this to an external URL, it will never be active..
        RenderSuiteLink(writer, "http://timelog.tozit.com", "Time Report", "ReportYourTimeAwesomeness", false);

        writer.RenderEndTag();
        base.Render(writer);
    }
}

Solution overview

For reference: I’ve structured the project in a way where I’ve put all the changes into one single Elements.xml file and they’re activated through a Site Scoped feature called DelegateControls. The solution is a Farm solution and all artifacts required are deployed through this package.

image

Summary

In this post we’ve looked at how we can customize some of the areas in a SharePoint site without using master page customizations. We’ve used the good-old approach of hooking up a few Delegate Control overrides to our site collection. Given the approach of Delegate Controls, we can easily just de-activate the feature and all our changes are gone. Simple as that.

In SharePoint 2013 we can still do Delegate Control overrides just like we did back in 2007 and 2010 projects, and it’s still pretty slick. I haven’t investigated any other master pages other than the Seattle.master right now – perhaps there’s more new delegate controls somewhere else. Let’s find out..

Enjoy.

Follow me

Tobias Zimmergren

Founder / Consultant / Advisor at TOZIT AB
Tobias Zimmergren delivers high-quality articles about business and technology around the Microsoft scene.

Tobias focuses on advisory and consultancy for the Office 365 and SharePoint offerings from Microsoft.
Follow me
  • Pingback: SP 2013: Tip – Change the "SharePoint" text in the top left corner. | Tobias Zimmergren's thoughts on development

  • jignesh(sharepointempower.com)

    Great stuff !!! thanks for sharing.

    • http://www.zimmergren.net/ Tobias Zimmergren

      Thank you jignesh.

      • ApriLynn

        Beautiful! Thanks for the info and the code! You are a million hours saved!

        • http://www.zimmergren.net/ Tobias Zimmergren

          Thank you AprilLynn, that’s a lot of hours right there – glad I could help :-)

          • Bismarck

            It seems I can only scope this at the Farm level. Is it possible to scope to the Web Application or event SPSite?

          • http://www.zimmergren.net/ Tobias Zimmergren

            Hi Bismarck,

            You can scope this to Site or Web, which are the two most normal ways to scope these types features.
            Just make sure to add the artifacts to a feature that you scope to Web or Site and you’re all set.

            Cheers,
            Tobias.

  • http://www.facebook.com/fmigacz Frank Migacz

    Can I scope the solution to the SPSite and run this in a sandbox (SharePoint Online)?

    • http://twitter.com/blksthl Thomas Balkeståhl

      Hi Tobias, great post.
      I have the same q as Frank, or almost, does this work in SPO 2013? Or is there any special modification needed?

      • Ben Weeks

        Hi guys, did either of you find out if this worked as a sandboxed solution?

  • http://twitter.com/christou Christian SU

    Good post :) Notice that for SuiteBarBrandingDelegate, the HTML is a SPWebApplication property : SPContext.Current.Site.WebApplication.SuiteBarBrandingElementHtml ;-)

    I did an admin application page + custom action to edit it to confirm that

  • CBL

    For the suite delegate links, any way to have them open in a new window? There is no override for that in RenderSuiteLink..

    • http://www.zimmergren.net/ Tobias Zimmergren

      Hi CBL,

      I haven’t looked into that myself, but I’m pretty confident it’s possible to do one way or the other. Since you can set attributes on your links (like: writer.AddAttribute(HtmlTextWriterAttribute.Class, “ms-core-suiteLinkList”); for example) then perhaps you can tag it with a custom class and have some jQuery magic take care of opening that link in a new window. Shouldn’t be too hard to accomplish that.
      As for any built-in way to have them open in a new window: I don’t know. But what I posted above should be possible.
      Cheers,
      Tobias.

  • http://twitter.com/pieterodb Pieter Op De Beeck

    Hi, good article! Do you think it is possible to add a drop-down menu in

    SuiteLinksDelegate- area?

    • http://www.zimmergren.net/ Tobias Zimmergren

      Hi Pieter,
      Just like I replied to CBL here below just now, I think you can do that using jQuery quite easily. Have a link render like normal and then append some jQuery and CSS magic on top of that to make a drop down. I don’t have any code samples at hand for this right now, but it should absolutely be possible :-)
      Cheers,
      Tobias.

  • Jude

    Thanks very much, this article makes my branding work much more easier. I was using css to cover the suitebar text. but it is still there when the page is loading.

    • http://www.zimmergren.net/ Tobias Zimmergren

      Hi Jude,
      I’m glad you liked it.
      Cheers,
      Tobias.

  • http://twitter.com/ekerot Peter Ekerot

    A shame that SuiteLinksDelegate is not really extensible. This solution breaks the semantics of the outputted HTML putting two UL’s after another, instead of letting us actually add LI elements to the parent unordered list of links. (hence the style-trick with inline-block, of course). Would have been nice if the delegatecontrol had allowed multiple controls instead, or another way to inject our own links “inline”.

    • http://www.zimmergren.net/ Tobias Zimmergren

      Just saw this comment mate :-)
      jQuery can fix anything, but I agree that the servercontrols should be able to output nicer HTML for us by default.

  • http://twitter.com/wesmacdonald Wes MacDonald

    Great post!

    • http://www.zimmergren.net/ Tobias Zimmergren

      Thank you Wes, appreciated.
      Tob.

  • Mahdi Kamani

    Hi,

    I’ve just apply your method to add a custom link to suite bar links but after deploying suite bar links go hidden and I can’t bring them back to my site….Any help or idea ?

    thanks in advance.

    • http://www.zimmergren.net/ Tobias Zimmergren

      Hi Mahdi,
      That doesn’t sound very good :-)
      Can you please reproduce the steps and share the code you’ve used so I know what you’ve done?
      None of the code in my article actually removes anything – it only replaces or adds things with your own custom controls. What differs your implementation from any of the above?
      Cheers,
      Tobias.

      • Rapati

        Hi,
        Even I followed the same on this article. It was working good in the development environment, not in the production. Once I activate the feature, all of the suite bar links are gone.
        Looks like something is broken.

      • Mahdi Kamani

        Hi Tobias,

        The code that I used in my project is exactly as same as yours but the only part that I think makes difference is RenderSuiteLink function. Here is the code that I use for this function:

        protected static void RenderSuiteLink(HtmlTextWriter writer, string url, string name, string linkId)

        {

        writer.AddAttribute(HtmlTextWriterAttribute.Class, “ms-core-suiteLink”);

        writer.RenderBeginTag(HtmlTextWriterTag.Li);

        writer.AddAttribute(HtmlTextWriterAttribute.Class, “ms-core-suiteLink-a”);

        writer.AddAttribute(HtmlTextWriterAttribute.Href, url);

        writer.AddAttribute(HtmlTextWriterAttribute.Id, linkId);

        writer.RenderBeginTag(HtmlTextWriterTag.A);

        writer.AddAttribute(HtmlTextWriterAttribute.Class, “ms-verticalAlignMiddle”);

        writer.RenderBeginTag(HtmlTextWriterTag.Span);

        writer.Write(name);

        writer.RenderEndTag();

        }

        }

        Thanks in advance
        Mahdi.

  • Gurdip

    Hi Tobias, is it possible to download this solution?

    • http://www.zimmergren.net/ Tobias Zimmergren

      Hi Gurdip,

      I haven’t put it out there for download, but all the code is in the blog post here so you should be able to easily patch it together :-)

      / Tob.

  • Sind

    Great post, used it to add a photo in top left. Do you have any example on how to add the current site title in the middle of the suit bar? Meaning we could remove it from the titlerow. That would be awesome!

    • http://www.zimmergren.net/ Tobias Zimmergren

      Hi Sind,

      I had a similar request from a client recently so I might post an update about that soon. Keep an eye out the coming hours/days.

      Tob.

  • Gurdeep

    I managed to put the solution together. However, when I deploy, I don’t see any changes apart from the Sharepoint text disappearing. I don’t have the images you referenced (but I’ve left the references in), but for the del. control which adds the text hyperlink, even that does not appear? I have a farm-based feature scoped @ the site level, like you have mentioned. This doesn’t show up on the central admin (feature activated). What could be wrong?

  • Jan

    Works like a dream.. Even for a non VS dude like me :-)
    Thank you for sharing Tobias

    • http://www.zimmergren.net/ Tobias Zimmergren

      Hi Jan,
      Glad you found it useful :-)
      Cheers,
      Tob.

  • Vlad

    I have the same problem as Gurdeep (or even worse) – I cannot even make the SharePoint text disappear. The feature is activated. What am I missing? Should ascx control be registered somewhere on the master page?

    • http://www.zimmergren.net/ Tobias Zimmergren

      If you’ve done the delegatecontrol feature properly, it should execute. What happens when you debug the code in the user control, does it hit your breakpoint or can you see any content from the actual user control on your page? If not – its not loaded and you need to revise your solution.

      If you still can’t get it to work, hit up google and search for delegate control in SharePoint 2013 sample code and you’ll find plenty of samples on how to build up the artifacts in the project.

      Hope this helps.
      Tob.

  • salah eddine mekhlouf

    Hy, can you post the code source, thank’s

    • http://www.zimmergren.net/ Tobias Zimmergren

      Hi there,

      Sorry, you’ll have to do that part youself mate.

      Cheers,
      Tob.

  • Sem

    Great, it’s done, very interesting post !!

    • http://www.zimmergren.net/ Tobias Zimmergren

      Thank you Sem.

      • salah eddine mekhlouf

        Hi Tobias,
        have you used PowerPoint automation services in SP 2013 ? I have correctly configured this one on 3 different VM, but when i run the code to convert ppt file into pdf, i always get this message: the specified document could not be converted….i found nothing in logs’….it seems to be SP 2013 error….
        thank you

  • nelson

    Has anyone deployed a delegateControl as a feature to the spwebapplication? Trying to make web application feature and from msdn seems to indicate you can do it but VS fails to deploy

    • http://www.zimmergren.net/ Tobias Zimmergren

      Hi Nelson,
      Not really – these guys are deployed at the Site or Web scope, where it works wonders.

      Cheers,
      Tob.

  • Pingback: SP 2013: Tip – Change the “SharePoint” text in the top left corner. | SharePoint 2013 Development

  • Ray G

    Hello, are you able to use delegate controls with a SharePoint Online Plan?

  • Kenny Duenke

    I implemented this
    solution and ran into a problem with the SuiteLinksDelegate.aspx.cs file. The MySuiteLinksUserControl is dependent on
    the web application having a connection to a User Profile Service service
    application. This makes sense because
    the Newsfeed and Sites links are pointing to places in your MySites. If MySites are turned off for your web
    application, you’ll see no links at all.
    You won’t even see your own, Time Report in this example.

    My solution is not to inherit from MySuiteLinksUserControl, but to use UserControl
    like normal. I then do what I want in CreateChildControls() and at the end of
    your CCC method do a Controls.Add(new MySuiteLinksUserControl()).
    Unfortunately, you can’t leverage the RenderSuiteLink method any more. However, if your web application isn’t
    connected to a User Profile Service service application, the Time Report link will
    render.

  • Cryptan

    Hi Tobias,
    I am having the same problem as some others on here. When I deploy my solution I can see the feature and it is activated, but I do not see my user controls. The SharePoint text disappears, but that is it. If I deactivate the feature, the “SharePoint” text comes back.

    When I add a breakpoint to my codebehind file I get the message: Breakpoint will not currently be hit. No symbols have been loaded for this document.
    I have followed your example and about 5 other people’s examples to the letter and I still can’t get anything to work. I have even downloaded sample solutions and they don’t work either.
    Is there something that I am missing?

  • Maciej

    Hint for all with problems running this thing: double check
    path of ControlSrc in elements.xml – it must correspond to file on disk. I also
    used Sequence=”1″ but I do no think it matters.

    I just successfully run it on VS2012 Update 3 & VS2013 (both
    with Farm scope).

    I tried VS2013 with WebApplication scope and it also works
    (I just cannot deploy it with VS2013 to mysites web application – but deployed
    on other web apps it works).

    Hope this will help anyone.

    Greetings

  • JohnC

    Hi Tobias, in your post you say “SuiteLinksDelegate control will allow us to modify the default links”. I simply want to rename SkyDrive to Documents. How should I approach this? Thanks

  • GlennR

    First let me say thank you Tobias. This helped me tremendously. One of the most well written tutorials. Easy to follow and implement. I had one question, is there any way to edit the items in the dropdown above the “promoted links”. Usually it contains the user name, My Site, Log Out, etc. I would like to add a couple links if possible. Thank you again!

  • Pingback: Delegate Controls | Bitan Eyal

  • ratandeep singh

    Hi ,

    I am getting following error

    Microsoft.SharePoint.Portal.WebControls.LocStringId’ does not contain a definition for ‘MySuiteLinks_Documents’

    What can be done ?

  • rajesh babu

    how develop delegates for office 365