Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

my current customer is rolling out SharePoint 2010 (yeah yeah, I know) and wants to know about MySite.

They want to customize the MySite experience and are wondering if enabling the features now will mess up the customizations in the future. I told them that sites which are created at this time, based upon the OOTB MySite template, will need some work because altering the template won't adapt existing sites.

But I did this before for regular sites, and usually it's not that big of a deal if you just create some features which are activated by script for existing sites; and stapled for new ones.

But I might be wrong here, or missing something. There seem to be some blogs which state that you should first customize and then roll-out, but those seem to be based on 2007. So I'd like to ask for field experience with this and things to look out for. Thanks.

share|improve this question
    
Are you refering to the "My Content"-section (personal site) or "My Profile"-section of My Site? –  Jan Maximilian W. Kristiansen Jan 28 '13 at 9:47
    
Both, basically. The customer has ideas similar to MySite in SharePoint 2013. It should be a start site with content rolled up (like tasks). I guess the my content section probably is best for this, but a new section might be cool to. Depends on the possibilities –  Jasper Jan 28 '13 at 13:57

1 Answer 1

up vote 1 down vote accepted
+100

I have done customizations to mysites. The biggest issue was applying those same customizations to every historical MySite. The solution I came up with was to use delegate controls to inject my customizations. These are applied dynamically at any scope. I wanted to minimize the number of times I had to iterate through our 15000 sites, so my only iteration through was to remove all old customizations then I added 2 new delegate controls to the master page and used features to enable/disable the injection of my customizations into the sites.

Because you are knowingly deploying customizations into SP2010 and because 2013 does a lot of work to MySites I would recommend saving yourself endless heartache by using delegate controls exclusively for your customizations.

There are many great writeups for using delegate controls, however, it took me a long time to tie the scalability of delegate controls to the business need of customizations and the maintenance nightmare of the MySites site collections, so perhaps pointing you in this direction will be the answer you are looking for.

UPDATE

Delegate controls can add css file to the additional page head.

Elements.xml:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Control
    Id="AdditionalPageHead"
    Sequence="1000"
    ControlSrc="~/_controltemplates/MySites.Branding/MySitesCss.ascx">
  </Control>
</Elements>

MySitesCss.ascx:

<!-- Header omitted for brevity/clarity -->


 <!-- Add custom css registration -->
<SharePoint:CssRegistration ID="CssRegistration1" Name="/_layouts/1033/styles/MySites.css" runat="server" After="minimalv4.css" />

Delegate controls can add js files to the additional page head.

Elements.xml:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Control
    Id="AdditionalPageHead"
    Sequence="1000"
    ControlSrc="~/_controltemplates/MySites.Branding/HelpLink.ascx">
  </Control>
</Elements>

HelpLink.ascx:

<!-- Start add links to script for help URL -->
<input id="helpURL" type="hidden" runat="server" value="" />
<script src="/_layouts/MySites.Branding/HelpLink.js" type="text/javascript" ></script>
<!-- End add links to scripts for help URL -->

I also updated the Master Page to have another delegate control and injected a picture:

<SharePoint:DelegateControl runat="server" ControlId="BigPictureHeader" AllowMultipleControls="true"/>

Elements.xml:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Control
  Id="BigPictureHeader"
  Sequence="1000"
  ControlSrc="~/_ControlTemplates/MySites.Branding/BigPictureHeader.ascx">
  </Control>
</Elements>

BigPictureHeader.ascx:

<asp:Panel ID="pnlBigPictureHeader" runat="server" CssClass="s4-notdlg" >
        <!-- Start add for header row  -->
            <div class="s4-title s4-lp">
                <div class="s4-title-inner">
                    <table class="s4-titletable" cellspacing="0">
                        <tbody>
                            <tr> 
                                <td class="s4-titlelogo">
                                    <SharePoint:SPLinkButton runat="server" NavigateUrl="~site/" ID="onetidProjectPropertyTitleGraphic">
                                        <SharePoint:SiteLogoImage name="onetidHeadbnnr0" ID="onetidHeadbnnr2" LogoImageUrl="/_layouts/images/siteIcon.png"
                                            runat="server" />
                                    </SharePoint:SPLinkButton>
                                </td>
                                <td class="s4-titletext">
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        <!-- End add for header row  -->
</asp:Panel>

I also ran into a need to add content to a web part once the page was created. I used a web-scoped delegate control in a stapler that would run once. This control was strictly code behind but on page load it would check if it was the default.aspx page in the root web and if it was it would add specific content to the web part and (this was the fun part) deactivate the feature that made it run. Because of this, the content add process ran before the first viewing of the page and then never again unless that web-scoped feature was reactivated.

protected void Page_Load(object sender, EventArgs e)
    {
        using (new SPMonitoredScope("MySites.Branding WebPartInjector Page_Load"))
        {
            SPWeb curWeb = SPContext.Current.Web;

            try
            {
                curWeb.AllowUnsafeUpdates = true;

                if (curWeb.IsRootWeb & curWeb.ServerRelativeUrl.ToString() != "/")
                {
                    SPFile thePage = curWeb.GetFile(curWeb.Url + "/default.aspx");
                    SPLimitedWebPartManager theMan = thePage.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);

                    foreach (WebPart WP in theMan.WebParts)
                    {
                        if (WP.ZoneID == "MiddleRightZone")
                        {
                            if (WP.GetType().ToString().Contains("ContentEditorWebPart"))
                            {
                                ContentEditorWebPart CEWP = new ContentEditorWebPart();
                                CEWP = (ContentEditorWebPart)WP;
                                if (CEWP.Content.InnerText.Contains("Blogs are a quick") || CEWP.Content.InnerText.Contains("BlogGuidance"))
                                {
                                    theMan.DeleteWebPart(CEWP);
                                }
                            }
                        }
                    }

                    curWeb.AllowUnsafeUpdates = true;

                    string message = string.Empty;
                    message = "<span id='BlogGuidance'></span>";
                    message += "<script type='text/javascript' src='/Style%20Library/BlogGuidance.js'></script>";

                    using (ContentEditorWebPart wpCE = new ContentEditorWebPart())
                    {
                        wpCE.Content.InnerText = message;
                        wpCE.Title = " ";
                        wpCE.ZoneID = "MiddleRightZone";
                        wpCE.ID = " ";
                        wpCE.ChromeState = System.Web.UI.WebControls.WebParts.PartChromeState.Normal;
                        wpCE.ChromeType = System.Web.UI.WebControls.WebParts.PartChromeType.TitleAndBorder;
                        wpCE.AllowHide = false;
                        wpCE.AllowClose = false;
                        wpCE.AllowMinimize = false;

                        //Add content to CEWP
                        XmlDocument xmlDoc = new XmlDocument();
                        XmlElement xmlElement = xmlDoc.CreateElement("Root");
                        xmlElement.InnerText = message;
                        wpCE.Content = xmlElement;
                        wpCE.Content.InnerText = xmlElement.InnerText;

                        //Add it to the zone
                        theMan.AddWebPart(wpCE, wpCE.ZoneID, 0);
                    }
                }
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    try
                    {
                        curWeb.Features.Remove(new Guid("723cdde5-d7b6-492d-8943-06a2142a230f"));
                    }
                    catch
                    {
                        //swallowing deactivation of self error 
                    }

                });
                curWeb.AllowUnsafeUpdates = false;
                Context.Response.Redirect(curWeb.Url);
            }
            catch (Exception g)
            {

                Logger.LogError(g, "WebPartInjector"); ;
            }
        }
    }

This process left me with 2 single line edits to the master page (I have a proof of concept that adds those dynamically as well leaving me with OOTB master pages)

I was able to accomplish all my goals using delegate controls.

  • Inject styles
  • Inject scripts
  • Inject full controls
  • Inject content

I have seen some people express concern about performance using this method, but on our farm the performance has not been an issue.

share|improve this answer
    
nice answer ghangas, hope you'll get the bounty, well deserved :) –  Francois Verbeeck Jan 29 '13 at 20:39
    
That was exactly what I was looking for, good research which proves it's possible to adapt the MySites after they've been created. It might not be as easy as for to-be-created sites, but you will always need updates anyway. Thanks Ghangas, bounty is yours :) –  Jasper Jan 30 '13 at 8:27

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.