Friday, 22 May 2015

SharePoint 2010/2013: Updating Master Pages and Page layouts

Recently I have a task to replace masterpage manually(Programmatically). I tried to do it creating a module and putting masterpage inside it. But IgnoreIfAlreadyExists attribute within Module element can be tricky because sometimes it doesn’t work properly to update the MasterPages and PageLayouts.

Here is my solution for the update masterpage and Page layouts:

Feature Activation Code sample:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            if (properties != null)
            {
                using (SPSite currentSite = (SPSite)properties.Feature.Parent)
                {
                    using (var web = currentSite.OpenWeb())
                    {
                        var ElementDefinitions = properties.Definition.GetElementDefinitions(CultureInfo.CurrentCulture);

                        foreach (SPElementDefinition ElementDefinition in ElementDefinitions)
                        {
                            if (ElementDefinition.ElementType == "Module")
                            {
                                Helper.UpdateFilesInModule(ElementDefinition, web);

                            }
                        }
                    }
                }
            }

        }

You need to add a new class in your solution named "Helper" and add below code in it.

Namespaces:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;
using System.Xml.Linq;
using System.IO;
using Microsoft.SharePoint;
using System.Xml;

using System.Collections;

Class Code:

internal static class Helper
    {
        internal static void UpdateFilesInModule(SPElementDefinition elementDefinition, SPWeb web)
        {
            XElement xml = elementDefinition.XmlDefinition.ToXElement();
            XNamespace xmlns = "http://schemas.microsoft.com/sharepoint/";
            string featureDir = elementDefinition.FeatureDefinition.RootDirectory;
            Module module = (from m in xml.DescendantsAndSelf()
                             select new Module
                             {
                                 ProvisioningUrl = m.Attribute("Url").Value,
                                 //PhysicalPath = Path.Combine(featureDir, m.Attribute("Path").Value),
                                 Files = (from f in m.Elements(xmlns.GetName("File"))
                                          select new Module.File
                                          {
                                              Name = f.Attribute("Url").Value,
                                              PhysicalPath = Path.Combine(featureDir, f.Attribute("Path").Value),
                                              Properties = (from p in f.Elements(xmlns.GetName("Property"))
                                                            select p).ToDictionary(
                                                              n => n.Attribute("Name").Value,
                                                              v => v.Attribute("Value").Value)
                                          }).ToArray()
                             }).First();

            if (module == null)
            {
                return;
            }

            foreach (Module.File file in module.Files)
            {
                string physicalPath = file.PhysicalPath;
                string virtualPath = string.Concat(web.Url, "/", module.ProvisioningUrl, "/", file.Name);

                if (File.Exists(physicalPath))
                {
                    using (StreamReader sreader = new StreamReader(physicalPath))
                    {
                        if (!CheckOutStatus(web.GetFile(virtualPath)))
                        {
                            web.GetFile(virtualPath).CheckOut();
                        }
                        SPFile spFile = web.Files.Add(virtualPath, sreader.BaseStream, new Hashtable(file.Properties), true);
                        spFile.CheckIn("Updated", SPCheckinType.MajorCheckIn);
                        if (CheckContentApproval(spFile.Item))
                        {
                            spFile.Approve("Updated");
                        }

                        spFile.Update();
                    }
                }
            }

        }

        private static bool CheckOutStatus(SPFile file)
        {
            if (file.CheckOutStatus != SPFile.SPCheckOutStatus.None)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private static bool CheckContentApproval(SPListItem listitem)
        {
            bool isContentApprovalEnabled = listitem.ParentList.EnableModeration;

            return isContentApprovalEnabled;
        }

        public static XElement ToXElement(this XmlNode node)
        {
            XDocument xDoc = new XDocument();

            using (XmlWriter xmlWriter = xDoc.CreateWriter())

                node.WriteTo(xmlWriter);

            return xDoc.Root;

        }
    }

    public class Module
    {
        public string ProvisioningUrl { get; set; }
        //public string PhysicalPath { get; set; }
        public Module.File[] Files { get; set; }

        public class File
        {
            public string Name { get; set; }
            public string PhysicalPath { get; set; }
            public Dictionary<string, string> Properties { get; set; }
        }

    }

Reference: http://falakmahmood.blogspot.in/2011/09/sharepoint-2010-updating-masterpages.html

You can now check useful post links on "useful links" Right hand side top.



No comments:

Post a Comment