Thursday, July 12, 2012

Programatically Add Webpart to all Pages only once

Programatically add a webpart to all the pages in a Site collection - let's start with the reason why you might need to do this. During my portal upgrade from MOSS 2007 to SP 2010 i had an issue where all the pages in a particular site collection was showing an empty space on the left side (Figure 1).
Simple fix for this one is add a content editor webpart on the page with the following javascript:
Empty space on left side
Figure 1

 <script type="text/javascript">
document.getElementById("s4-leftpanel").style.display = 'none';
document.getElementById("MSO_ContentTable").style.marginLeft = "10px";
</script>

This solves the issue for current page, but i have the same issue for more than 100 pages. To automate this i have exported my content editor webpart(with javascript fix)  and uploaded to SiteCollection's WebParts gallery and named it "Hide Quik Launch.dwp"(it is really hiding the Out-of-box quick launch html element).
Here is the code to programatically deploy this webpart to all the pages in my sitecollection, in short it looks for all the aspx pages in each site and adds this webpart to the page only if it doesn't have it.






public class Program
    {
        static void Main(string[] args)
        {
            SPSite sc = null;
            SPWeb pc = null;
            string SPSiteUrl = ConfigurationManager.AppSettings["SPSiteUrl"];
            try
            {
                using (sc = new SPSite(SPSiteUrl))  //("http://sansp2010dev:8010/sites/information"))
                {
                    using (pc = sc.OpenWeb())
                    {              
                        AddWebPartToCurrWeb(pc, pc);   //top site
                        foreach (SPWeb currWeb in pc.Webs)
                        {
                            try
                            {     AddWebPartToCurrWeb(currWeb, pc);    // subsites                        }
                            finally
                            {
                                if (currWeb != null)
                                    currWeb.Dispose();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {                Console.WriteLine(ex.Message);            }


            Console.WriteLine("Done!");
            Console.ReadKey();
        }


 private static void AddWebPartToCurrWeb(SPWeb currWeb, SPWeb pc)
        {
            Console.WriteLine("In " + currWeb.Title + ":");
            SPList currList = currWeb.Lists["SitePages"];
            if (currList != null)
            {
                foreach (SPListItem currItem in currList.Items)
                {
                    if (currItem.Name.EndsWith("aspx"))
                    {
                        XmlReader xmlReader = GetWebPartXML(pc, "Hide Quick Launch.dwp");
                        bool currPageAlreadyHasWebpart = PageContainsHideQuickLaunch(currWeb, "/SitePages/" + currItem.Name);


                        if (xmlReader != null && !currPageAlreadyHasWebpart)
                        {
                            SPFile currPage = currWeb.GetFile(currWeb.Url + "/SitePages/" + currItem.Name);
                            if (currPage.Item == null)
                                continue;


                            using (SPLimitedWebPartManager webPartMgr = currPage.GetLimitedWebPartManager(PersonalizationScope.Shared))
                            {
                                string errorMessage;
                                System.Web.UI.WebControls.WebParts.WebPart ceWP = webPartMgr.ImportWebPart(xmlReader, out errorMessage);
                                Console.WriteLine(currPage.Name + " - Error if any: " + errorMessage);
                                webPartMgr.AddWebPart(ceWP, "LeftColumn", 1);
                                Console.WriteLine("Added Hide Quick Launch webpart to " + currPage.Name);
                            }
                        }
                    }
                }
            }
        }


private static bool PageContainsHideQuickLaunch(SPWeb currWeb, string currPageName)
        {
            bool found = false;
            SPFile currPage = currWeb.GetFile(currWeb.Url + currPageName);
            if (currPage.Item == null)
                return found;


            using (SPLimitedWebPartManager webPartMgr = currPage.GetLimitedWebPartManager(PersonalizationScope.Shared))
            {
                foreach (System.Web.UI.WebControls.WebParts.WebPart wp in webPartMgr.WebParts)
                {
                    if (wp.Title.Contains("Hide Quick Launch"))
                    {
                        found = true;
                        break;
                    }
                }
            }


            return found;
        }


private static XmlReader GetWebPartXML(SPWeb pc, string webPartName)
        {
            XmlReader xmlReader = null;
            try
            {
                SPQuery query = new SPQuery();
                query.Query = string.Format("<Where><Eq><FieldRef Name='FileLeafRef'/><Value Type='File'>{0}</Value></Eq></Where> ", webPartName);
                SPList webPartGallery = pc.GetCatalog(SPListTemplateType.WebPartCatalog);
                SPListItemCollection webParts = webPartGallery.GetItems(query);
                if (webParts != null && webParts.Count != 0)
                {
                    Stream xmlStream = webParts[0].File.OpenBinaryStream();
                    StreamReader reader = new StreamReader(xmlStream);
                    StringReader strReader = new StringReader(reader.ReadToEnd());
                    xmlReader = XmlReader.Create(strReader);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return xmlReader;
        }


Happy Coding - San
Reference:  zabistop.blogspot.com