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
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).
2. Right-Click on the solution, click on Add->New item, select Module
3. Give Name Master Page.
4. Repeat step 2 for creating Page Layout, Style library and Publishing
Images. Your solution should look like:
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.