David Jacobus

SharePoint Consultant

  Home  |   Contact  |   Syndication    |   Login
  18 Posts | 0 Stories | 7 Comments | 0 Trackbacks

News

Hello,
My name is David Jacobus I am a former teacher of Computer Science and Mathematics, who is now working full time as a SharePoint Consultant!

Article Categories

Archives

Post Categories

Monday, October 27, 2008 #

ONET.XML

Part 4 is the real difference in the site definition we are creating and those offered in many books and blogs. Except for the methodology I am presenting, I haven’t really offered anything new! Today we will start to deviate. The ONET.xml file is fairly simple when you get to using it a few times! The ONET.XML file I am proposing is very simple and not much in it except for some OOTB xml and the only thing that will change in this instance is adding all the features we have created and two more new features! Feature receiver for code and a feature stapler to add the code to the site definition. But first let’s complete the ONET.XML file:

1. NavBars Element: We will keep the default quick launch so we will leave it alone!

clip_image002

2. List Templates Element is empty we’ll leave the same

3. Document Templates we will leave as is

4. Configurations elements: We’ll only have one so we will delete all but the default configuration.

a. We’ll keep <Configuration ID="0" Name="Default">

b. We’ll delete all the List Elements

i. We are using features to provision the lists

ii. The only configuration elements that are not empty is: Site Features and Web features

iii. WOW! This is in concert with the whole idea around the feature solution framework!

5. Modules elements: We will delete all the modules.

clip_image004

6. We will now add the features we have created to this point in the WSPBuilder project

clip_image006

7. We are done with ONET.XML (Easy Huh!)

a. But wait we haven’t provisioned default.aspx

i. It is normally provisioned via a module in ONET.XML

ii. We will provision it in a new feature!

1. So we can add a feature receiver

2. Add a new feature folder ABCTeamSiteRec

a. Build the site Definition as we need the strong name

b. Use Red Gate’s reflector to get the needed information

c. Drop the DLL into Red Gate and get the needed information

clip_image008

8. Add the following in the feature XML file:

<?xml version="1.0" encoding="utf-8"?>

<Feature

Id="{9F2EA305-7F72-40fd-A0E8-5353A5CBB251}"

Title="A Company feature: SiteDefinition Activation"

Description="SiteDefinition Activation"

Version="1.0.0.0"

Scope="Web"

Hidden="TRUE"

ImageUrl="ABCteamSite/company10.jpg"

ReceiverAssembly="ABCSiteDef, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e540898f86a0353c"

ReceiverClass="ABCSiteDef.FeatureReceiver" xmlns="http://schemas.microsoft.com/sharepoint/">

<ElementManifests>

<ElementManifest Location="elements.xml"/>

</ElementManifests>

</Feature>

9. Copy the default.aspx page to this feature folder and then add the following into the elements. Xml file:

<?xml version="1.0" encoding="utf-8" ?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<Module Name="HomePage" Path="" Url="">

<File

Url="default.aspx"

Type="Ghostable"

IgnoreIfAlreadyExists="False"/>

</Module>

</Elements>

10. Next we need to add the feature receiver add the following into a class at the root of the site not in the 12 hive

using System;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using Microsoft.SharePoint;

using Microsoft.SharePoint.WebControls;

using Microsoft.SharePoint.WebPartPages;

using Microsoft.SharePoint.Navigation;

using Microsoft.SharePoint.Administration;

namespace ABCSiteDef

{

public class FeatureReceiver : SPFeatureReceiver

{

public override void FeatureActivated(SPFeatureReceiverProperties properties)

{

SPWeb currentWeb = null;

SPSite currentSite = null;

object oParent = properties.Feature.Parent;

if (properties.Feature.Parent is SPWeb)

{

currentWeb = (SPWeb)oParent;

currentSite = currentWeb.Site;

}

else

{

currentSite = (SPSite)oParent;

currentWeb = currentSite.RootWeb;

}

// Get the web part manager

SPLimitedWebPartManager mgr = currentWeb.GetLimitedWebPartManager("default.aspx", System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);

// Tasks List

SPList list = currentWeb.Lists["Tasks"];

// Instantiate the web part

ListViewWebPart wp = new ListViewWebPart();

wp.ZoneID = "Left";

wp.ListName = list.ID.ToString("B").ToUpper();

wp.ViewGuid = list.DefaultView.ID.ToString("B").ToUpper();

mgr.AddWebPart(wp, "left", 1);

mgr.AddWebPart(wp, "left", 1);

// Calender List

SPList list7 = currentWeb.Lists["Calendar"];

// Instantiate the web part

ListViewWebPart wp7 = new ListViewWebPart();

wp7.ZoneID = "Left";

wp7.ListName = list7.ID.ToString("B").ToUpper();

wp7.ViewGuid = list7.DefaultView.ID.ToString("B").ToUpper();

mgr.AddWebPart(wp7, "left", 3);

mgr.AddWebPart(wp7, "left", 3);

// Internal Contacts List

SPList list2 = currentWeb.Lists["Internal Contacts"];

// Instantiate the web part

ListViewWebPart wp2 = new ListViewWebPart();

wp2.ZoneID = "Right";

wp2.ListName = list2.ID.ToString("B").ToUpper();

wp2.ViewGuid = list2.DefaultView.ID.ToString("B").ToUpper();

mgr.AddWebPart(wp2, "Right", 3);

// Announcements List

SPList list3 = currentWeb.Lists["Announcements"];

// Instantiate the web part

ListViewWebPart wp3 = new ListViewWebPart();

wp3.ZoneID = "Right";

wp3.ListName = list3.ID.ToString("B").ToUpper();

wp3.ViewGuid = list3.DefaultView.ID.ToString("B").ToUpper();

mgr.AddWebPart(wp3, "Right", 4);

// Links List

SPList list4 = currentWeb.Lists["Links"];

// Instantiate the web part

ListViewWebPart wp4 = new ListViewWebPart();

wp4.ZoneID = "Right";

wp4.ListName = list4.ID.ToString("B").ToUpper();

wp4.ViewGuid = list4.DefaultView.ID.ToString("B").ToUpper();

mgr.AddWebPart(wp4, "Right", 5);

currentWeb.Update();

}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)

{

/* no op */

}

public override void FeatureInstalled(SPFeatureReceiverProperties properties)

{

/* no op */

}

public override void FeatureUninstalling(SPFeatureReceiverProperties properties)

{

/* no op */

}

}

}

clip_image010

11. Next we need to add a feature stapler so the code and thus the web parts will be added to default.aspx when the site is provisioned!

12. Add A new feature folder to the WSPBuilder solution

a. Name it ABCTeamSiteRecStapler

i. Add the following feature code:

<?xml version="1.0" encoding="utf-8" ?>

<Feature Id="{5FAFFFF9-50BF-4fea-BC70-7AF3266AFC4E}"    note: make sure the guid points to the feature receiver

Title="$Resources:MultiLangStaplingFeatureName"

Description="$Resources:MultiLangstaplingFeatureDescription"

Version="12.0.0.0"

Scope="Site"

xmlns="http://schemas.microsoft.com/sharepoint/"

DefaultResourceFile="_Res">

<ElementManifests>

<ElementManifest Location="elements.xml"/>

</ElementManifests>

</Feature>

13. Add the following elements.xml file

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

<FeatureSiteTemplateAssociation

Id="{3D6DC874-154C-4e3d-AE0E-9A3F21D69136}"

TemplateName="ABCTeamSite#0" />

</Elements>

clip_image012

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

List Definitions Using SharePoint Solutions Generator 2008

1. Start SharePoint Solutions Generator

a. Create List Definition

clip_image002

clip_image004

clip_image006

b. The two custom lists are Internal Contact (Custom list) and Tasks (Custom View)

c. Hit defaults’ to finish

d. VS 2008 Solutions Generator will provide a link to the generated solution

clip_image008

2. Create two Feature folders in the WSPBuilder Solution

a. Tasks

b. InternalContacts

clip_image010

3. Copy the two folders created by the Solutions Generator into these folders

clip_image012

4. Notice the custom view in the tasks list definition

a. In addition, The ListDefinition.xml file.

b. We will use this to create the feature so:

i. Move this to the next folder up on both lists

clip_image014

5. Next we will create the feature files

a. Add a new xml file to the feature folder on both lists

clip_image016

b. Copy the following xml into the file:

<?xml version="1.0"?>

<Feature Id="{770CB6F9-FC52-4041-872E-83E9685B2F7A}"

Title="Internal Contacts"

Description=""

Version="1.0.0.0"

Scope="Web"

ImageUrl="ABCteamSite/company1.jpg"

xmlns="http://schemas.microsoft.com/sharepoint/">

<ElementManifests>

<ElementManifest Location="ListDefinition.xml" />

</ElementManifests>

</Feature>

clip_image018

c. Do the same for the Tasks list

d. Be sure to change the GUID on the list feature

e. The image should be the same but with a different number for each feature.

i. I use a small transparent gif of the company logo

ii. If I have 10 features I will have 10 images the same just numbered sequentially

iii. The reason is if someone deactivates a feature all the other features will show with a broken image if they all use the same image (Experience)

6. The List definition File will be the same that was created by the Solution generator

clip_image020

clip_image022

7. The real workhorse of the list definition is the schema.xml file and is beyond the scope of this blog entry!

8. Now we need to create list instance features for each list in the site:

a. 6 lists

i. Tasks

ii. Internal Contacts

iii. Calendar

iv. Links

v. Announcements

vi. Team Discussions

b. They will all be similar so a copy and paste would be appropriate

c. The custom lists instances will have their feature GUID exposed in their elements.xml file while list instance based upon built in list templates will reference the built in feature GUIDS.

d. Custom Lists (Tasks)

9. Built-in List (Announcements)

clip_image024

clip_image026

a. Notice the feature ID in the list instance reflects a built-in List feature ID: 0BFEA71-D1CE-42de-9C63-A44004CE0104

b. They are all the same until the last three digits in this case 104

10. Custom List Internal Contacts List template feature

clip_image028

clip_image030

a. Notice that the list instance points to the same feature as the list template

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

I spend some time over the last weeks reverse engineering Windows SharePoint Services 3.0 Tools: Visual Studio 2008 Extensions, Version 1.2 and with the help of a few bloggers who really did much of the investigations I just validated them. I’ll allude to these as we develop the site definition.

In WSPBuilder when creating a project the tool behind the scenes parses the 12 hive and creates entries in a solution manifest file corresponding to these entries. I won’t go into the details and they aren’t needed just use the tool and thank the developers for the effort, just understand that solution development was much harder before these tools were developed!

Let’s get started:

1. Create a new WSP Project:

clip_image002

2. The VS 2008 WSPBuilder Start:

clip_image004

3. Create the 12 hive folders you’ll need:

a. Template

i. 1033

ii. Features

iii. Images

iv. Layouts

v. SiteTemplates

vi. XML

clip_image006

Site Definition

The site definition I am going to create is based upon a custom team site developed in the UI. I am going to go through the process of the site definition development in WSPBuilder. Here is a screen shot of the proposed site definition:

clip_image008

What we have is 5 lists of which two are custom with views. The onet.xml file will have no custom navigation and the default.aspx page will have some custom list views on the page. (Caveat: We could build this site definition in its entirety with the SharePoint Solution generator 2008! We are not going to so I can demonstrate how to create a complete site definition thus useable on other site definition types!)

1. Lets add the fragments we will need to do a site definition:

a. Create a webtempABCTeamSite.xml file under the 1033 folder: Subfolder XML

clip_image010

clip_image012

2. Copy the following fragment into this file:

<?xml version="1.0" encoding="utf-8"?>

<Templates>

<Template Name="ABCTeamSite" ID="10002">

<Configuration

ID="0"

Title="ABCTeamSite"

Description="ABC Team Site"

Hidden="FALSE"

ImageUrl="/_layouts/images/ABCTeamSite/ABCTeamSite.png"

DisplayCategory="ABCCustom" />

</Template>

</Templates>

3. Create a folder beneath the images folder: ABCTeamsite and add an image of what the site will look like:

clip_image014

4. Copy the Team Site (STS) folder into the siteTemplates folder and rename it to ABCTeamSite

clip_image016

5. Get rid of defaultdws.aspx

6. Develop custom lists using the UI

a. If using content types develop the content type feature using the UI

i. Use MOSS Feature Generator MFG (CodePlex: http://www.codeplex.com/mossfeaturegenerator)

1. To generate the content type feature files

2. I don’t use MFG for List Definitions as I found some fidelity problems!

b. Use SharePoint solution Generator 2008 to develop the custom list definitions

clip_image018

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

For the last 1 1/2 years I have browsed and used content from hundreds of blogs that I have researched in the performance of my position as a SharePoint developer. I have needed to do this as SharePoint 2007 has many books which have shallow dives into the API only a few offer insights into “Best Practices” and the best way to accomplish SharePoint customizations. This blog entry is some pay back for all those bloggers whom I have used to ensure successful engagements.
In the last 16 months I have had 4 major clients and a few smaller ones and for a few of the engagements I have found the need to provide the client with a site definition for a common division/department site. In the beginning I used a couple of books which provided basic instructions on how to copy the SharePoint team site and configure it to meet specification. I was able to make it work but I knew that I had to spend too much time with the modifications to list definitions, and that humongous onet.xml file! 
When I first entered the SharePoint arena I did most all customizations through XML files: Content Types, etc. After my 2nd client I realized that although XML can get the job done it is ugly and exacting! Case sensitivity and a misspelled word could bring down a SharePoint installation especially when dealing with content types. Although XML is still a requirement much of the hassle can be alleviated with a combination of XML and code (C#). Therefore, this post is my take on best practices for Site Definitions as a combination of XML and code (C#) and a methodology to use in the development of site definitions.
Consultants/Developers need to have a common delivery mechanism of SharePoint Artifacts to the client. Two CodePlex tools are the mainstream tools used in the industry: STSDev and WSPBuilder. I have used both and they are time saving and first class tools for SharePoint solution files. I am a firm believer that as a developer we only deliver solutions to the client that can be installed onto client servers either directly onto the production server(s) or through the development, test, and production sequence. I have worked with some who will deliver direct SharePoint Designer solutions (me in the beginning) that are not repeatable installations but repeatable configuration solutions, they are fraught with errors!
For this blog entry I will focus on a solution built with WSPBuilder but I use STSdev in much of my work! Okay, let’s get one false impression that is out on the web thrown out! Windows SharePoint Services 3.0 Tools: Visual Studio 2008 Extensions, Version 1.2 is not a POS especially the SharePoint Solution Generator. In the 2005 version I wouldn’t use it because of all the GUID attachments to list names, etc which made the solution ugly and incomprehensible to the end user. But in VS 2008 the Solution Generator is a first class tool! I tested it on a custom teams site with 11 custom lists, custom list views and with custom dispform’s. The solution replicated a STP with full fidelity!   However, Microsoft put much of the under pinning’s in hidden features and custom build processes! So if you are going to use it for site definitions other than a custom team site then a reproducible solution is needed and thus the purpose of this blog entry!
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati