Professional Documents
Culture Documents
Applies to: Microsoft Office SharePoint Server 2007, Microsoft Visual Studio 2008
June 2008
In Microsoft Visual Studio 2008, you can create custom activities that can be consumed in workflows.
Creating custom activities lets you encapsulate business logic that applies to different scenarios and
that can be used in different workflows. This Microsoft Office Visual How To demonstrates how to create
a custom activity to send an e-mail message with an attachment.
First, you must create your custom activity. Then, you can add that to a workflow project and use it to
send an e-mail message with an attachment.
Creating a Custom Activity Project
First, create a Visual Studio 2008 Workflow Activity Library project.
To create a Visual Studio 2008 Workflow Activity Library project
1. Open Visual Studio 2008.
3. Under the Workflow Project Type, select the Workflow Activity Library project template.
1. The first thing you must do is change your class declaration to inherit directly from Activity
instead of SequenceActivity.
Open your activity in code view, and change SequenceActivity to Activity. Your class
definition should look like the following.
C#
Copy Code
public partial class SendMailWithAttachmentActivity : Activity
{ …
2. Now you must create some Dependency Properties. Add the following fields inside your class
definition.
C#
Copy Code
public static DependencyProperty ToProperty
= DependencyProperty.Register(
"To", typeof(string),
typeof(SendMailWithAttachmentsTest));
Copy Code
[DesignerSerializationVisibility(DesignerSerializationVisibility.
Visible)]
[ValidationOption(ValidationOption.Required)]
[Browsable(true)]
[Description("Enter any e-mail recipients, separated by
semicolons")]
public string To
{
get { return
((string)(base.GetValue(SendMailWithAttachmentsTest.ToProperty))); }
set { base.SetValue(SendMailWithAttachmentsTest.ToProperty,
value); }
}
[DesignerSerializationVisibility(DesignerSerializationVisibili
ty.Visible)]
[ValidationOption(ValidationOption.Required)]
[Browsable(true)]
[Description("Enter the e-mail sender")]
public string From
{
get { return
((string)(base.GetValue(SendMailWithAttachmentsTest.FromProperty)));
}
set {
base.SetValue(SendMailWithAttachmentsTest.FromProperty, value); }
}
[DesignerSerializationVisibility(DesignerSerializationVisibilit
y.Visible)]
[ValidationOption(ValidationOption.Optional)]
[Browsable(true)]
[Description("Enter any carbon copy recipients, separated by
semicolons")]
public string CC
{
get { return
((string)(base.GetValue(SendMailWithAttachmentsTest.CCProperty))); }
set { base.SetValue(SendMailWithAttachmentsTest.CCProperty,
value); }
}
[DesignerSerializationVisibility(DesignerSerializationVisibility
.Visible)]
[ValidationOption(ValidationOption.Required)]
[Browsable(true)]
[Description("Enter the e-mail subject")]
public string Subject
{
get { return
((string)(base.GetValue(SendMailWithAttachmentsTest.SubjectProperty)
)); }
set {
base.SetValue(SendMailWithAttachmentsTest.SubjectProperty, value); }
}
[DesignerSerializationVisibility(DesignerSerializationVisibilit
y.Visible)]
[ValidationOption(ValidationOption.Optional)]
[Browsable(true)]
[Description("Enter the body text of the e-mail")]
public string Body
{
get { return
((string)(base.GetValue(SendMailWithAttachmentsTest.BodyProperty)));
}
set {
base.SetValue(SendMailWithAttachmentsTest.BodyProperty, value); }
}
[DesignerSerializationVisibility(DesignerSerializationVisibilit
y.Visible)]
[ValidationOption(ValidationOption.Optional)]
[Browsable(true)]
[Description("Enter an attachment file path")]
public string Attachment
{
get { return ((string)(base.GetValue
(SendMailWithAttachmentsTest.AttachmentProperty))); }
set {
base.SetValue(SendMailWithAttachmentsTest.AttachmentProperty,
value); }
}
[DesignerSerializationVisibility(DesignerSerializationVisibilit
y.Visible)]
[ValidationOption(ValidationOption.Required)]
[Browsable(true)]
[Description("Enter the Smtp Server for the email")]
[DisplayName("Smtp Server")]
public string SmtpServer
{
get { return ((string)(base.GetValue
(SendMailWithAttachmentsTest.SmtpServerProperty))); }
set {
base.SetValue(SendMailWithAttachmentsTest.SmtpServerProperty,
value); }
}
4. Now, you must add a property for your InvokeEvent field. This EventHandler property lets
you add code in a workflow to interact with this activity programmatically. Add this code under
the Properties you just added.
C#
Copy Code
[DescriptionAttribute("Invoke")]
[CategoryAttribute("Invoke Category")]
[BrowsableAttribute(true)]
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisib
ility.Visible)]
public event EventHandler Invoke
{
add
{
base.AddHandler(SendMailWithAttachmentsTest.InvokeEvent,
value);
}
remove
{
base.RemoveHandler(SendMailWithAttachmentsTest.InvokeEvent,
value);
}
}
5. Add a using statement at the top of the class. This enables you to access the ASP.NET 2.0 Mail
namespace for sending your e-mail message. Add the following code.
C#
Copy Code
using System.Net.Mail;
6. The last thing you must do here is override the Execute method. Add the following method
inside your class definition.
C#
Copy Code
Protected override ActivityExecutionStatus
Execute(ActivityExecutionContext executionContext)
{
// Raise Invoke Event to execute custom code in the
workflow.
this.RaiseEvent(SendMailWithAttachmentsTest.InvokeEvent,
this, EventArgs.Empty);
1. First, give your assembly a strong name. In Solution Explorer, right-click the project, and
then select Properties.
6. In this demonstration, we are not concerned with security, so clear the Protect my key file
with a password check box. Click OK.
Now your assembly is strong named, and all you have to do is install it to the global assembly
cache.
7. Save and build the project.
8. Open a Visual Studio 2008 command prompt.
9. Navigate to the Activity solution directory, and run the following command:
gacutil /if SendMailWithAttachmentActivity.dll
Now, that you have successfully installed your activity, you can use it from a workflow project.
Creating a Workflow Project
Next, you create a Sequential Workflow project to use your custom activity.
To create a Visual Studio 2008 Sequential Workflow project
1. Start Visual Studio 2008.
3. Under the Office Project Type, select the SharePoint 2007 Sequential Workflow project
template.
5. Type a valid SharePoint Web URL. The example uses http://moss.litware.com. Click
Next.
6. Select a library or list to associate with your workflow, and click Next.
7. Leave the default options for how a workflow can be started, Manually by users and When
an Item is created. Click Finish.
Adding a Custom Activity to the Toolbox
Now that you have created your Sequential Workflow project, you must add your custom activity to
your Toolbox before you can use it.
To add the custom activity to the Visual Studio 2008 Toolbox
4. Click OK.
5. Your activity is now available in the Toolbox.
Figure 1. Toolbox with new activity available
Note:
If you have a toolbox category selected, the activity is added to that category by default. You
can drag the activity to another category if you want.
Adding a Custom Activity to the Workflow
Now, you must add your custom activity to your simple workflow.
To add the custom activity to the workflow
This takes you to the code-behind class, and you will see that a method stub has been auto-
generated for you.
5. Add the following code inside this method.
C#
Copy Code
SendMailWithAttachmentActivity.To = "nicolec@litwareinc.com";
SendMailWithAttachmentActivity.From = "willisj@litwareinc.com";
SendMailWithAttachmentActivity.CC = "willisj@litwareinc.com";
SendMailWithAttachmentActivity.Subject = "Email with Attachment
Testing.";
SendMailWithAttachmentActivity.Body = "This email should have an
attachment.";
SendMailWithAttachmentActivity.Attachment
= @"C:\Documents and Settings\Administrator\Desktop\code
snippets.txt";
SendMailWithAttachmentActivity.SmtpServer =
workflowProperties.Site.WebApplication.OutboundMailServiceInst
ance.Server.Address;
6.
Note:
The purpose of this demonstration is to show you how to create and consume a custom activity. In a
real-world scenario, you would never hard-code these values. You would retrieve them
programmatically, or possibly through an Initiation form or a Task form.
Running the Workflow Project from Visual Studio 2008
Press F5 to run your workflow. When you activate this workflow on a document in a document library,
an e-mail message is generated and sent with the attachment you specified.
Figure 3. E-mail message with attachment
1. Introducing Office SharePoint Designer 2007 Workflows
Office SharePoint Designer 2007, a replacement for FrontPage, is used as an aid in the
rapid design and deployment of workflows. Office SharePoint Designer 2007 is specifically
designed to help create and customize web sites and workflows built with SharePoint
Products and Technologies. The Development process in SharePoint Designer is based on
declarative rules-based, code-free workflow editor.
SharePoint Designer (SPD) gives list administrators, business administrators, and designers
the ability to create workflows without writing any code. SPD exposes many of the
workflow activities that ship with SharePoint as "actions" that users can string together
into a sequential process. These actions are customized via sentences that describe the
action and bind data to action parameters.
However, businesses will oftentimes need more custom functionality than the actions
provided with SharePoint, requiring them to write custom code that can run on the
server. This guide describes how to write a custom code as an activity using the Visual
Studio Extensions for Windows Workflow Foundation and expose it as an action in SPD.
As the user is selecting and configuring conditions and actions in the workflow interface,
Office SharePoint Designer 2007 generates the two files that actually represent the
workflow class:
The workflow markup file, which contains markup language that describes the activities
included in the workflow.
The workflow rules file contains the business logic of the workflow in declarative rules
form, rather than as code.
2. Create a Microsoft Office InfoPath 2007 Form
1. Create a new Microsoft Office InfoPath 2007 Form.
2. Add two Text boxes and rename the text boxes as "Contributors" and "Readers".
3. Save the Form.
4. Publish the form with the two columns to the Microsoft Office SharePoint Server
2007 site for which the item level security needs to be implemented.
This code snippet generates the getter/setter code and allows you to specify the
property name, type and description for the property.
26. Fill in these fields in the boilerplate code with the corresponding values. Use Tab to
move between the fields and press enter when finished with the fields.
a. For deriving the Workflow Context object to retrieve the current SharePoint
Site:
i. Name: __Context.
ii. Type: WorkflowContext.
iii. Description: Context.
b. For retrieving the List Id for which the activity is attached:
i. Name: ListId
ii. Type: string
iii. Description: List Id
c. For retrieving the current List Item to provide Item Level Security:
i. Name: ListItem
ii. Type: int
iii. Description: ListItem
Note: Remove the Category Property and add the following code in its place for all the
three dependency properties.
[ValidationOption(ValidationOption.Required)]
The resulting output should resemble the following:
With this customized, the property is exposed to the rest of the workflow. The
workflow can now bind variables to these properties for both input and output.
27. In the Solution Explorer, right click on References to bring up the context menu
28. Select Add Reference.
29. From the Add Reference dialog box, add references to the
System.DirectoryServices.
30. In the Solution Explorer, right click on ItemLevelSecurityActivity.cs to bring up
the context menu.
31. Select View Code.
32. Add the following namespaces in the code:
4. Deploy the dll to the GAC and add it to the web.config file
The next step is to compile your activity and deploy it to the GAC
(C:\WINDOWS\assembly). The assembly must be signed. You can drag and drop this into
the GAC directory or use the .net gacutil tool. Keep a note of the assembly, class,
version, and public key token, as they'll be used later on in the .ACTIONS file.
1. Navigate to the root port directory of the SharePoint Site for which the activity is
created located in "C:\inetpub\wwwroot\wss\virtualdirectories" and search for
"web.config" file. These xml files contain lists of authorized types that can be used
for that server port.
2. Open the file and search for "WorkflowActions", which should take you to an entry
that looks like this:
<authorizedType
Assembly="ItemLevelSecurityActivity, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=7211fc0c4fbd8603"
Namespace="ItemLevelSecurityActivityLibrary"
TypeName="*"
Authorized="True" />
The activity dll is now ready to be run on the server
5. Edit the WSS.ACTIONS file to describe the activity
parameters
The final step of preparing an activity for SPD is to change the WSS.ACTIONS file. This
xml file describes the types of the promoted properties of the activity and how to map
them into a rules sentence.
1. Navigate to "C:\Program Files\Common Files\Microsoft Shared\web server
extensions\12\TEMPLATE\1033\Workflow" folder and open the WSS.ACTIONS file.
� AppliesTo � describes what types of lists this activity can be used for, either "list",
"doclib", or "all"
� Category � category that SPD will display in the categories for available actions
RuleDesigner
The variable parameters in the sentence, e.g. %1, etc., are exposed as customization
links. When displayed, they will be replaced with the "FieldBind" tags below, where %1 will
be replaced with the FieldBind with Id=1,etc.
The "FieldBind" tag describes each variable parameter. The "Field" attribute corresponds
to the parameter, or activity property, as it is described in the Parameter tag in the
markup. "DesignerType" describes what type of interface to show when the user clicks on
the link. For example, if you want to show a select user dialog, you would use
"SinglePerson" for the designer type. The "Text" attribute is how the field is displayed in
the sentence.
The end result for the above markup would look something like this in SPD:
Parameters
<Parameters>
<Parameter
Name="__Context"
Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext,
Microsoft.SharePoint.WorkflowActions"
Direction="In"/>
<Parameter
Name="ListId"
Type="System.String, mscorlib"
Direction="In" />
<Parameter
Name="ListItem"
Type="System.Int32, mscorlib"
Direction="In" />
</Parameters>
Finally, the "Parameters" tag tells the RuleDesigner how to map the fields to the promoted
properties on the workflow activity.
Each "Parameter" describes the name of the property (which should match the
corresponding FieldBind above), the system type of the property, and direction ("In"
means that the activity gets that parameter, and "Out" means the activity sets that
parameter).
Once you have this file laid out, save your file.
6. Boot SPD
1. Do an iisreset.
2. Navigate to Start | All Programs | Microsoft Office | Microsoft Office
SharePoint Designer 2007.
3. Select the File | New | Workflow menu command.
4. In the Workflow Designer dialog box, enter a name for the Workflow and select
the SharePoint Document library list for which the activity should be attached from
the Dropdown.
5. Check the Automatically start this workflow when a new item is created option.
6. Check the Automatically start this workflow whenever an item is changed option.
7. Click Next.
8. Click Actions
9. Select the More Actions
10. In the Workflow Actions dialog box, click the dropdown for the Select a Category
and choose Extras.
11. In the Choose an Action box, select the Item Level Security activity in sharepoint
designer will appear and click Add.
12. Note that Apply security to this Document Library is displayed.
13. Click on this option in the Actions
14. From the Choose List Item dialog box, Select the Current Item option and click OK
15. Now the Actions is changed by displaying the current item's name.
Without a doubts one of the best things of MOSS 2007 is the new SharePoint Designer, and within him,
the workflow designer, that allows us speedy and simple form to design workflows.
In this file, the conditions and the actions that appear within SharePoint Designer are defined.
<Condition Name="Creado en un intervalo de fechas determinado"
FunctionName="CreatedInRange"
ClassName="Microsoft.SharePoint.WorkflowActions.Helper"
Assembly="Microsoft.SharePoint.WorkflowActions,
Version=12.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c"
AppliesTo="list"
UsesCurrentItem="true">
<RuleDesigner Sentence="creado entre %1 y %2">
<FieldBind Id="1" Field="_1_" Text="fecha" DesignerType="Date"/>
<FieldBind Id="2" Field="_2_" Text="fecha" DesignerType="Date"/>
</RuleDesigner>
<Parameters>
<Parameter Name="_1_" Type="System.DateTime, mscorlib" Direction="In"/>
<Parameter Name="_2_" Type="System.DateTime, mscorlib" Direction="In"/>
</Parameters>
</Condition>
Herein, we can see the assembled dll that handles the condition, to which elements he is applied,
and if it is possible to use the present item in the workflow.
Within the condition we have the rule for the designer, with the text that is going to appear; each rule
uses a series of fields tags FieldBind, that connects with the necessary parameters in the assembled
file.
Each tag FieldBind has an identifier that corresponds with the position of the field within sentence
ID=1, and that will be %1 in the sentence attribute as well.
Also we can see attributes like Text, that will be the text by defect, and the DesignerType, that is the
type of field.
After that, we have the section of Parameters with the different parameters that will go to the
assembled file. The Name attribute has to correspond with the Field attribute of tag FieldBind, and
the direction of the parameter needs to be In for input and Out for output.
Now, we are going to see how the actions look in the same file; they are very similar to the
conditions.
The first part includes the assembled one that will take care to handle the action.
The second one, are the rules for the designer. In this case the fields that has been used are a
combobox (DesignerType= " Dropdown ") and a line of text (DesignerType= " TextArea ")
The third part of the parameters, besides to use both fields defined in the rule of the designer, uses
three additional parameters that are:
With these three fields (that they are pre-established, so that we can use them whenever we want) we
have as much control on the list as on the job stream that is being carried out.
At the moment A file XSD for this type of archives does not exist
Add custom workflow activities to SharePoint Designer (Part 2)
In order to add a new activity to our SharePoint Designer, first we need to begin a WorkFlow project
in Visual Studio 2005, concretely, a Workflow Activity Library (Workflow activity library).
From this point we would create our activity; for this example I am going to create an activity
that will send a text to the event viewer.
1: public partial class LogEventViewer : Activity
2: {
3:
6:
7: public LogEventViewer()
8: {
9: InitializeComponent();
10: }
11:
17: [Category("User")]
18: [Browsable(true)]
19: [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
21: {
24: }
25:
32: {
34:
35: eventLog.Source = "SharePoint Workflow";
36:
37: try
38: {
40: }
41: finally
42: {
43: eventLog.Dispose();
44: }
45:
47: }
48: }
First, we declare a dependent property of the workflow called TextLogProperty, which we will use
to pass the text that we wish to show in the event viewer.
The internal property of the activity will be TextLog; this internal property obtains and establishes the
value from the dependent property of the workflow.
Then we define the Execute method, that will be the method in charge to visualize the message in
the event viewer.
A good practice is that the activities include a Validador, that I have omitted in the example but that is
highly recommended although not obligatory, or if we want to use the activity inside of the visual
studio workflow designer.
Once we have made the compilation, we can test it first (another good practice) creating an
application to host the workflow and checking the activity.
Finally, after we are sure that our activity works correctly, we must install it in the GAC in our
SharePoint server. And we need to modify the Web.config to include our assembly in the following
section:
<System.Workflow.ComponentModel.WorkflowCompiler>
<authorizedTypes>
......
<authorizedType Assembly="IdeSeg.SharePoint.Workflow.Activities,
Version=1.0.0.0, Culture=neutral,
PublicKeyToken=3bba710be857fdc1"
Namespace="IdeSeg.SharePoint.Workflow.Activities"
TypeName="*"
Authorized="True" />
</authorizedTypes>
</System.Workflow.ComponentModel.WorkflowCompiler>
Now we need to modify the file WSS.ACTIONS that we saw in the first article in order to add our new
action
<Action Name="Log en visor de eventos"
ClassName="IdeSeg.SharePoint.Workflow.Activities.LogEventViewer"
Assembly="IdeSeg.SharePoint.Workflow.Activities, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=3bba710be857fdc1"
AppliesTo="all"
Category="Personalizadas">
<RuleDesigner Sentence="Logear el evento siguiente %1">
<FieldBind Field="TextLog" Text="este mensaje" Id="1"
DesignerType="TextArea"/>
</RuleDesigner>
<Parameters>
<Parameter Name="TextLog" Type="System.String, mscorlib" Direction="In"
/>
</Parameters>
</Action>
What we have done in the first place is authorize our assembly so that he is now an integral part of
the WorkFlow engine of SharePoint, and secondly, adding it to the WSS.ACTIONS file, we have
indicated to the SharePoint Designer that we have added a new activity.
When we use SharePoint Designer to publish a site, at the moment that we created a new workflow or
we published an existing one, he communicates with SharePoint and recovers the File WSS.ACTIONS
to configurate the assistant of the WorkFlow.
In this way the new actions will be part of the file XOML that the SharePoint Designer will create.
Finally the result within the SharePoint Designer will be as follow:
Creating your own Custom Workflow Activities as Components using Windows
Workflow Foundation (Framework 3.0) and deployment on SharePoint 2007.
//-----------------------------------------------------------------------------//
//--------------Active Directory helper Class----(Rifaqat:2nd April 06)-------//
//-------Description: ...............................................--------//
//-------------------------------------------------------------------------//
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.DirectoryServices;
using System.Collections;
namespace ActivityLibrary1
{
internal class ADHelper
{
private string ldapPath;
DirectorySearcher search;
internal ADHelper(string ldapPath)
{
this.ldapPath = ldapPath;
search = new DirectorySearcher(new DirectoryEntry(ldapPath));
}
internal string GetUsersManager(string loginName)
{
SearchResult result;
search.Filter = String.Format("(SAMAccountName={0})", loginName);
search.PropertiesToLoad.Add("manager");
result = search.FindOne();
if (result == null)
{
return "";
}
else
{
string userPath = result.Properties["manager"][0].ToString();
System.DirectoryServices.DirectoryEntry de = new DirectoryEntry("LDAP://" +
userPath);
return de.Properties["sAMAccountName"].Value.ToString();
}
}
In this code the DirectoryUri and Query are passing as inputproperty and are used to specify
the text that will be displayed in the Display Name of User as Output. We use a dependency
property to enable the workflow to bind data to it. As with all workflow activities, the
Execute method performs the action.
Step 2: Sign and deploy the activity assembly to the GAC
After you build the custom activity assembly, sign it and copy it to the GAC. You then have
to tell SharePoint to trust the assembly. This is similar to configuring a web part as a safe
control, but instead of adding an entry to the <SafeControls> section, you add an entry to
the <System.Workflow.ComponentModel.WorkflowCompiler> section. Edit the web.config
file for your SharePoint web application and add an <authorizedType> element as in the
following example:
• Goto in your Site using this URL C:\Inetpub\wwwroot\wss\VirtualDirectories\10161
• Open your Config File.
• You need to add your assembly in specific site port config file:
This article will explain about Site Definition, why we do need custom site
definition ?and how to create and deploy a custom site definition.
Site Definition
• Site Definitions are the foundations on which all sites and user templates are built.
• Site Definition is collection ox XML and .aspx file.
• Site Definitions are predefined components needs to be included when a site was
created in SharePoint server.
• Site Definition contains information of Web Part , Lists, Features and navigation bars
to be included in the site.
• Customizing Portal Sites and other SharePoint sites using Site Definition is most
appropriate for third party developer and SharePoint Administrator.
• Site Definitions requires access to a file system of the Web Server.
• Server administrator must be also involved in deployment of Site Definitions.
• Custom Site Definitions are Version and Upgrade independent.
• Subsequent upgrades to SharePoint products and technologies may overwrite
existing Site Definitions. Using Custom Site definition exclude site from potential
upgrade issues.
• To avoid Unghosting , Custom Site Definition is to be create.
• There are two options to create it
1. Create New Site Definition File : Either Start from Scratch and create files one
by one or Copy an existing Site Definition and modify it.
2. Copy a Site Definition and change it in Visual Studio: We can make copy an
existing site definition and modify it in visual studio to create new site
definition.
• The configuration of this site definitions are defined in XML file which is available in
Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=12
.0.0.0,Culture=neutral,P
Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint,
Version=12.0.0.0, Culture=neutral,
Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint,
Version=12.0.0.0, Culture=neutral,
Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages"
Assembly="Microsoft.SharePoint,
<SharePoint:EncodedLiteral runat="server"
text="<%$Resources:wss,multipages_homelink_text%>"
</asp:Content>
runat="server"/></label>
</asp:Content>
<style type="text/css">
TD.ms-titleareaframe, .ms-pagetitleareaframe {
height: 10px;
Div.ms-titleareaframe {
height: 100%;
.ms-pagetitleareaframe table {
background: none;
height: 10px;
</style>
</asp:Content>
<script type="text/javascript">
</script>
</asp:Content>
<SharePoint:DelegateControl runat="server"
ControlId="SmallSearchInputBox" />
</asp:Content>
</asp:Content>
<style type="text/css">
.ms-bodyareaframe {
padding: 0px;
</style>
</asp:Content>
<tr>
<td class="ms-pagebreadcrumb">
<asp:SiteMapPath SiteMapProvider="SPContentMapProvider"
id="ContentMap" SkipLinkText=""
NodeStyle-CssClass="ms-sitemapdirectional" runat="server"/>
</td>
</tr>
<tr>
<td class="ms-webpartpagedescription"><SharePoint:ProjectProperty
Property="Description"
runat="server"/></td>
</tr>
<tr>
<td>
<tr>
</td>
</tr>
<tr>
<WebPartPages:WebPartZone runat="server"
FrameType="TitleBarOnly" ID="Left"
Title="loc:Left" />
</td>
<td> </td>
<WebPartPages:WebPartZone runat="server"
FrameType="TitleBarOnly" ID="Right"
Title="loc:Right" />
</td>
<td> </td>
</tr>
</table>
</td>
</tr>
<tr>
Title="loc:Bottom" />
</td>
</tr>
</table>
</asp:Content>
7. Register new site definition to SharePoint.
8. Open the folder
C:\Program Files\Common Files\Microsoft Shared\web server
extensions\12\TEMPLATE\1033\XML
9. Copy the file WEBTEMP.XML and save it as WEBTEMPTIGER.xml. here make a note that ,
we need to append name of folder which we created in step 2 ( in this case it is tiger) to
WEBTEMP. So here name would be WEBTEMPTIGER.xml
10. Open WEBTEMPTIGER.XML in notepad and replace it with following content.
<?xml version="1.0" encoding="utf-8"?>
</Template>
</Templates>
Make sure here ID should be greater than 10000. It must not collide with id of any other
Site Definition.
11. Restart IIS. Go to Start->Run->IISRESET
12. Now you would be able to see this Site Definition inside Custom category.