This blog is moved to
http://amalhashim.wordpress.com

Thursday, August 12, 2010

Sharepoint 2007 Deploying Styles as Feature

Assuming you have WSP Builder installed.
Open Visual Studio, From File –> New Project
image
Clicking OK will create a solution with the following folder structure
image
Now right click the Project “Test_Style” –> Add –> New Item
image
From the Add New Item dialog Select WSPBuilder –> Blank Feature
image
Clicking Add will bring up the following dialog
image
If you want the style to be applied on Site Collection level, then select the scope as Site, and Click OK will add feature/element files as shown below
image
Now add your style file under the folder TestStyle as shown below
image
Open feature.xml file and copy paste the following replacing the existing ElementManifests tag
<ElementManifests>
        <
ElementManifest Location="elements.xml"/>
        <
ElementFile Location="MyStyle.css" />        
</
ElementManifests>

Open elements.xml file and copy paste the following replacing existing contents
<?xml version="1.0" encoding="utf-8" ?>
<
Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<
Module Name="New Style" Url="Style Library" Path="" RootWebOnly="TRUE" >
<
File Url="MyStyle.css" Type="GhostableInLibrary" IgnoreIfAlreadyExists="TRUE"></File>
</
Module>
</Elements>






Now build the WSP by Right Clicking the project from Solution Explorer








image





Add the solution, and activate the feature.








Now, if you notice the feature was suppose to overwrite the file if it exists. But, if the file exists its not overwriting, even if we provide “IgnoreIfAlreadyExists” flag in elements.xml file. As a solution for this, we need to handle the FeatureActivated event and manually checkout the file and overwrite it and checkin the file. To achieve this we need to build a class library, which should go to GAC.







using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using System.IO;
using System.Diagnostics;




namespace UpdateStyleReceiver
{
class UpdateStyle : SPFeatureReceiver
{
SPWeb web = null;
string directoryPath = null;

// copy to location
string url = null;

public override void FeatureInstalled(SPFeatureReceiverProperties properties) { }

public override void FeatureUninstalling(SPFeatureReceiverProperties properties) { }

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
WriteMessageToEventLog("Feature Activated");

try
{
web = ((SPSite)properties.Feature.Parent).RootWeb;

// set the directory path on the file system where the feature was activated
directoryPath = properties.Definition.RootDirectory;

// run with elevated permissions so we can overwrite the file
SPSecurity.RunWithElevatedPrivileges(OverwriteFile);
}
catch (Exception ex)
{
WriteMessageToEventLog(ex.ToString());
}
}

public void OverwriteFile()
{
// create a new site object so that elevation works properly
SPSite site = new SPSite(web.Site.ID);

// copy to location
string url = null;

// get the url to the local file
string[] localFile = System.IO.Directory.GetFiles(directoryPath, "*.css", System.IO.SearchOption.TopDirectoryOnly);

// define a fstream object so we can read the contents of the file into a byte array
FileStream fstream = File.OpenRead(localFile[0]);

byte[] contents = new byte[fstream.Length];
fstream.Read(contents, 0, (int)fstream.Length);
fstream.Close();

// get a handle to the master page gallery
SPList styleLibrary = site.OpenWeb().Lists["Style Library"];

// get a handle to the folder we want to upload the file to
SPFolder editingMenuFolder = styleLibrary.RootFolder;

SPFile customQuickAccessFile = editingMenuFolder.Files["MyStyle.css"];

// build the destination copy url
url = site.Url + "/" + editingMenuFolder.Url + "/";

// check out the file, replace it with the modified one, and check it back in, publish and approve
customQuickAccessFile.CheckOut();
customQuickAccessFile.CopyTo(url + "MyStyle_Original.css", true);

WriteMessageToEventLog(editingMenuFolder.ServerRelativeUrl);
WriteMessageToEventLog(editingMenuFolder.Url);

// check in new file
customQuickAccessFile = editingMenuFolder.Files.Add(url + "MyStyle.css", contents, true);
customQuickAccessFile.CheckIn("File over-written by activiating the Published Page View Feature");
customQuickAccessFile.Publish("File published by activating the Published Page View Feature");
customQuickAccessFile.Approve("Approved by Published Page View Feature");

site.Close();
}

public void DeleteFile()
{
// create a new site object so that elevation works properly
SPSite site = new SPSite(web.Site.ID);

// get a handle to the master page gallery
SPList styleLibrary = site.OpenWeb().Lists["Style Library"];

// get a handle to the folder we want to upload the file to
SPFolder editingMenuFolder = styleLibrary.RootFolder;

SPFile customQuickAccessFile = editingMenuFolder.Files["MyStyle_Original.css"];

// build the destination copy url
url = site.Url + "/" + editingMenuFolder.Url + "/";

customQuickAccessFile.MoveTo(url + "MyStyle.css", true);

customQuickAccessFile.Publish("File published by activating the Published Page View Feature");
customQuickAccessFile.Approve("Approved by Published Page View Feature");

site.Close();
}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
WriteMessageToEventLog("Deactiviating Feature");

try
{
web = ((SPSite)properties.Feature.Parent).RootWeb;

// run with elevated permissions so we can overwrite the file
SPSecurity.RunWithElevatedPrivileges(DeleteFile);
}
catch (Exception ex)
{
WriteMessageToEventLog(ex.ToString());
}
}

private void WriteMessageToEventLog(string message)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
EventLog.WriteEntry("Copy Feature Receiver", message);
});
}
}
}



Modify the feature.xml as follows










<?xml version="1.0" encoding="utf-8"?>
<
Feature Id="20402429-a875-482d-a4c8-e8449f48d04c"
Title="Update Style"
Description="Description for Update Style"
Version="12.0.0.0"
Hidden="FALSE"
Scope="Site"
DefaultResourceFile="core"
ReceiverAssembly="UpdateStyleReceiver, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7701372303d9a778"
ReceiverClass="UpdateStyleReceiver.UpdateStyle"

xmlns="http://schemas.microsoft.com/sharepoint/">
<
ElementManifests>
<
ElementManifest Location="elements.xml"/>
<
ElementFile Location="MyStyle.css" />
</ElementManifests>
</
Feature>



1 comment:

autowebsite said...

Good share! The code can be used for Wordpress!