Custom Branding Solution Pack For Sharepoint 2010


Download link

Introduction

Today, in this article I am trying to provide you the Custom Branding solution Pack. This solution pack will save time and effort while developing the custom Sharepoint with publishing sites in Sharepoint. It works great. So, we all are good to go and use this re-usable solution pack.

Description

The source code shows how to prepare a structure for Sharepoint Branding solution. This pack contains :

  • Master Page Gallery structure
  • Page Layout Gallery structure
  • Image Gallery
  • Styles Library gallery
  • Event Receiver

BrnsShare1.jpg

While developing a Sharepoint solution, it is very important to have a solution structure which is very flexible, re-usable and most importantly, it should be simple and understandable. Through this article I am trying to make this task easier for all.

Steps

As I explained, you can use the same solution for your development purpose but I would like to share the steps which will help you understand the solution structure and Code

1. Create an Empty Sharepoint project and give it a name (E.g. Ravishankar.Branding).

BrnsShare2.jpg

2. Right-Click on the solution, click on Add->New item, select Module

BrnsShare3.jpg

3. Give Name Master Page.

4. Repeat step 2 for creating Page Layout, Style library and Publishing Images. Your solution should look like:

  BrnsShare4.jpg

5. Now that the structure is ready, we can put all custom master pages, page layouts, Images and style sheet & JavaScript files in the solution structure.

6. The next thing left is to create an eventreciever. This receiver is basically very important as you are deploying and retracting solution every time and you need to set the latest whenever you are deploying the solution. To create EventReciever, right-click on Feature, Add EventReciever.

7. On the Activation, you can add the code like below to set your master on the activation:

/// <summary>
        /// Set the MainMasterPage.master as default master for site.
        /// </summary>
        /// <param name="properties"></param>
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate
            {
                using (SPSite site = properties.Feature.Parent as SPSite)
                {
                    SPWeb rootweb = site.RootWeb;
                    ChangeSiteMaster(rootweb, RavishankarMasterPage);                  
                }
            });
       }

 Where the constants are :

#region Constants
        internal const string masterPagesfolder = "RavishankarMasterPage";
        internal const string pageLayoutsFolder = "RavishankarPageLayouts";
        internal const string defaultMasterPage = "_catalogs/masterpage/v4.master";
        internal const string RavishankarMasterPage = "_catalogs/masterpage/RavishankarMasterPage/Ravishankar.master";

        internal const string publishingImagesFolder = "Ravishankar.Images";
        internal const string publishingImagesPath = "/PublishingImages/";

        internal const string styleFolder = "Ravishankar.Styles";
        internal const string stylePath = "/Style Library/";

        internal const string jsFolder = "Ravishankar.Js";
        internal const string jsPath = "/Style Library/";

        #endregion

8. On DeActivating the feature, your code should look like below:

/// <summary>
        /// Handles the feature deactivating event
        /// </summary>
        /// <param name="properties"></param>
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            try
            {
                if (properties != null)
                {
                    SPSecurity.RunWithElevatedPrivileges(
                    delegate()
                    {
                        using (SPSite site = properties.Feature.Parent as SPSite)
                        {
                            SPWeb rootweb = site.RootWeb;
                            DeleteImagesJsCssFolders(rootweb);
                            ChangeSiteMaster(rootweb, defaultMasterPage);
                            DeleteFolders(rootweb, masterPagesfolder);
                            DeleteFolders(rootweb, pageLayoutsFolder);
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                SPSecurity.RunWithElevatedPrivileges(
                    delegate()
                    {
                        SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Ravishankar.Branding", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
                    }
                );
            }

        }

As you can see, one the Deactivation, I have called the following methods:

  • DeleteImagesJsCssFolders(rootweb);

  • ChangeSiteMaster(rootweb, defaultMasterPage);

  • DeleteFolders(rootweb, masterPagesfolder);

  • DeleteFolders(rootweb, pageLayoutsFolder);

DeleteImageJsCssFolder

As we need to update the CSS, images and JavaScript on activation and remove them when we remove our solution, the code will remove all used CSS, images and JavaScript which the solution used. Code is like below:

private void DeleteImagesJsCssFolders(SPWeb rootweb)
        {
            SPFolder folder;
            string imagesPath = rootweb.Url + publishingImagesPath + publishingImagesFolder;
            folder = rootweb.GetFolder(imagesPath);
            if (folder != null && folder.ItemCount > 0)
            {
                folder.Delete();
            }

            string styleLibraryPath = rootweb.Url + stylePath + styleFolder;
            folder = rootweb.GetFolder(styleLibraryPath);
            if (folder != null && folder.ItemCount > 0)
            {
                folder.Delete();
            }

            string jsLibraryPath = rootweb.Url + jsPath + jsFolder;
            folder = rootweb.GetFolder(jsLibraryPath);
            if (folder != null && folder.ItemCount > 0)
            {
                folder.Delete();
            }
        }

ChangeSiteMaster

On retraction, we need to reset the master page to the original state, so we have to implement the logic so that existing master page will reset to Sharepoint site. The code should be like:

/// <summary>
        /// Changes site master page to default
        /// </summary>
        /// <param name="web">root web of the site</param>
        internal void ChangeSiteMaster(SPWeb web, string defaultMasterPage)
        {
            using (SPWeb currweb = web)
            {
                currweb.CustomMasterUrl = GetUrlWithTrailingSlash(currweb.ServerRelativeUrl) + defaultMasterPage;
                currweb.Update();
                foreach (SPWeb childweb in currweb.Webs)
                {
                    ChangeSiteMaster(childweb, defaultMasterPage);
                    childweb.Dispose();
                }
            }
        }


DeleteFolder

Finally we need to remove the folder which contains Master Pages and Page layouts. Here is the code for that:

/// <summary>
        /// Deletes folder from the master page gallery
        /// </summary>
        /// <param name="rootweb">rootweb of the site</param>
        internal void DeleteFolders(SPWeb rootweb, string folderName)
        {
            //Removing the master pages and page layouts folder.
            SPList galleryList = rootweb.GetCatalog(SPListTemplateType.MasterPageCatalog);
            SPFolderCollection subfolders = galleryList.RootFolder.SubFolders;
            if (subfolders != null && subfolders.Count > 0)
            {
                SPFolder folder = subfolders.OfType<SPFolder>().ToList().Find(i => string.Equals(i.Name.Replace(" ", ""),
                    folderName.Replace(" ", ""),
                    StringComparison.CurrentCultureIgnoreCase));
                if (folder != null)
                {
                    folder.Delete();
                    galleryList.Update();
                }
            }
        }

That's all. We are ready with our Branding Solution.

Summary

As this solution structure is standard and more flexible, it is ready for use for your development purpose. This will save a lot of your development effort and provide a standard solution structure which you can use for multiple applications in Sharepoint. Feel free to post comment if anything is not clear or need any clarification.