Sunday, June 24, 2012

Site Provision/Site definitions /List Definition


http://mymemorysucks.wordpress.com/2009/02/25/site-definitions-vs-site-templates-and-site-provisioning-providers/

Site Def:
All the code and the pages that are used to administer and render the SharePoint site are stored as physical files on the web server. A site definition exists as physical files on the web server and defines, through the use of SharePoint’s XML schema (known as CAML), the lists, columns, features etc. that should be created/activated when a site is created.


Site Template
The point to remember though is the out-of-the-box site types provided by Microsoft, such as the Blank Site, Team Site, Blog etc., are also site definitions with XML files and all that stuff (you can go visit the entire family in %Program Files%\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates).

If you create a site template based off an out-of-the-box site definition it means that you can easily take that site
template to another completely different SharePoint installation and, more likely than not, will be able to load it and create sites from it. This in fact is cited as being one of the big wins for using a site template. Deployment can be done by fairly low level admin access and doesn’t require involvement from farm administrators (generally the IT department/infrastructure nerds).

The Problems With Site Definitions
Site definition once deployed and in use on a SharePoint installation can’t be modified. Any attempts to add to the site definition is going to result in breaking the current sites that have been created from the current site definition. What this means is that if you do intend to use a site definition, you better be pretty damn sure that when you deploy it for use, thats the final version and you’ll never need to update it again.

The Problems With Site Templates
So after hearing how restrictive site definitions are you’re probably thinking “problem solved… I’ll use site templates” but there are problems with using that too. The greatest argument in the case for site templates, their simplicity, is also their greatest weakness… they are too simple. Their simplicity causes them to be less efficient, can’t be feature stapled (another post for another day) and as they are not created within a development environment make them hard to debug for a developer, if problems arise.


If you have a situation where the site definition will not change e.g. a SharePoint product for sale, then I’d say to use a site definition. If you are developing in-house templates that will be added to by end users and you’ll be forever upgrading the site, then use a site template. With both these options in mind there is a third solution that can provide a solution to the weaknesses of both situations and is a sort of hybrid of the two.


Site Provisioning
“Site provisioning… whats that?” I hear you say through the electronic ether. Provisioning a site is a fancy way of
saying “creating a site”.
A site provisioning provider is a piece of code that is run by a site definition when a new site is created. By default SharePoint performs the provisioning actions of a new site. These actions can include creation of lists, activation of features etc. and, most importantly, telling the site which site definition it should be based off. This is important because by declaring the site definition to base the site off you inevitably bind the site to that site definition.

1.Allow Site Administrators to create a site using the out of the box site creation screens
2.Support Feature Stapling for future updates
3.Create no dependencies on the SharePoint Farm:
   The Site "Template" can be removed at any time without affecting previously created sites
    Minimal impact projected during future platform upgrades


If you implement your own class that inherits from SPWebProvisioningProvider, you can use it to call the ApplyWebTemplate method of a Web which allows you to manually provision one of the out of the box Site Definitions!  That means you get our unique Site Template Name but when the site is created it THINKS it is an out of the box Site Definition!

1.Create the webtemp*.xml (using the ProvisionAssembly and ProvisionClass attributes):

2.Create the Provisioning Provider (which applies the "Blank Site" Site Definition):

3.Create any Feature Receivers and Feature Staplers

4.Wrap everything into a SharePoint Solution and you're done!

You decide to use Feature Stapling and to implement your site customizations as custom code wrapped in a Feature Receiver.

Post-Deployment you can make updates by updating your Feature Receiver or the code in your provisioning provider.  Also, if you're done making sites of that type, go ahead and uninstall your SharePoint Solution: Your sites were created using out of the box Site Definitions so there is no leftover dependency.


Site provision handler.


http://www.codeproject.com/Articles/185209/SharePoint-Custom-Provisioning-Provider?display=Print

using vS2010 site definition project.
http://msdn.microsoft.com/en-us/library/gg276356.aspx

http://msdn.microsoft.com/en-us/library/gg276356.aspx
The new recommended method for providing a mechanism to create a new site is to use a custom Site Provisioning Provider.


The first thing we need of course is to create a new Empty SharePoint 2010 project in Visual Studio. Then, add a code file to this project and derive it from SPWebProvisioningProvider. This base class has one method that needs to be implemented, Provision:




public class CPSiteProvider : SPWebProvisioningProvider
{
public override void Provision(SPWebProvisioningProperties props)
{
throw new NotImplementedException();
}
}
Of course, whether using a Site Definition or a custom provisioning provider such as this, there must be a webtemp* file so SharePoint can recognize and make the template available. More information about the details of this file can be found here. For this discussion however, the key points are the attributes ProvisioningAssembly, ProvisioningClass and ProvisionData:version="1.0" encoding="utf-8" ?>
  <Templates> 
 <Template Name="CPSiteProvider" ID="25001"> 
 <Configuration 
 ID="0"  
Title="Code Project Site Provisioning Provider"  
Hidden="false"  
ImageUrl="/_layouts/images/CPSiteProvider/CP_Logo.gif"  
Description="A demonstration or using a custom Site Provisioning Provider"  
DisplayCategory="Code Project" 
 ProvisionAssembly="$SharePoint.Project.AssemblyFullName$" ProvisionClass="CPSiteProvider.ProvisioningProvider" 
 ProvisionData="TEMPLATE\FEATURES\ CPSiteProvider_SiteData\ProvisioningData\CPSiteProvider.xml" SubWebOnly="TRUE">  
Configuration> Template> Templates>
For ProvisioningAssembly, we'll just make use of the built-in Visual Studio macro which will expand to the proper four-part entry when the project is built. The ProvisioningClass is the fully qualified name of the class that implements SPWebProvisioningProvider, which in our case is ProvisioningProvider. The ProvisionData attribute is used to specify any extra data that is need by the Provisioning Provider. In this case I am using the path, relative to the SharePoint root folder, of an XML file that will contain additional information.

The Provisioning Provider is a blank slate and will not create anything unless it is told to. With that in mind, the first we'll do is to use the ApplyWebTemplate method of the SPWeb object to create a blank site to start with. As you can see, web is one of the properties available from the SPWebProvisioningProperties property passed into the Provision method. The other property is Data which will contain the value of the ProvisionData attribute specified in the webtemp file which we'll make use of next.



private const string SITE_TEMPLATE = "STS#1";
public override void Provision(SPWebProvisioningProperties props)
{
// Create a blank site to begin from
props.Web.ApplyWebTemplate(SITE_TEMPLATE);
}
Now that the basic site has been created, we'll add the features required to configure our site appropriately.


public override void Provision(SPWebProvisioningProperties props)
{
// Create a blank site to begin from
props.Web.ApplyWebTemplate(SITE_TEMPLATE);
// Save this so it is available in other methods
Properties = props;
SPSecurity.CodeToRunElevated code =new SPSecurity.CodeToRunElevated(CreateSite);
SPSecurity.RunWithElevatedPrivileges(code);
}
private void CreateSite()
{
using(SPSite site = new SPSite(Properties.Web.Site.ID))
{
using(SPWeb web = site.OpenWeb(Properties.Web.ID))
{
// Add specified features to this site
AddSiteFeatures(site);
// Add specified features to this web
AddWebFeatures(web);
// Add new default page
AddDefaultPage(web);
}
}
}

Since site could be created by anyone, we need to ensure the proper security privileges are available, this is where SPSecurity.RunWithElevatedPrivileges is useful. This will have any code that is run in its context to be executed with the credentials of the Web Application AppPool. Although you could use an anonymous delegate with this method, for readability and maintainability, I'll use create a SPSecurity.CodeToRunElevated object and assign a method to run. One minor issue with this is the delegate for this method takes no parameters. To be able to have access to the SPWebProvisioningProperties, I'll assign it to private property.



In the AddSiteFeatures method, the first thing to do it is access the XML file that contains the features we want to enable in this site. Since the path was relative, we need to get to the SharePoint root folder. Although it is typically %Program Files%\Common Files\Microsoft Shared\Web Server Extensions\14 as good developers, we can't rely on this and should specifically query the object model for the correct path. This is done in the DataFile property using the SPUtility.GetGenericSetupPath method.



private void AddSiteFeatures(SPSite site)
{
List features = (from f in DataFile.Elements("SiteFeatures") .Elements("Feature")
select f).ToList();
foreach(XElement feature in features)
 {// Make sure the feature hasn't already been activated
 SPFeature f = site.Features[new Guid(feature.Attribute("ID").Value)];
 if(f == null)
{ site.Features.Add(new Guid(feature.Attribute("ID").Value)); }
}
 private XElement DataFile { get
{ XElement featuresXml = null;
 if(Properties != null) {
// Construct the path from the SharePoint root folder to
// the file specified in the webtemp
string path = SPUtility.GetGenericSetupPath
(Path.GetDirectoryName(Properties.Data));
path = Path.Combine(path, Path.GetFileName(Properties.Data));
// Load the xml file
featuresXml = XElement.Load(path);
}
return featuresXml;
} }

After getting the XML file, it is simply a matter of adding the specified features to either the Site or Web. I have used the same features as the Site Definition project to make it comparable, but you can add any other features that are required. Any lists or other items can also be added to the site at this point.



The benefit to this method is the site is not created until runtime and is independent of files in the file system unlike the Site Definition method. To get an apples to apples comparison, we need to include the default.aspx page.



private void AddDefaultPage(SPWeb web)

{
string file = (from f in DataFile.Elements("DefaultPage")
select f).Single().Attribute("file").Value;
string filePath = FeaturePath + "\\" + file;
TextReader reader = new StreamReader(filePath);
MemoryStream outStream = new MemoryStream();
StreamWriter writer = new StreamWriter(outStream);
writer.Write(reader.ReadToEnd());
writer.Flush();
web.Files.Add("Default.aspx", outStream, true);
}

As you see here, we extract the path to the Default.aspx page that will be used from the provisioning file, then read the contents of the file into a Stream and write it back into a StreamWriter. Using true in the SPWeb.Files.Add method will allow the existing Default.aspx page to be overwritten by our new file. Since this causes the page to be added to the content database, it is now unghosted and thus independent of the file in the file system.



You can test this process in the same way as before. Create a new site based on this template. Update the default.aspx page in the Visual Studio project and redeploy the solution. If you refresh the page, you will not see any changes. If you create a new site, the modified default.aspx page will then be used.


=================================


Use feature-stapling to associate your features to the site definition
This option should be used when the site definition is already in use (and sites have been created). This is because there are risks in modifying a site definition once it has been deployed, since the site definition files on the filesystem are used for pages which are ghosted (not modified).
To use feature-stapling, you first need the feature(s) you wish to link to the site definition - these should be created in the normal way. The, you should create a 2nd feature which does the actual stapling. Sample values for the various files are shown below:
The manifest.xml file if you are wrapping your feature in a solution:
xml version="1.0" encoding="utf-8"?>
<Solution xmlns="http://schemas.microsoft.com/sharepoint/" SolutionId="26E1A1D9-7BB2-4e76-888E-B20184B16E3B">
  <FeatureManifests>
    <FeatureManifest Location="COB.Demos.FeatureStapling\feature.xml" />
  FeatureManifests>
Solution>
The feature.xml file which defines the feature 'header' information:
xml version="1.0" encoding="utf-8" ?>
<Feature Id="4AF9999A-0517-4224-9ED3-D2F9F87D92E2"
        Title="COB.Demos.FeatureStapling"
        Description="Staples a set of features to custom site definitions. The features/site definitions are defined in stapling.xml."
        Version="1.0.0.0"
        Scope="Farm"
        Hidden="FALSE"
        xmlns="http://schemas.microsoft.com/sharepoint/">
  <ElementManifests>
    <ElementManifest Location="stapling.xml" />
ElementManifests>
Feature>

And finally, the core feature definition in the stapling.xml file:

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <FeatureSiteTemplateAssociation Id="F6924D36-2FA8-4f0b-B16D-06B7250180FA" TemplateName="MySiteDefName#0" />
  <FeatureSiteTemplateAssociation Id="94C94CA6-B32F-4da9-A9E3-1F3D343D7ECB" TemplateName="MySiteDefName#0" />
  <FeatureSiteTemplateAssociation Id="02464C6A-9D07-4F30-BA04-E9035CF54392" TemplateName="MySiteDefName#0" />
Elements>


The FeatureSiteTemplateAssociation element maps feature GUIDs to site defintions - note that the format of the TemplateName attribute value is #. This obviously allows a degree of flexibility and allows you to do fairly complex things with different configurations of site definitions.

The final thing to note is that feature-stapling won't affect any sites which have already been created from a site definition, only subsequent sites. The only way to do this is to activate your features individually on the site, though obviously an STSADM script can help you activate multiple features against multiple sites.






================================= 



Site Template
The first option for getting the SharePoint Designer changes beyond the current site is to take the site you've modified with SharePoint designer and save it as a template. Then when you need a new site you create it from the site template you've created. This approach works but it means that you either have to create a new site template for each of the built in site definitions -- or you have to live with just the one site template that you've created. It also means that you can't go back and apply the changes after they've been created.
Finally, to add insult to injury, if you ever change the work that you did on the original site those changes won't be reflected across the other SharePoint sites that were created from the template because each page exists separately in the database. So site templates solve the problem of getting SharePoint Designer changes into multiple sites but without the ability to adapt to changes in the future.


Site Definitions
solve the problem of site templates in that changes can be affected to them after they've been created -- but at the cost of additional work. Site definitions exist on the file system of each of the front end web server unlike site templates which exist in the content database. Each site which is created from the site definition doesn't make a copy of the page in the database, instead it stores a pointer to the site definition file. The good news is that when the page on the file system changes it changes all of the references in the database -- thus solving the problem of making changes to existing branding.
In order to do a site definition, you'll first have to get the changes to the files that you want into files. You can do this from SharePoint Designer by selecting Save As and pointing to a directory. From there you have to create the support files for the site definition including the ONET.XML file which drives how the site definition is used, and the WEBTEMP*.XML file which makes the site definition show up as an option. In most cases you'll copy the STS site definition that comes with SharePoint and make your changes there rather than starting from scratch.


http://msdn.microsoft.com/en-us/library/aa979709(v=office.12).aspx
A custom template is a customization applied to a site or list definition.

Site definitions :
----------------

Site definitions consist primarily of
multiple XML and
ASPX files stored on a front-end Web server in folders under the
\\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE directory.
In Windows SharePoint Services 3.0, a SharePoint site definition is basically transformed into a
Site definition
--list of Features plus a
--layout page
--and a master page.
The goal is that any templated SharePoint site can be transformed by an administrator into another templated SharePoint site simply by toggling Features on the site and possibly switching the layout page or master page.
List TemplatesList templates contain the
--files,
--views,
--fields,
--Web Parts, and, optionally,
--the content that is associated with a list.

Users create list templates on the Save as Template page for a list, or through code that uses the SaveAsTemplate method of the Microsoft.SharePoint.SPList class. When saved, list templates are stored in the List Template gallery of the top-level site in a site collection. They are available to all sites in the site collection that derive from the same site definition and language as the site on which the list was originally created. To make a list template available to a site in another site collection, download the template from its current gallery and then upload it to the gallery of the new site collection.

Similar to list templates, site templates can be downloaded and moved to other site collection galleries.
Unlike list templates, however, site templates can also be moved into the Central Site Template gallery, where they become available for top-level site creation in Self-Service Site Creation in addition to subsite creation.

The following are the prominent XML files that govern the structure and content of a site definition.

  • WebTemp*.xml Files
  • Identify the site definitions and configurations and provide information about how they appear in the user interface (UI) to users who are creating new websites.
  • Location: %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\1033\XML
  • Onet.xml Files
  • Define the navigation areas, specify the list definitions available in the UI, specify document templates and their files, define the base types for lists, and define configurations and modules for site definitions.
  • Location: %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\SiteDefinitions\site_type\XML
  • In addition, Onet.xml uses Configuration elements to define the site definition configurations in a site definition (such as STS and BLOG) and Module elements to define the modules in each site definition configuration. For more information about modules, see How to: Provision a File.


But such a site definition is really a family of one or more site definition configurations, each of which is represented by one of Template element's child elements. Details of the configuration are stored in a corresponding element in the ONET.xml file.
By contrast, a custom site template is stored as a .stp file in the SharePoint database and is listed in the site templates gallery for the site. You can copy the file to a folder, change its extension to ".cab", and open it.

===========================================================================
Deciding Between List Definitions and List Templates
Custom list definitions hold the following advantages over list templates:

·         Data is stored directly on the Web servers, so performance is typically better.
·         A higher level of list customization is possible through direct editing of a Schema.xml file.
·         Certain kinds of customization to lists require use of site and list definitions.

List definition disadvantages include the following:
·         Customization of list definition requires more effort than configuring list templates.
·         Editing a list definition after it has been deployed is difficult.
·         Doing anything other than adding code can break existing sites.
·         Customizing list definitions requires access to the file system of the front-end Web server.

List templates hold the following advantages over customization of list definitions:
·         List templates are easy to create.
·         Almost anything that can be done in the user interface can be preserved in the template.
·         List templates can be modified without affecting existing sites that have been created from the templates.
·         List templates are easy to deploy.

List template disadvantages include the following:
·         List templates are not created in a development environment.
·         List templates are less efficient in large-scale environments.
·         If the List definition on which the list template is based does not exist on the front-end server or servers, the list template does not work.

1 comment:

  1. The site definition files are located in the WFE servers whereas the site templates are located in the content databases.
    Site definitions once deployed and then changed will wreck all the existing sites that have used the same.Hence it is advised to use Site Provisioning,This way the site created in run time and the required features are added to the same using Feature Receivers.
    The other part is that once deployed we will have to use the Feature Stapling to add the features to the same.This style won't affect any sites which have already been created from a site definition, only subsequent sites


    ReplyDelete