Saturday 17 September 2011

How to create a simple Custom Site Definition with Visual Studio 2010

When you create a new site you will have different sites you can choose from the nice and shiny Silver Light menu.

In this article I am going to focus of how to create a custom site definition with the help of Visual Studio 2010. I am not going to use any plugin like CKSDev, just because I keep thinking when you are learning something you have to avoid any kind of short cuts and concentrate in the core of the subject, that is the only way to understand how the things work. This approach will provide you a bigger picture and it will allow you go to extra mille with this product.

First of all, What is a Custom Site Definition? : Easy… a blank site, where we can add “things”. A custom site definition doesn’t need to have code behind, you can add it if you want to make your site clever, but that is what I call “advance level”. I am going to demonstrate how to create a site definition with code behind, of course, assuming you are in advance level. I will add bits and bobs that could be interesting for your new site.

Let’s go to start a step by step tutorial, this is the end result (see below). At the end of the article you will see you can download the file.

image

Step 1
Go to Visual Studio 2010->New Project->Sharepoint –> 2010 –>Site Definition and call the project netsourcecodeSiteDefinition
image

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Step 2
Now we have the project, select it, right click and Add->New Item…->Visual Webpart-> Call it; SiteDefinitionVisualWebPart
image

Step 3
Go to Features->Feature1 and rename it to CSDFeature, your project should look like this now:
imageStep 4 
Now it is time to configure our web interface with the onet.xml file. This file is the key of the whole project. This little XML piece of code tell Sharepoint 2010 where we want to place the Navigation bars, Lists, WebFeatures etc.
We are going to start with the navigation bars. To avoid complexity at this level, I have decided to copy exactly the same that Microsoft use for their sites, have a look and think about it…but before these are the properties you need to be aware:

<NavBar
  Body = "Text"
  ID = "Integer"
  Name = "Text"
  Prefix = "Text"
  Separator = "Text"
  Suffix = "Text"
  Url = "Text">
</NavBar>

Now check the default navigation bar. In the onet.xml file add this code under <NavBars>:

<NavBar 
      Name="$Resources:core,category_Lists;" 
      Prefix="&lt;table border='0' cellpadding='4' cellspacing='0'&gt;" 
      Body="&lt;tr&gt;&lt;td&gt;&lt;table border='0' cellpadding='0' cellspacing='0'&gt;&lt;tr&gt;&lt;td&gt;&lt;img src='/_layouts/images/blank.gif' id='100' alt='' border='0'&gt;&amp;nbsp;&lt;/td&gt;&lt;td valign='top'&gt;&lt;a id='onetleftnavbar#LABEL_ID#' href='#URL#'&gt;#LABEL#&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;" 
      Suffix="&lt;/table&gt;" ID="1003" />

It is not easy to follow, I know that is why I am relying in the default one.


Step 5
In the onet.xml file under <Lists> add a new list, use this code. It is from a Microsoft Tutorial, and it will add a simple task list.

 <List 
        FeatureId="00BFEA71-A83E-497E-9BA0-7A5C597D0107" 
        Type="107" 
        Title="Project Tasks" 
        Url="$Resources:core,lists_Folder;/$Resources:core,tasks_Folder;" QuickLaunchUrl="$Resources:core,lists_Folder;/$Resources:core,tasks_Folder;/AllItems.aspx" />

Again, this is the definition for the element List (Click Here to learn more):

 <List
  CustomSchema = "Text"
  Description = "Text"
  EmailAlias = "Text"
  EnableContentTypes = "TRUE" | "FALSE"
  EnableMinorVersions = "TRUE" | "FALSE"
  FeatureId = "GUID"
  ForceCheckout = "TRUE" | "FALSE"  HyperlinkBaseUrl = Text
  QuickLaunchUrl = Text
  RootWebOnly = "TRUE" | "FALSE"
  Title = "Text"
  Type = Integer
  Url = "Text"
  VersioningEnabled = "TRUE" | "FALSE">
</List>

Before going to the next step I want you to have a look to that little number in the Type attribute. It has been set to 107, you will be asking…why is that? well, there is a reason for that. There is a list of types where the lists are defined by Microsoft in Sharepoint, have look:

    100    Generic list
    101    Document library
    102    Survey
    103    Links list
    104    Announcements list
    105    Contacts list
    106    Events list
    107    Tasks list
    108    Discussion board
    109    Picture library
    110    Data sources
    111    Site template gallery
    112    User Information list
    113    Web Part gallery
    114    List template gallery
    115    XML Form library
    116    Master pages gallery
    117    No-Code Workflows
    118    Custom Workflow Process
    119    Wiki Page library
    120    Custom grid for a list
    130    Data Connection library
    140    Workflow History
    150    Gantt Tasks list
    200    Meeting Series list
    201    Meeting Agenda list
    202    Meeting Attendees list
    204    Meeting Decisions list
    207    Meeting Objectives list
    210    Meeting text box
    211    Meeting Things To Bring list
    212    Meeting Workspace Pages list
    301    Blog Posts list
    302    Blog Comments list
    303    Blog Categories list
    1100    Issue tracking
    1200    Administrator tasks list
This attribute corresponds to the Type attribute of the ListTemplate element.

As you can see we are going for a Task List, I don’t know, perhaps we should add a 101 (Document Library), but I leave that in your hands so you can get some practice.


Step 6
This is how you onet.xml should look like, you can copy and paste it into your code if you want.

<?xml version="1.0" encoding="utf-8"?>
<Project Title="netsourcecodeSiteDefinition" Revision="2" ListDir="" xmlns:ows="Microsoft SharePoint" xmlns="http://schemas.microsoft.com/sharepoint/">
  <NavBars>    
	  <NavBar 
      Name="$Resources:core,category_Lists;" 
      Prefix="&lt;table border='0' cellpadding='4' cellspacing='0'&gt;" 
      Body="&lt;tr&gt;&lt;td&gt;&lt;table border='0' cellpadding='0' cellspacing='0'&gt;&lt;tr&gt;&lt;td&gt;&lt;img src='/_layouts/images/blank.gif' id='100' alt='' border='0'&gt;&amp;nbsp;&lt;/td&gt;&lt;td valign='top'&gt;&lt;a id='onetleftnavbar#LABEL_ID#' href='#URL#'&gt;#LABEL#&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;" 
      Suffix="&lt;/table&gt;" ID="1003" />
  </NavBars>
  <Configurations>
    <Configuration ID="0" Name="netsourcecodeSiteDefinition">
     <Lists>
        <List 
          FeatureId="00BFEA71-A83E-497E-9BA0-7A5C597D0107" 
          Type="107" 
          Title="Project Tasks" 
          Url="$Resources:core,lists_Folder;/$Resources:core,tasks_Folder;" QuickLaunchUrl="$Resources:core,lists_Folder;/$Resources:core,tasks_Folder;/AllItems.aspx" />
	  </Lists>
      <SiteFeatures>
      </SiteFeatures>
      <WebFeatures>
      </WebFeatures>
      <Modules>
        <Module Name="DefaultBlank" />
      </Modules>
    </Configuration>
  </Configurations>
  <Modules>
    <Module Name="DefaultBlank" Url="" Path="">
      <File Url="default.aspx">
      </File>
    </Module>
  </Modules>
</Project>

Step 7
It is time to check our beautiful non-used Visual Web Part. In the Microsoft Example the add a date control to filter the tasks, I think that is quite a good example so I am going to the same.
Go to your Visual Web Part (SiteDefinitionVisualWebPartUserControl) double click and copy and paste this code just after the Control tag:

<p>
Tasks Due on or before:
</p>
<p>
<SharePoint:DateTimeControl 
                            ID="DateTimeControl1" 
                            runat="server" 
                            OnDateChanged="filterDate_DateChanged"     
                            AutoPostBack="True" 
                            DateOnly="True" />
</p>
<SharePoint:ListViewByQuery runat="server" ID="taskView" />

Step 8
Now go to SiteDefinitionVisualWebPartUserControl.ascx.cs file and copy this code, but don’t forget to remove the blank Page_Load event.

SPQuery query;
SPWeb thisWeb;
protected void Page_Load(object sender, EventArgs e)
 {
   thisWeb = SPContext.Current.Web;
   taskView.List = thisWeb.Lists["Project Tasks"];
   query = new SPQuery(taskView.List.DefaultView);
   query.ViewFields = "<FieldRef Name='Title' /><FieldRef Name='AssignedTo' /><FieldRef Name='DueDate' />";
   taskView.Query = query;
 }
protected void filterDate_DateChanged(object sender, EventArgs e)
{
   String camlQuery = "<Where><Leq><FieldRef Name='DueDate' />"
   + "<Value Type='DateTime'>"
   + SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTimeControl1.SelectedDate)
   + "</Value></Leq></Where>";
   query.Query = camlQuery;
}
Don’t forget to add this “usings” at the top of your class:
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Utilities;
What are we doing here you will be asking yourself, well, let’s go to analyse the code.
On Page_Load(…) we tell our control taskView (listview) to get the list “Project Tasks”, after that we pass a CAML query to tell exactly what we want to display. Finally with taskView.Query=query we tell our object to render the results.
On filterDate_DateChanged(…) we pass the query with the date. Because the object (DateTimeControl1) has been setup to AutoPostback it will reload the list again and again…

Step 9
Now we have a functional visual web part, it is time to add it in our Custom Site Definition. How do we do this? it is quite easy, the only thing we need to do is “register” the webpart in the Custom Site Definition by adding a reference to it.
Go to SiteDefinition->default.aspx double click and add this code below the last  register tag.

<%@ Register TagPrefix="MyWebPartControls" Namespace="netsourcecodeSiteDefinition.SiteDefinitionWebPart" Assembly="$SharePoint.Project.AssemblyFullName$" %>

Step 10
Let’s go to add our Visual Web Part to the “PlaceHolderMain”, just copy and paste this code between the “PlaceHolderMain”

<MyWebPartControls:SiteDefinitionWebPart runat="Server" />

As you can see this is a very simple operation. You can add more Visual Web Parts in order create a very sophisticated Site Definition… but I assume that is another story.


Step 11
Moment of truth! Deploy… now go to your site, Site Actions->New Site
image


Be sure you select your template:
image


Conclusion: A Custom Site Definition can save plenty of time to the Administrator. If the Site is developed properly by a Software Architect the possibilities are endless. In my next tutorial I am going to demonstrate how to create a more complex site definition with a Site Provision Provider, this should allow you to inherit from another site definitions, for example.


Download the code!


image

5 comments:

Anonymous said...

Heу there supеrb blοg! Does running a blog sіmilar to thіѕ take a lаrge amоunt of work?
I have virtually no unԁerstanding of progrаmming but I ωaѕ hoρing to ѕtart mу own blоg in
the neаr future. Anyways, should уou have any suggestions oг
tips for neω blog owners plеase share. I underѕtand this is off
subjеct but I juѕt had to ask. Kudos!

Review my ρаge ... Selektah new youth culture clothing brand

Anonymous said...

We aгe a group of νolunteеrs and starting а nеw schemе іn ouг cоmmunity.

Your site provіdeԁ us with valuable infοrmation to worκ οn.
You've done a formidable job and our entire community will be thankful to you.

Look into my webpage - mediatemple coupon

Anonymous said...

Greetings! I know this is somewhat off topic but I was wondering if you knew where I could
get a captcha plugin for my comment form? I'm using the same blog platform as yours and I'm having
trouble finding one? Thanks a lot!

My web-site; raid recovery service

Anonymous said...

I am wondering which blogging and site-building platform you might be running?
I'm new to operating a blog and have been thinking about using the Hubpages platform. Do you think this is a good platform to start with? I would be very thankful if I could ask you some questions through email so I can learn a bit more prior to getting started. When you have some free time, please contact me at: russel.cherry@hotmail.de. Kudos

Here is my web blog; search search

chenmeinv0 said...

chanel bags
moncler coats
hermes outlet
moncler sale
rolex watches
cheap uggs
oakley sunglasses
abercrombie and fitch clothing
ralph lauren outlet
gucci handbags
2016.12.17xukaimin