Chapter 7. Templates

Templates form the bedrock of most professionally developed SharePoint applications. They are more flexible and extensible than customized solutions built using the SharePoint UI or SharePoint Designer. There are different types of templates within the SharePoint framework. The range includes the following:

  • Column templates

  • List templates, including those for content types, fields, and views

  • Site templates

Working with templates enables you to develop solutions for custom columns, lists, content types, and complete SharePoint applications. Furthermore, they are highly reusable and deployable in order to create instances from your template on every SharePoint environment. In this context, we describe the new tools and opportunities introduced with Visual Studio 2010.

First this chapter describes how you can easily build a column template. This is followed by an explanation of the purpose and context for list templates. By constructing a sample list template, you'll learn how list definitions are structured, what kind of custom extensions you can build, and how to integrate such a template into your SharePoint application landscape.

The chapter also deals with the creation of templates for a SharePoint site or site collection. A simple example explains each component you need to construct your own custom site template.

By the end of this chapter, you should be able to build your own custom templates that can be used in nearly every SharePoint environment (depending on the SharePoint version you are using—Foundation, Standard, or Enterprise).

Templates Overview

In SharePoint 2010, different templates are available. This section describes each one in turn (Table 7-1 gives an overview).

Table 7.1. SharePoint 2010 Templates

Template

Description

Column templates

Can be created either using the Web UI or using an XML field definition

Custom field types

Are reusable and can be used as templates

List templates

Can be created using the SharePoint UI (List Settings

SharePoint 2010 Templates

List definitions

List definition in XML format that provides a list template

Site template

Can be created using the SharePoint UI (Site Settings

SharePoint 2010 Templates

Site definitions

Site definitions in XML format providing a site template

All these elements, except for custom field types, are covered in this chapter. Custom field types are explored in Chapter 11.

Column Templates

One of the easiest templates that you can create is a template for a site column. Templates for columns are often used if you require the same column in different lists—or even sites—over and over again. Consider, for example, a project management site that needs a Choice column called Status in every project-related list, and every instance has the same choice options. Simply build a feature once, defining a template for this specific column, and instantiate it many times.

To specify, deploy, and use such a column template, you need to build a SharePoint feature. Features in SharePoint are components with various contents, such as custom code, list definitions, event handlers, and Web Parts. They can be installed and activated separately in an existing SharePoint web site, or they can be integrated in a SharePoint solution (.wsp file). (Features are introduced in more detail in Chapter 9.)

The element manifest file of a feature specifies the column, as shown in Listing 7-1.

Example 7.1. Column Template Elements.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
     <Field ID="{2FAB9B49-1A3A-47b3-174C-8A84F0D322AB}"
       Name="Status"
       Group="MyProjectColumns"
       Type="Choice"
       DisplayName="Project Status"
       SourceID="http://schemas.microsoft.com/sharepoint/v4/fields"
       StaticName="Status"
       FillInChoice="FALSE">
         <CHOICES>
<CHOICE>Not Started</CHOICE>
             <CHOICE>Running</CHOICE>
            <CHOICE>Closed</CHOICE>
         </CHOICES>
         <Default>Not Started</Default>
     </Field>
 </Elements>

The attributes of the Field element specify the parameters of the template:

  • ID: Specifies the unique ID of the field

  • Name: Specifies the name of the field

  • Group: Specifies the group in which the custom column appears

  • Type: Specifies the field type of this column

  • DisplayName: Specifies the display name of the column

  • SourceID: References the SharePoint base field definitions

  • StaticName: Specifies the static name of the column

  • FillInChoice: Specifies whether an additional value can be entered in a choice field

  • Choices: Specifies the available choices and default choice of this field

(For details on creating a custom field type, see Chapter 11.)

Features can be deployed to a SharePoint environment with a specific scope. Some features may be used only on a concrete site, and others may be used for a whole SharePoint farm.

There are four possible values for the feature's Scope attribute:

  • Web: Single web site

  • Site: Site collection

  • WebApplication: Web application

  • Farm: SharePoint Farm

To deploy a custom site column definition on every web site separately (Web-scoped), you use the feature definition shown in Listing 7-2.

Example 7.2. Column Template Feature.xml

<?xml version="1.0" encoding="utf-8"?>
 <Feature Id="1F7BD552-10B1-1B54-85B5-5ED1D39C12F5"
   Title="ProjectStatusField"
   Description="Provides a custom project status choice column for lists."
   Version="1.0.0.0"
   Scope="Web"
   xmlns="http://schemas.microsoft.com/sharepoint/">

     <ElementManifests>
         <ElementManifest Location="elements.xml"/>
     </ElementManifests>
 </Feature>

The first attributes ID, Title, Description, Version, and Scope of the Feature element define mandatory data. The ElementManifest element references the Elements.xml file you created earlier (Listing 7-1).

As a result, you should have the target folder called ProjectStatus, as shown in Figure 7-1.

Custom column feature folder

Figure 7.1. Custom column feature folder

For deploying and activating, you can use the SharePoint administration command-line tool stsadm.exe.

(For more details about features, see Chapter 9.) After deployment and activation of this feature, you can see your status column in the "Available column types" list on the Column Creation page (see Figure 7-2).

Column Creation page

Figure 7.2. Column Creation page

The other approach to constructing a column template is to use the SharePoint UI. The following exercise demonstrates how to create a reusable site column.

List Templates

Templates for lists make sense in many scenarios. For example, if you need several instances from the same list type, including the same columns, views, and so on, on multiple web sites, you don't want to repeatedly build the same list. In such a scenario you would create a list template or definition once and reuse it.

List Definitions vs. List Templates

There are two types of list templates: list definitions and list templates. List templates can be created in the SharePoint UI. Simply go to the List Settings page of a list, and click "Save list as template." The template will be stored in the list template gallery. But this method has several disadvantages. When SharePoint creates the list template, there can be references to other lists and fields, if, for instance, you have used lookup fields. If you try to build a new list instance from this template in another SharePoint system, SharePoint may throw an exception because some of the references that are defined in the list definition file using GUIDs cannot be resolved. Another disadvantage is the limited extensibility. You can use only the fields and options that you can configure through the UI or SharePoint Designer.

List definitions, on the other hand, are specified in XML and are provided through a feature or site definition. Using list definitions, you have a greater scope for customization. For example, you can add event handlers for list events such as ItemAdded, and you can add custom actions that extend list context menus or toolbar buttons.

Custom List Definitions

To create a custom list definition, use the List Definition Visual Studio 2010 project template (Figure 7-3).

SharePoint project templates in Visual Studio 2010

Figure 7.3. SharePoint project templates in Visual Studio 2010

This project template offers a wizard where you can add a list instance feature based on the list definition you want to create. That could be confusing, because that is more than you need at this point. If you activate this feature, it will create a concrete list instance.

The presentation of these files in Solution Explorer shown in Figure 7-4 is even more confusing since the physical files that are deployed look different from this. You have to decide whether you can work more efficiently with the Visual Studio 2010 project template support for features, packages, and so forth, or whether you want to use the conventional method of building features, solutions, and so on. These conventional methods are, for instance, writing features and list definitions from scratch directly into XML files and using a folder layout in Solution Explorer such as the one illustrated in Figure 7-4.

For a pared-down list template, you only need a feature containing the list definition file. Thus, the target folder would have the structure and contents as in Figure 7-5.

Basic structure of the List Definition template

Figure 7.4. Basic structure of the List Definition template

Contents of the target folder

Figure 7.5. Contents of the target folder

To build our example list definition, remove the list instance related files so that you end up with the structure shown in Figure 7-6 in the Solution Explorer window.

Reduced structure for a list defintion without a list instance

Figure 7.6. Reduced structure for a list defintion without a list instance

For a list definition, you only need an XML list definition file called schema.xml and, according to the base type of your new list definition, different list forms. For a list based on the custom list template, you need no more files. Nevertheless, you have to specify four list forms inside the list definition file. The first three basic forms are derived from the %SharePoint Root%TEMPLATEPagesform.aspx template file. The AllItems.aspx page uses the viewpage.aspx page at the same location.

  • NewForm.aspx

  • EditForm.aspx

  • DispForm.aspx

  • AllItems.aspx

These four files are merely placeholders for the real content that will be loaded from SharePoint at runtime. Thus, these four files are identical for all list types that are derived from the custom list template or similar definitions. The list forms, especially the view forms, for the calendar or picture library list types use additional view forms that need to be delivered with the list definition.

You need to define a feature that acts as a container that can be deployed and that provides the custom list template in a SharePoint environment. A feature providing the list definition looks like Listing 7-3.

Example 7.3. Feature.xml

<?xml version="1.0" encoding="utf-8"?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
         Id="2de7fd2d-da5a-499d-860e-5e2b70374631"
         ImageUrl=""
         Scope="Web"
         Title="ProjectListFeature">
  <ElementManifests>
    <ElementManifest Location="Elements.xml" />
    <ElementFile Location="ProjectListSchema.xml" />
  </ElementManifests>
</Feature>

In addition to the standard feature attributes—ID, Title, Scope, and Description—you can define an assembly and class attribute for a custom feature receiver to handle the FeatureActivated and FeatureDeactivated events.

ReceiverAssembly="ProjectList, Version=1.0.0.0, Culture=neutral, PublicKeyToken=64f6d54d1d6e09cd"
ReceiverClass="Core.Feature.ListFeatureReceiver"

Tip

You can find a full reference for all feature attributes at http://msdn.microsoft.com/en-us/library/ms475601(office.14).aspx.

In a feature receiver FeatureActivated event, you can execute custom initializations when the feature is activated. For instance, create a list from the template you provide in this feature, and create initial list items.

A feature receiver class that implements event handlers for these events could look like the example in Listing 7-4.

Example 7.4. FeatureReceiver Class

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

namespace Core.Feature
{
    public class ListFeatureReceiver : SPFeatureReceiver
    {

        public override void FeatureActivated(
 SPFeatureReceiverProperties properties)
        {
            //feature is scoped at Web, so the parent type is SPWeb
            using (SPWeb web = properties.Feature.Parent as SPWeb)
            {
                //For Example print Url of the Web
                Response.Write(web.Url);
            }
         }
        public override void FeatureDeactivating(
 SPFeatureReceiverProperties properties)
        {
                //do nothing
        }
      }
}

The element <ElementManifest> specifies which element files are deployed for the list definition. In the example, the list definition file schema.xml and the elements.xml file contain the real list template declaration (see Listing 7-5).

Example 7.5. Elements.xml for List Definition Deployment

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <ListTemplate
        Name="ProjectList"
        Type="12099"
        BaseType="0"
        OnQuickLaunch="TRUE"
        SecurityBits="11"
        Hidden="TRUE"
        Sequence="410"
        DisplayName="ProjectList - My custom list"
        Description=""
        Image="/_layouts/images/itgen.gif"/>
</Elements>

Be careful that the value for the list template's name attribute and the subdirectory name shown in Figure 7-5 containing the list definition are exactly the same. Otherwise, SharePoint may not find the referenced files if you want to create a list instance from this template.

The other attributes define basic properties of the list template.

In any case, you must set a type attribute. The value should be greater than 10,000 in order to prevent conflicts with existing template types from SharePoint. Furthermore, you can control the visibility with the hidden attribute, set a base type, and enter values for the display name, description, and icon for the list template. Base types range from 0 to 4, where 0 refers to a list type and, for instance, 1 refers to a document library.

List Template Definition Files

The schema.xml file defines the final appearance of the list. The basic elements such as fields, views, and content types are defined in this file.

Listing 7-6 shows the basic structure.

Example 7.6. Basic List Definition Structure in schema.xml

<List>
    <MetaData>
<ContentTypes/>
<Fields/>
<Views>
  <View>
    <Joins/>
    <Projections/>
    <ViewFields/>
    <Query/>
  </View>
<Forms/>
</MetaData>
</List>

The following sections explain these basic elements of a list definition file and show how to build the example template step-by-step by defining the necessary attributes, fields, views, and so on.

The List Element

The List element specifies basic attributes such as list Title, Type, BaseType, and Url (see Listing 7-7).

Example 7.7. List Element in schema.xml

<List
  xmlns:ows="Microsoft SharePoint"
  Title="ProjectList"
  FolderCreation="FALSE"
  Direction="$Resources:Direction;"
  Url="Lists/ProjectList"
  BaseType="0">

The Url property is generally overwritten by the settings inside the onet.xml file of a site definition. Furthermore, you need to specify a BaseType ID from which your custom list template is derived. At this point, you can also define, for instance, whether to enable versioning.

Note

Additional attributes are optional; you can find them at http://msdn.microsoft.com/en-us/library/ms459356(office.14).aspx.

The ContentTypes Element

In the ContentTypes section, you define a new content type for your list template based on the base type of your list template. If you have used the Visual Studio list definition project template, it has created the section shown in Listing 7-8 inside your schema.xml file.

Example 7.8. ContentTypes Element in schema.xml

<ContentTypes>
    <ContentTypeRef ID="0x01">
        <Folder TargetName="Item" />
    </ContentTypeRef>
    <ContentTypeRef ID="0x0120" />
</ContentTypes>

Change this initial declaration to the one shown in Listing 7-9, since you're creating your own content type:

Example 7.9. ContentType Declaration

<ContentType ID="0x0100443C8F5ED3211f01ACC2EC3F262E51F6"
             Name="$Resources:Item"
             Group="$Resources:List_Content_Types"
             Description="$Resources:ItemCTDesc"
             Version="1">
<FieldRefs>
</FieldRefs>
</ContentType>

In this ContentType declaration, specify a unique ID, which must be in a particular format based on a hexadecimal inheritance schema (starting with 0x01) in combination with a unique ID. In addition, specify the Name, a Description, and a Group for your content type. (For more information about creating content types, see Chapter 4.)

After specifying custom fields in the next section, you can add these fields to your custom content type at this section. The content type section of the example will be completed later in the chapter.

Note

You can find explanations and a full reference to content types at http://msdn.microsoft.com/en-us/library/aa544130(office.14).aspx.

The Fields Element

In the Fields section of the list definition file, you define the fields that you want to use for your list. The field definitions are based on the fldtypes.xml file located in the %SharePoint Root%TEMPLATEXML folder. For example, if you want to add a simple text field, you would use the following line:

<Field
    Type="Text"
    Description="Name of the customer "
    DisplayName="Customer"
    Required="TRUE"
    MaxLength="255"
    ID="{1185203c-4916-47f9-af3f-d5ac6cbaf676}"
    Name="Customer"/>

Each field definition has standard attributes such as Name, Type, ID, Description, DisplayName, and Required, as well as some additional type-specific attributes, such as MaxLength for a text field. You have to supply some of these attributes such as Name, ID, and Type since they are required attributes.

Note

Other field attributes are optional and may be related to a field type. You can find a full reference of field attributes at http://msdn.microsoft.com/en-us/library/ms437580(office.14).aspx.

The ID attribute specifies a GUID to identify the field. You can add this ID to the previous content type definition if you want to use this field in your content type.

For the example with the project scenario, you need to define some fields for the project list (see Listing 7-10).

Example 7.10. Field Specification in schema.xml

<Field
    Type="Text"
    Description="Name of the Project"
    DisplayName="ProjectName"
    Required="TRUE"
    MaxLength="255"
    ID="{ce7ac62b-d584-48b6-8022-524b7bbaa83e}"
    StaticName="ProjectName"
    Name="ProjectName" />
<Field
    Type="Choice"
    DisplayName="Phase"
    ReadOnly="TRUE"
    Required="TRUE"
    Format="Dropdown"
    FillInChoice="FALSE"
    ID="{eeb87858-0017-46c3-8bba-31caa0abc9fa}"
    StaticName="Phase"
    Name="Phase">
        <Default>Presales</Default>
<CHOICES>
          <CHOICE>Presales</CHOICE>
          <CHOICE>Initiation</CHOICE>
          <CHOICE>Execution</CHOICE>
          <CHOICE>Close</CHOICE>
        </CHOICES>
 </Field>
<Field
    Type="Boolean"
    Description="Is the project manager contract owner?"
    DisplayName="ContractOwner"
    ID="{1a72202d-fcbe-40e7-9571-e59cfc4b4cc6}"
    StaticName="ContractOwner"
    Name="ContractOwner"
    RowOrdinal="0">
        <Default>0</Default>
</Field>
<Field
    Type="Currency"
    Description="Total Product Revenue"
    DisplayName="Volume Product"
    Required="FALSE"
    LCID="1033"
    ID="{6f5f2e54-2314-43de-9bd2-231ce4e984fb}"
    StaticName="VolumeProduct"
    Name="VolumeProduct" />
<Field
    Type="Currency"
    Description="Total costs for products"
    DisplayName="Cogs Products"
    Required="FALSE"
    LCID="1031" ID="{f4df0519-1cff-4fab-afa1-56591997a134}"
    StaticName="CogsProducts"
    Name="CogsProducts" />

Lookup Fields

You can define a lookup field that looks up a field in another list. For this, you need to supply the name of the lookup field, the target list, and the field from the target list that is to be displayed. You can even specify additional fields that come from that target list and show supplementary values—but they are read-only. Figure 7-7 shows how a lookup field refers to a Greetings list and displays two extra fields from that Greetings list.

List with lookup fields

Figure 7.7. List with lookup fields

The first field declaration specifies a normal lookup field called Greetings. The two subsequent fields are read-only and display additional data related to the first lookup field (see Listing 7-11).

Example 7.11. Lookup Field Specification in schema.xml

<Field Type="Lookup" DisplayNam="Greetings" Required="FALSE" List="Lists/Greetings" ShowField="Title" ID="{f76e5a46-83eb-480a-8e62-d99c67d3f9e9}" StaticName="Greetings" Name="Greetings" />

<Field Type="Lookup" DisplayName="Greetings:My Column" List="Lists/Greetings" ShowField="My_Column" FieldRef="f76e5a46-83eb-480a-8e62-d99c67d3f9e9" ReadOnly="TRUE" ID="{4f152f23-c6a2-4375-8de2-77df143b8bdc}"  StaticName="Greetings_x003a_My_Column " Name="Greetings_x003a_My _Column" />

<Field Type="Lookup" DisplayName="Greetings:MyColumn2" List="Lists/Greetings" ShowField="MyColumn2" FieldRef="f76e5a46-83eb-480a-8e62-d99c67d3f9e9" ReadOnly="TRUE" ID="{251798c2-95f6-451e-bd06-df9191774477}" StaticName="Greetings_x003a_MyColumn2" Name="Greetings_x003a_MyColumn2" />

Note

Defining lookup fields always presumes that the target list exists at runtime. Especially in templates and list definitions, you cannot be sure that the target list exists while instantiating a list from this template.

After specifying all fields, you can add them to your sample content type specification (see Listing 7-12).

Example 7.12. ContentType Specification in schema.xml

<ContentType ID="0x0100443C8F5ED3211f01ACC2EC3F262E51F6" Name="$Resources:Item"
             Group="$Resources:List_Content_Types"
             Description="$Resources:ItemCTDesc" Version="1" >
    <FieldRefs>
       <FieldRef ID="{ec70c353-343a-4d20-9532-29ce0150680b}" Name="ProjectName" />
       <FieldRef ID="{84c56f39-3d3f-4cf4-8be4-203cb94be296}" Name="Phase"/>
       <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" />
       <FieldRef ID="{f4df0519-1cff-4fab-afa1-56591997a134}" Name="ContractOwner"/>
       <FieldRef ID="{9f5f2e54-61ba-43de-9bd2-231ce4e984fc}" Name="CogsProducts" />
       <FieldRef ID="{6f5f2e54-2314-43de-9bd2-231ce4e984fb}" Name="VolumeProduct" />
       <FieldRef ID="{f76e5a46-83eb-480a-8e62-d99c67d3f9e9}" Name="Greetings" />
       <FieldRef ID="{4f152f23-c6a2-4375-8de2-77df143b8bdc}"
                 Name="Greetings_x003a_My_Column" ReadOnly="TRUE" />
       <FieldRef ID="{251798c2-95f6-451e-bd06-df9191774477}"
                 Name="Greetings_x003a_MyColumn2" ReadOnly="TRUE" />
    </FieldRefs>
</ContentType>

The Views Element

The Views section is one of the most important ones in the schema.xml file. Here you define how many views you need, which fields are displayed, and any other options such as filtering, grouping, and sorting.

To create a view for the list, you use the default view as a starting point (see Listing 7-13).

Example 7.13. Default View Specification

<Views>
    <View DisplayName="All Items" DefaultView="TRUE" BaseViewID="1" Type="HTML"
          MobileView="TRUE" MobileDefaultView="TRUE" XslLink="main.xsl"
          ImageUrl="/_layouts/images/generic.png" WebPartZoneID="Main"
          WebPartOrder="1" Url="AllItems.aspx" SetupPath="pagesviewpage.aspx">

        <XslLink>main.xsl</XslLink>
            <Query>
                <OrderBy>
                    <FieldRef Name="ID" />
                </OrderBy>
            </Query>
        <ViewFields>
            <FieldRef Name="Attachments" />
            <FieldRef Name="LinkTitle" />
            <FieldRef Name="Date" />
        </ViewFields>
        <RowLimit Paged="TRUE">30</RowLimit>
    </View>
</Views>

The View element specifies common properties:

  • DisplayName: Sets the name of the view

  • DefaultView: Sets the default view property

  • BaseViewID: Sets the ID of the base view

  • Type: Sets the type (the default is HTML; could be Chart or Pivot)

  • MobileView: Specifies whether it is a mobile view

  • MobileDefaultView: Sets the default for mobile view

  • ImageUrl: Sets the image at the ViewSelector

  • XslLink: Sets the path to the XSL rendering file

  • WebPartZoneID: Specifies the Web Part zone in which the list view is to be inserted

  • WebPartOrder: Sets the Web Part order inside the specified zone

  • Url: Sets the Url URL the Web Part Page that hosts the list view

  • SetupPath: Specifies a parent view page from which the actual (AllItem.aspx) page is derived

XSL-Based Rendering

The first element of the view references the XSL file that is used for rendering the view. The XSL-based rendering replaces the CAML-based approach from SharePoint 2007 that contained about 3,000 lines of rendering information inside the schema.xml file. With SharePoint 2010, you can now customize the rendering by editing the referenced main.xsl. There is a new element inside the view section called ViewStyle that controls the appearance of list items in a view. By inserting a specific ViewStyle ID, you can, for instance, display the list items in a tile arrangement instead of the standard list view. The next exercise demonstrates how you can change this design using SharePoint Designer.

Another new feature of SharePoint 2010 is the XSLT List View Web Part that replaces the existing list view Web Part.

We recommend that you use SharePoint Designer 2010 to customize the rendering of a list in these XSLT list view Web Parts, for instance, by creating conditional formatting. With SharePoint Designer, you can add rules to show or hide content; to change the format, fonts, or colors; and even to reorder the whole list item arrangement.

If you add a conditional formatting rule, SharePoint Designer adds the required XSLT code to the view page such as AllItems.aspx. Examine the changed contents of AllItems.aspx in order to reuse the XSLT specifications for your custom list definition. This procedure is much easier than writing the XSL transformation from scratch.

Joins and Projections

In SharePoint 2010, you can use CAML-based joins and projections to build views based on joining two lists connected via an existing lookup relationship. In essence, projections are like lookup fields that show one or more fields from the target list.

One or more joins are defined inside the Joins element within the View element. There are two types of joins: inner joins and left joins. You can define joins only between two lists, but you can build a chain of joins. Therefore, you have to use at least the parent list of the view, called the primary list. The other list for the join is called the foreign list. An additional join can be built from that foreign list joining to another foreign list, which in turn can join another foreign list, and so forth.

The following excerpt—not included in our sample project list definition—shows how it works.

The example scenario needs to display which projects are located at what location. So, the view needs to join the projects list with an existing project partner list and, in the next step, the project partner list with the list of locations. Define a lookup field named ProjectPartnerName in a Project list that looks up to a ProjectPartner list, as shown in Figure 7-8. This list has a lookup field called LocationName that looks up data from a Locations list, as shown in Figure 7-9 and Figure 7-10.

Project list view including Project Partner

Figure 7.8. Project list view including Project Partner

Project partners list

Figure 7.9. Project partners list

Locations list

Figure 7.10. Locations list

The joins defined within the schema look like Listing 7-14.

Example 7.14. Specification of Joins in schema.xml

<Joins>
  <Join Type="LEFT" ListAlias="ProjectPartner">
    <Eq>
      <FieldRef Name="ProjectPartnerName" RefType="Id" />
      <FieldRef List="ProjectPartner" Name="ID" />
    </Eq>
  </Join>

  <Join Type="LEFT" ListAlias="partnersLocations">
    <Eq>
      <FieldRef List="ProjectPartner" Name="LocationName" RefType="Id" />
      <FieldRef List="partnersLocations" Name="ID " />
    </Eq>
  </Join>
</Joins>

The type of join can be either left or inner. If you have more than one join from one list to another, they have to be distinguished using the ListAlias attribute in order to identify them individually. For the first Join element, the ListAlias attribute equals the name of the list. The next Join elements can have individually aliases. In the List attribute of the FieldRef element, you always have to use the value from the ListAlias attribute. The FieldRef parameter specifies the "join on" fields, where the first one is the lookup field from the primary list, and the second one is the field from the foreign list. The field from the foreign list must always be the ID field.

Note

You cannot use a multilookup field as a base for a join relationship.

If you have a Where clause in the Query section of the view that uses a field from a foreign list—for instance, LocationName—you need to specify this field in the ProjectedFields element (see Listing 7-15).

Example 7.15. Specification of Projected Fields in Schema.xml

<ProjectedFields>
  <Field
    Name="LocationName"
    Type="Lookup"
    List="partnerLocations"
    ShowField="Title" />
</ProjectedFields>

Should you want to show one or more fields from another list inside your view, you can define these fields inside the ProjectedFields element. You also have to insert these fields in the ViewFields section of the View element and in the content type specification.

The Name attribute refers to the name of the lookup field. The Type attribute must always be Lookup since the joins and projected fields mechanism is built on an existing lookup relationship between the two lists. The List attribute refers to the list alias specified in the corresponding join section. The final attribute, ShowField, defines the field from the foreign list that should be displayed in the view.

To distinguish a projected field from the normal lookup field that you can specify in the fields section, remember that projected fields always relate to joined lists, whereas lookup fields in the field section do not require a join relation.

Note

Not all lists can be joined, and not every field can be used as a "join on" parameter. Furthermore, the total number of join elements in a view cannot exceed the MaxQueryLookupFields property from the SPWebApplication object (the default is six).

The ViewFields Element

In the ViewFields section of a view, you can specify which fields should be visible in the list view. Listing 7-16 shows how you can define fields to be shown in a view.

Example 7.16. Specification of ViewFields in schema.xml

<ViewFields>
    <FieldRef Name="LinkTitle"/>
    <FieldRef Name="Phase" />
    <FieldRef Name="ProjectName" />
    <FieldRef Name="ContractOwner" />
</ViewFields>

You only need to supply the internal name of the field using a FieldRef attribute. In addition to the fields you have specified in the Fields section, you can refer to the base fields that exist in every list. For example, you can add the Title field to your view fields. That would add the Title text column. But you can also add LinkTitle if you want to add the title field with the context menu.

The Query Element

In this section, you can define a CAML-based query that sorts or filters your list elements in this view. Listing 7-17 gives an example.

Example 7.17. Query Specification in a View

<Query>
    <Where>
        <Eq>
            <FieldRef Name="Phase" />
            <Value Type="Text">Execution</Value>
        </Eq>
    </Where>
    <OrderBy>
        <FieldRef Name="ID"></FieldRef>
    </OrderBy>
</Query>

This query filters the list items by comparing the Phase field value with Execution and orders the list items by ID. Using CAML, you can build complex queries in this section.

Forms

Inside the <Forms> element, you define which forms are used for creating a new list item, editing an item, or displaying an item. If your list definition is based on the custom list template, you can use a master form, specified by the SetupPath attribute, from which your forms are derived (see Listing 7-18).

Example 7.18. Specification of Forms in schema.xml

<Form Type="DisplayForm" Url="DispForm.aspx"
      SetupPath="pagesform.aspx" WebPartZoneID="Main" />

<Form Type="EditForm" Url="EditForm.aspx"
      SetupPath="pagesform.aspx" WebPartZoneID="Main" />

<Form Type="NewForm" Url="NewForm.aspx"
      SetupPath="pagesform.aspx" WebPartZoneID="Main" />

You can also provide your own custom forms through this feature containing the list definition file and form files that are referenced through the Url attribute. Don't forget to include these custom forms inside the element manifest of the list definition feature. You create custom forms by simply copying the referenced form's .aspx file and renaming it to, for example, EditForm.aspx (Listing 7-19).

Example 7.19. Feature.xml for List Definition Using Custom Forms

<?xml version="1.0" encoding="utf-8"?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
         Id="2de7fd2d-da5a-499d-860e-5e2b70374631"
         ImageUrl=""
         Scope="Web"
         Title="ProjectListFeature">
    <ElementManifests>
        <ElementManifest Location="Elements.xml" />
        <ElementFile Location="ProjectListSchema.xml" />
        <ElementFile Location="ProjectListNewForm.aspx" />
        <ElementFile Location="ProjectListDispForm.aspx" />
        <ElementFile Location="ProjectListEditForm.aspx" />
        <ElementFile Location="ProjectListAllItems.aspx" />
    </ElementManifests>
</Feature>

Using List Templates

There are several different approaches to actually using your custom list templates. After deploying and activating the feature containing the list definition files—either built manually from scratch or autogenerated from Visual Studio—you can create a list from this list definition.

The following exercises describe four ways to create an instance from a list template, assuming the list definition is installed properly.

Custom list template on the Create page

Figure 7.11. Custom list template on the Create page

The following exercise includes a list definition in a custom site definition.

Another way of creating a new list is using the SharePoint API. In contrast to the preceding example, using the SharePoint API enables you to create a new list directly from a template without building a whole new site.

The final exercise shows how to use SharePoint Designer to create a new list from an installed list template.

Site Templates

By using templates for SharePoint sites, you can build complete SharePoint applications that can be instantiated over and over again. For example, if you need a SharePoint site for managing projects including custom lists, Web Parts, and so forth, you can define a site template that you can reuse for every project by instantiating a site from it. But, like list templates, site templates can be created in different ways, as you will learn in a moment.

Note

Almost every component that can be defined in a site definition can also be defined as a feature. Site definitions and features both use the SharePoint Foundation XML schema located in the SharePoint root in the XML/Schema subdirectory.

Visual Studio 2010 Support

Visual Studio 2010 includes a project template for a SharePoint site definition. By creating a new project from this project template, Visual Studio 2010 provides the necessary files and skeleton content (see Figure 7-12).

Site definition project template in Visual Studio2010

Figure 7.12. Site definition project template in Visual Studio2010

You can now use the new Visual Studio 2010 tools for SharePoint to complete your site definition. In the following sections, we explain how to use and extend the files that are generated by the Visual Studio 2010 project template.

SiteTemplate vs. SiteDefinition

SharePoint distinguishes between a site template and a site definition. You can create a site template by building a SharePoint application including lists, Web Parts, and such elements, using the SharePoint UI and the SharePoint Designer. Afterward, you can save the complete site as a template in a SharePoint solution (.wsp file) that can be imported to the site template gallery.

Site templates built this way are using their base template, such as team site or blank site, including such components as lists, Web Parts, and language settings. It follows that you need to be careful to provide the same preconditions as in the source SharePoint environment. If, for instance, the target SharePoint system uses a different language, the template wouldn't even appear in the template selection box of the target site's Create page. Although the algorithm was improved in SharePoint 2010, because SharePoint now builds .wsp solution files instead of .stp files (that only stored a delta of customizations compared to its base template), you still can't guarantee that your template will work in another SharePoint environment. To avoid surprises, you should consider the language and whether there were any customizations in the template's source site that can lead to missing references on the target site.

Site definitions, on the other hand, are defined in XML files and can contain all the necessary components—with no surprises. They are packaged in SharePoint solution files (.wsp) and are easy to transport since everything you need is packaged into a single file. Thus, site definitions are preferred by professional developers because they are more dependable and extensible.

The following exercise explains how to create a minimal site definition using Visual Studio 2010.

Basic site definition structure of the project template

Figure 7.13. Basic site definition structure of the project template

Site Definition Structure

A bare-bones site definition contains three files:

  • webTemp.xml: Created for every language version and contains the entries for the template selection box on the site creation page

  • onet.xml: Contains one or more configurations for a site template, including specification of all components used, such as features, lists, and Web Parts

  • default.aspx: Empty page

In the following subsections, these files are detailed. You will learn their purpose and which attributes are most important.

Note

For a full site definition reference and extending the examples, see the official MSDN reference at http://msdn.microsoft.com/en-us/library/aa978512(office.14).aspx.

webTemp.xml

Usually site definitions are deployed as SharePoint solutions. Although you could alternatively copy your site definition files to the SharePoint Root (14 hive), you gain much more control of your solutions by deploying it as a solution file (.wsp) using Central Administration or by uploading it to the solution gallery. (For more information about solution deployment, see Chapter 9.)

To use a site definition (by creating sites from a template), you must first specify a declaration of the template as an XML file in order to make it available in the template selection box of the New SharePoint Site page. This requires an XML file called webTemp*.xml. Insert your unique name in place of the asterisk to avoid overwriting internal template files. The path for these template declaration files is SharePoint RootTemplateLocaleCodeIDXML. In the Visual Studio 2010 Solution Explorer, these files appear beneath the locale ID, such as en-US.

To demonstrate the creation of a simple site definition, we will reuse the project management scenario from the list template chapter. Therefore, a simple template declaration file, called webTempProject.xml, looks like Listing 7-20.

Example 7.20. A webTempProject.xml File

<Templates xmlns:ows="Microsoft SharePoint">
  <Template Name="ProjectSite" ID="12099" >
     <Configuration ID="0" Title="SharePoint Project Management DB Site"
                   Description="" Hidden="FALSE"
                   ImageUrl="/_layouts/images/Project/logo.bmp"
                   DisplayCategory="CustomSharePoint" RootWebOnly="false" />
  </Template>
</Templates>

This short declaration contains the following elements and attributes:

  • Template element attributes:

    • * Name: Specifies the name of the template and the folder where the site definition is located inside the %SharePointRoot%TEMPLATESite Definition folder.

    • * ID: Specifies a unique ID for this template. Use IDs greater than 10,000 to avoid conflicts with existing SharePoint templates.

  • Configuration element attributes:

    • * ID: References the ID inside the onet.xml file of this site definition

      • * Title: Title of the new site

      • * Description: Description text of the new site

      • * Hidden: Flag indicating whether the configuration appears on the site creation page

      • * ImageUrl: URL to a picture that is displayed on the site creation page as a preview picture

      • * DisplayCategory: The category under which the configuration appears inside the template selection box of the site creation page

      • * RootWebOnly: Flag indicating whether the configuration can only be used for root sites (site collections)

Tip

If you have created a site definition using the Visual Studio 2010 site definition project template, you can easily locate the webTemp*.xml file in Solution Explorer under SiteDefinition

A webTempProject.xml File
Template selection box of the New SharePoint Site page

Figure 7.14. Template selection box of the New SharePoint Site page

This is a small example that creates an additional entry in the New SharePoint Site page template selection box in the specified group, as shown in Figure 7-14. But first you have to deploy this file by copying the file into the %SharePoint Root%TEMPLATELocaleIDXML folder and resetting IIS or using the Visual Studio 2010 built-in deployment by pressing F5.

In the webTemp*.xml file, you can specify much more than a single site template. For example, the SharePoint basic site definitions that are defined in the webtemp.xml file located in the same folder contain different configurations for such sites as team sites, meeting spaces, and blog sites.

To achieve this, you can specify multiple Template elements that reference different site definitions in the %SharePointRoot%TEMPLATESite Definition folder. Each of the Template elements can contain multiple configurations that are specified inside an onet.xml file of a site definition. An example of using multiple configurations is shown next. We also explain the structure of an onet.xml file and how the configurations work.

Site Provisioning Provider

Using a site provisioning provider, you can execute custom code in the provisioning event of a site. In the event handler method, you can directly customize the new site—for instance, by creating new subsites or lists.

In the Configuration element of the webTempProject.xml file, simply add two additional attributes (see Listing 7-21).

Example 7.21. webTempProject.xml

<Templates xmlns:ows="Microsoft SharePoint">
  <Template Name="ProjectSite" ID="12099" >
    <Configuration ID="0" Title="SharePoint Project Management DB Site"
                   Description="" Hidden="FALSE"
                   ImageUrl="/_layouts/images/Project/logo.bmp"
                   DisplayCategory="CustomSharePoint" RootWebonly="false"
                   ProvisionAssembly="Project, Version=1.0.0.0, Culture=neutral,
                   PublicKeyToken=xxxxxxxx"
                   ProvisionClass="Project.ProvisioningProvider"
                   ProvisionData="Custom Project Site"/>
  </Template>
</Templates>

In addition to the assembly and the class that implements the provisioning provider, you can also pass data, which is then available for further use in the event-handling method.

Listing 7-22 shows how the class ProvisioningProvider and the event-handling method for the Provision event are implemented.

Example 7.22. Custom Provisioning Provider

using System;
using Microsoft.SharePoint;

namespace Project
 {

    public class ProvisioningProvider : SPWebProvisioningProvider
    {
        public override void Provision(SPWebPovisioningProperties props)
        {
            //Apply Site Template
            properties.Web.ApplyWebTemplate("Project#0");

            //for further use of the site you need to elevate privileges
            SPSecurity.RunWithElevatedPrivileges(delegate() {
                using (SPWeb web = properties.Web)
                {
                    web.Title=properties.Data;
                    web.Update;
                }
            });
        }
    }
}

As a result, when a new site from the actual site definition is created, the Provision event handler automatically applies the first configuration of the project site definition and sets the Title of the site to the ProvisionData value you specified in the webTempProject.xml file. In the Properties.Web.ApplyWebTemplate method, the first part of the string Project#0 references the site definition, whereas the portion after the # defines the configuration.

You can use such a provisioning provider to automatically create subsites using a particular site definition. Doing it this way, you can even create sites from site definitions and their configurations that are marked as hidden and are not visible in the SharePoint Create Site page.

default.aspx

For a minimalist site definition, you need at least a start page for your new site. This start page is a page called default.aspx. It uses the default master page of SharePoint, and consequently you must supply all content in Content controls.

Tip

If you created a site definition using the Visual Studio 2010 site definition project template, a minimal default.aspx has already been created. Now you can easily extend it.

A skeleton default.aspx page, such as Visual Studio 2010, created with the site definition project template looks like Listing 7-23.

Example 7.23. Minimal default.aspx File

<%@ Page language="C#" MasterPageFile="˜masterurl/default.master" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c"  %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<asp:Content ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">
    <SharePoint:ProjectProperty Property="Title" runat="server"/>
</asp:Content>
<asp:Content ID="Content1" ContentPlaceHolderId="PlaceHolderMain" runat="server">
    <h1>
<asp:Literal ID="Literal1" runat="server" Text="<%$Resources:ProjectSite,Greeting%>"></asp:Literal>
    <font color="red">ProjectSite</font>
    </h1>
</asp:Content>

Besides the usual @Page, @Assembly, and @Register directives, a sample page title in the Content control with the ID Content1 is defined in the code. For our actual example, we will extend this to become a dual-zone Web Part page.

Add two WebPartZone controls to this Content control (Listing 7-24).

Example 7.24. Extended default.aspx

<asp:Content ID="Content1" ContentPlaceHolderId="PlaceHolderMain" runat="server">
    <h1>

        <font color="red"> ProjectSite</font>
    </h1>
                 <table width="100%" cellpadding=0 cellspacing=0
               style="padding: 5px 10px 10px 10px;">
            <tr>
                <td valign="top" width="70%">
                    <WebPartPages:WebPartZone runat="server"
                         FrameType="TitleBarOnly" ID="Left" Title="loc:Left" />
                                  </td>
                                  <td>&nbsp;</td>
                                  <td valign="top" width="30%">
                                      <WebPartPages:WebPartZone runat="server"
                         FrameType="TitleBarOnly" ID="Right" Title="loc:Right" />
                                  </td>
                                      <td>&nbsp;</td>
                                  </tr>
                </table>
</asp:Content>
Web Part zones at the default.aspx page

Figure 7.15. Web Part zones at the default.aspx page

These are empty Web Part zones whose contents can be filled by modules specified in the onet.xml file. This is a big advantage because you can provide one empty start page (containing only a page title and empty Web Part zones) that can be used for different configurations. The next section explains how this works.

Onet.xml

The core of a site definition is the onet.xml file that specifies all the components that the site contains, such as lists, Web Parts, and pages.

To allow SharePoint to find the onet.xml and any files referenced in it while creating an instance from a site template, it is essential that the file is located in a subfolder of %SharePoint Root%TemplateSiteTemplates. The folder's name must be the same as the one specified in the webTemp*.xml's template name attribute. In our example, the folder's name is ProjectSite.

Thus, the ProjectSite folder must hold a default.aspx file and a subfolder called XML containing the onet.xml file. Figure 7-16 shows the target folder.

Site template target folder

Figure 7.16. Site template target folder

The basic structure for the onet.xml looks like Listing 7-25.

Example 7.25. Basic Structure of onet.xml

<Project Title="ProjectSite">
    <NavBars/>
    <ListTemplates/>
    <DocumentTemplates/>
    <Configurations>
        <Configuration ID>
            <Lists/>
            <Modules/>
            <SiteFeatures/>
            <WebFeatures/>
        </Configuration>
    </Configurations>
    <Modules>
        <Module/>
    </Modules>
</Project>

Tip

If you have created a site definition using the Visual Studio 2010 site definition project template, a basic onet.xml file has been generated automatically. You can easily extend this onet.xml file.

The project element is the root element. The value of the title attribute must once again match with the subfolder's name under %SharePointRoot%14TemplateSiteDefinition and the entry in the webTempProject.xml file.

  • NavBars: This defines the top and quick launch navigation statically so that when creating a new page, the desired navigation is available directly.

  • ListTemplates: This defines list templates that are provided for use in the new site.

  • Document Templates: This provides document templates for list types and document.

  • Configurations: Each configuration is a set of lists, modules, and features.

  • Modules: This specifies one or more modules that are used within configurations and contain a Web Part page's content, sites, and auxiliary files.

The following sections explain each element with an example and incrementally build a complete definition for a sample project site.

The NavBars Element

In this section, we define several entries for the top-navigation and quick launch bar. With little effort you can define a complete navigation structure for the site.

Listing 7-26 shows the common format for two-level navigation.

Example 7.26. Basic NavBar Structure

<NavBar Name=""  ID="" Url="">
    <NavBarLink Name="" Url=""/>
</NavBar>

Tip

All NavBarLink elements that are defined in onet.xml are static links that appear in the UI regardless of whether the user has the right to visit the link's target page. A more flexible solution is to change the navigation bars programmatically—in a feature receiver, for instance.

The top navigation bar must start with ID 1002. This is because the top node for the top navigation starts with 1002 in the content database. You can copy and paste the entry from the STS site definition in order to get an empty top navigation bar containing a home link button only (see Listing 7-27).

Example 7.27. Specification for Top-Navbar (Watch That the Body Attribute Contains HTML)

<NavBar Name="$Resources:core,category_Top;"
        Separator="&amp;nbsp;&amp;nbsp;&amp;nbsp;"
        Body="&lt;a ID='onettopnavbar#LABEL_ID#' href='#URL#'
                  accesskey='J'&gt;#LABEL#&lt;/a&gt;"
        ID="1002" />

For the quick launch bar on the left side, you can define <NavBar> elements for your project site from ID 1025 because that's the start node for the quick launch bar in the content database (see Listing 7-28).

Example 7.28. Specification of Quick Launch Bar

<NavBar Name="Project" ID="1025" Url="default.aspx">
    <NavBarLink Name="ProjectDetails" Url="details.aspx"/>
    <NavBarLink Name="FinancialDetails" Url="financials.aspx"/>
    <NavBarLink Name="Overview" Url="overview.aspx"/>
</NavBar>
<NavBar Name="Reports"ID="1026" Url=„reports.aspx">
    <NavBarLink Name="DetailsReport" Url="detailsreport.aspx"/>
    <NavBarLink Name="ProjectManagement Cockpit" Url="pmcockpit.aspx"/>
    <NavBarLink Name="FinancialReport" Url="financialreport"/>
</NavBar>
<NavBar Name="Project Team" ID="1027" Url="team.aspx"/>

The result of this NavBar specification looks like Figure 7-17 if you have created a new site from the site definition examples up to this point.

Navigation structure in the quick launch bar

Figure 7.17. Navigation structure in the quick launch bar

Tip

At this point, if you want, you can configure the quick launch bar to have a two-tier appearance. If you want a two-tier top navigation bar, you must use the administration pages (which requires the publishing feature to be activated) or use the SharePoint API.

The ListTemplates Element

In the ListTemplates section, you define list templates to be available on the Create page of the new site. At this point, you use list definition features and element.xml files to define these list templates. For the list definition example that you created earlier, the ListTemplate element looks like Listing 7-29.

Example 7.29. List Template Declaration in the onet.xml

<ListTemplate
    Name="ProjectList"
    Type="13001"
    Hidden="FALSE"
    BaseType="0"
    SecurityBits="11"
    Sequence="1410"
    DisplayName="Project List"
    Description="This list contains common project details."
    Image="/_layouts/images/itgen.gif" />

Document Templates

The DocumentTemplates element is used to define templates for document libraries that are available if you click the New button in the document libraries toolbar. We recommend you copy and paste the section from the team site definition, located in the %SharePointRoot%TemplateSiteTemplateSTSXML folder, and, if necessary, extend or replace it with your own document templates. The section can also be left blank, but the user cannot create any new documents when they click the New button on the document libraries toolbar.

Modules

In the Modules section, you define one or more modules that can be used by configurations. A module is a container that can contain different files or content. This content could be as follows, for instance:

  • Master pages

  • Web pages

  • Web Part content

The next example defines two modules that are used in the configuration elements that are specified later.

The first module contains the default.aspx that is needed at least for a bare-bones site definition. Add the lines in Listing 7-30 to the onet.xml file.

Example 7.30. Module Specification in onet.xml

<Module Name="Default" Url="" Path="">
      <File Url="default.aspx" NavBarHome="True">

These lines merely name the module and reference the corresponding file. The NavBarHome attribute makes it the start page, available in the root of the site that is linked to the home button. Next, define two Web Parts for the left and right Web Part zones you added earlier to the Content control in default.aspx named Content1. The first one is a ContentEditorWebPart containing a "Hello World" message, located at the left WebPartZone (see Listing 7-31).

Example 7.31. Content Editor Web Part Specification in a Module

<AllUsersWebPart WebPartZoneID="TopLeftZone" WebPartOrder="1">
    <![CDATA[
<WebPart xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns="http://schemas.microsoft.com/WebPart/v2">
            <Title>Hello World</Title>
            <FrameType>TitleBarOnly</FrameType>
            <Description>Hello World</Description>
            <IsIncluded>true</IsIncluded>
            <ZoneID>Left</ZoneID>
            <PartOrder>1</PartOrder>
            <FrameState>Normal</FrameState>
            <Height />
            <Width />
            <AllowRemove>true</AllowRemove>
            <AllowZoneChange>true</AllowZoneChange>
            <AllowMinimize>true</AllowMinimize>
            <IsVisible>true</IsVisible>
            <Hidden>false</Hidden>
            <DetailLink />
            <HelpLink />
            <Dir>Default</Dir>
            <PartImageSmall />
            <MissingAssembly />
            <PartImageLarge>/_layouts/images/mscontl.gif</PartImageLarge>
            <IsIncludedFilter />
            <Assembly>Microsoft.SharePoint, Version=14.0.0.0, ...</Assembly>
            <TypeName>Microsoft.SharePoint.WebPartPages.ContentEditorWebPart
            </TypeName>
            <ContentLink
               xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />
            <Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor">
               Hello World!
            </Content>
            <PartStorage
               xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />
        </WebPart>
    ]]>
</AllUsersWebPart>

The Web Part's content needs to be in CDATA encoding, such as &lt; instead of a < character.

In the right Web Part zone, you specify the standard SharePoint Foundation Logo Image Web Part (see Listing 7-32).

Example 7.32. Image Web Part Specification in onet.xml

<AllUsersWebPart WebPartZoneID="Right" WebPartOrder="1">
<![CDATA[
    <WebPart xmlns="http://schemas.microsoft.com/WebPart/v2"
             xmlns:iwp="http://schemas.microsoft.com/WebPart/v2/Image">
        <Assembly>Microsoft.SharePoint, Version=14.0.0.0, ...</Assembly>

        <TypeName>Microsoft.SharePoint.WebPartPages.ImageWebPart</TypeName>
        <FrameType>None</FrameType>
        <Title>$Resources:wp_SiteImage;</Title>
        <iwp:ImageLink>/_layouts/images/homepage.gif</iwp:ImageLink>
<iwp:AlternativeText>$Resources:core,sitelogo_wss;</iwp:AlternativeText>
    </WebPart>
]]>
</AllUsersWebPart>

For the example report module, simply copy the default.aspx file, rename it to report.aspx, edit the NavBarHome attribute to false, and put it into the same folder as the default.aspx file. Specify a new module called Reports that contains a list view Web Part showing a project list that is an instance from the project list definition created earlier. This list is instantiated in the Configuration section shown in Listing 7-33.

Example 7.33. List View Web Part Specification in onet.xml

<Module Name="Reports" Url="" Path="">
    <File Url="Report.aspx" NavBarHome="False">
        <View List="12001" BaseViewID="0" WebPartZoneID="Left" WebPartOrder="1">
            <![CDATA[
                <WebPart xmlns="http://schemas.microsoft.com/WebPart/v2">
                    <Assembly>Microsoft.SharePoint, Version=14.0.0.0, ...</Assembly>
                    <TypeName>Microsoft.SharePoint.WebPartPages.ListViewWebPart
                    </TypeName>
                    <TitleProjectMasterData</Title>
                    <FrameType>TitleBarOnly</FrameType>
                </WebPart>
            ]]>
        </View>
    </File>
</Module>

Configurations

In this section, you can define one or more configurations for your site definition. Why should you define more than one configuration?

Imagine that you have built a site definition and want to use it on a developer system, a staging system for testing, and a production system. You want to integrate some kind of feedback or bug-tracking list, but this shouldn't appear in a production environment. Configurations give you the ability to build different templates that vary slightly from each other. For example, you can build three different configurations that contain largely the same content but with a "bug-tracking" list added for the developer configuration and a feedback list included in the staging configuration. The production environment has no extras. You can control the visibility of these configurations in the webTempProject.xml file via three different configuration sections.

There are essentially three types of components can you define in an onet.xml configuration section:

  • Lists

  • Modules

  • Features

Extend your project site definition example by adding the three different configurations outlined earlier.

Start by defining the production configuration that contains the base components (Listing 7-34).

Example 7.34. Configuration Specification in onet.xml

<Configuration ID="0" Name="Production"
               CustomMasterUrl="_catalogs/masterpage/cc.master"
               MasterUrl="_catalogs/masterpage/cc.master">
    <Lists>
        <List FeatureId="00BFEA71-E717-4E80-AA17-D0C71B360101"
              Type="101"
              Title="$Resources:core,shareddocuments_Title;"
              Url="$Resources:core,shareddocuments_Folder;"
                 QuickLaunchUrl="$Resources:core,shareddocuments_Folder;
                                /Forms/AllItems.aspx" />
        <List FeatureId="7346F629-03E1-436D-B2A2-80E2744FD8BC"
              Type="12001"
              Title="ProjectList" Url="Lists/ProjectList" />
    </Lists>
    <Modules>
        <Module Name="Default" />
        <Module Name="Reports" />
    </Modules>
    <SiteFeatures>
        <!-- BasicWebParts Feature -->
        <Feature ID="00BFEA71-1C5E-4A24-B310-BA51C3EB7A57" />
        <!-- Three-state Workflow Feature -->
        <Feature ID="FDE5D850-671E-4143-950A-87B473922DC7" />
    </SiteFeatures>
    <WebFeatures>
        <!-- Custom ProjectList Feature -->
        <Feature ID="7346F629-03E1-436D-B2A2-80E2744FD8BC" />
        <!-- TeamCollab Feature -->
        <Feature ID="00BFEA71-4EA5-48D4-A4AD-7EA5C011ABE5" />
        <!-- MobilityRedirect -->
        <Feature ID="F41CC668-37E5-4743-B4A8-74D1DB3FD8A4" />
    </WebFeatures>
</Configuration>

In the Lists section, two lists are defined: a shared documents library for storing project-related documents and an instance from the project list definition built earlier in this chapter. It also references the two modules that you defined earlier.

The next step is to define which features should be used within this template. You need to specify site-scoped and web-scoped features separately. For the site-scoped features, use the basic Web Part feature and three-state workflow that comes with SharePoint and that enables basic functionalities. At the web-scoped section, you first reference the project list feature containing the list definition. The next two features are SharePoint standard elements that contain several list templates, such as custom list or calendar and the mobility redirect feature.

To create the configuration for the development environment, copy the configuration you've just built, change the configuration ID to 1, rename it to Developer, and add a bug-tracking list (issue-tracking list) to the list section (Listing 7-35).

Example 7.35. Add an Issue Tracking List in the Lists Section of onet.xml

<List FeatureId="00bfea71-5932-4f9c-ad71-1557e5751100"
      Type="1100" Title="BugTrackingList"
      Url="Lists/BugTrackingList" />

For the third configuration, you again copy the configuration for the production environment, change the configuration ID to 2, rename it to Staging, and add another list for collecting feedback (discussion board) in the staging environment (Listing 7-36).

Example 7.36. Add a Discussion Board in the Lists Section of onet.xml

<List FeatureId="00bfea71-6a49-43fa-b535-d15c05500108"
      Type="108"
      Title="Feedback"
      Url="Lists/Feedback" />

To use these configurations, you need to extend the webTempProject.xml file you specified earlier. Simply add the two extra configurations (Listing 7-37).

Example 7.37. Extend webTempProject.xml

<Templates xmlns:ows="Microsoft SharePoint">
    <Template Name="ProjectSite" ID="12099" >
        <Configuration ID="0" Title="SharePoint Project Site Production Environment" Description="" Hidden="FALSE" ImageUrl="/_layouts/images/Project/logo.bmp" DisplayCategory="CustomSharePoint" RootWebOnly="false" />
        <Configuration ID="1" Title="SharePoint Project Site Development Environment" Description="" Hidden="FALSE" ImageUrl="/_layouts/images/Project/logo.bmp" DisplayCategory="CustomSharePoint" RootWebOnly="false" />
        <Configuration ID="2" Title="SharePoint Project Site Staging Environment" Description="" Hidden="FALSE" ImageUrl="/_layouts/images/Project/logo.bmp" DisplayCategory="CustomSharePoint" RootWebOnly="false" />
    </Template>
</Templates>

As a result, you have these configurations available at the template selection box of the Create page, after deploying your solution package (see Figure 7-18).

Custom site template at the site creation page

Figure 7.18. Custom site template at the site creation page

The site definition specification in onet.xml is finished, and you can now deploy this site definition, either by pressing F5 in Visual Studio or by copying all the necessary files to the %SharePointRoot%TemplateSiteTemplates folder and recycling the application pool (IIS reset). You can now use the custom site definition.

Using a Site Definition

You have different options to create a new site from a site definition. Three of them are as follows:

  • stsadm.exe

  • SharePoint UI's Create Workspace/Site Collection

  • Custom code

stsadm.exe

You can create a new site via the stsadm.exe command-line tool by specifying, at a minimum, the Url attribute, the ownerlogin, the owneremail, and the site template to use:

STSADM.EXE -o createsite -url http://projectserver.com -ownerlogin ProjectServerpehlke -owneremail [email protected] -sitetemplate Project#0

The first part of the site template parameter refers to the template name. The number preceded by the # specifies the configuration ID.

Create Workspace or Site Collection via the UI

To create a new site from a site definition using the browser interface of SharePoint, you can use either Central Administration or the site settings of a SharePoint site.

The second option to create a site from a site definition is to use the SharePoint Create pages, like in Figure 7-19.

Note

If you don't see your template in the template selection box, you may have selected the wrong language or defined your template as RootWebOnly=true in your webTemp*.xml file.

Site creation page

Figure 7.19. Site creation page

Custom Code

You can build a console application, an application page, or even a feature that creates subsites by implementing a custom FeatureActivated event handler in a feature receiver class (or any other program code, such as a web page). A class that meets these requirements looks like Listing 7-38.

Example 7.38. Create a New Subsite

using System;
using Microsoft.SharePoint;

namespace project.feature
{
    class projectFeatureReceiver : SPFeatureReceiver
    {
        public override void FeatureActivated(SPFeatureReceiverProperties props)
        {
            using (SPWeb web = props.Feature.Parent as SPWeb)
{
                web.Webs.Add("SubSite1", "Sub Site 1", "",
                              1033, "Project#0", false, false);
            }
       }
    }
}

Summary

Using templates enables you to extend your custom solution with many features that would not be possible simply using the SharePoint UI or SharePoint Designer. These templates increase the reusability of components in your custom SharePoint applications and make them more structured.

A combination of different templates and contents such as list definitions, site definitions, Web Parts, features, images, and application pages in a custom SharePoint solution (.wsp file) can form a template for a whole SharePoint application that can be instantiated over and over again in different SharePoint environments.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.29.119