Pages

Tuesday, September 20, 2011

Create Site collection using Sharepoint Webtemplate object model

Create Sites and Site colletion using Custom Web template using object model and shrepoint web services in sharepoint 2010.


Web templates are new introduction in sharepoint 2010. But in a nutshell they are same as site template in 2007 except for the fact that Microsoft listened to all the developer community and made this change. The change is good and bad. The change that is brought into site template is now when you save the site as template it now saved into the solution gallery under site settings page as a WSP. WSP is a deployment package in sharepoint world. This solution gallery is a repository for sanboxed solutions, which implies the template that you created has now become sanboxed solution and can be used with the site collection.


Now let us talk about the good thing. The wsp can be downloaded and using the Sharepoint 2010 project template in visual studio 2010 you can import the wsp as a solution. Viola, now you can see all the information present in the template. You have access to onet.xml and element file that goes with it. There is also a feature created for you that acts as feature stapler or more like a feature that adds all the required thing to the site created out of this template.


Another very important and thoughtful idea that microsoft incorporated in web templates is you can deploy these web templates globally instead of having this as sanboxed solution. How do you do that? It is simple and straight forward. Once you download the template from solution gallery and import the wsp you can see a Site level feature is built in, you can change this feature to Farm scoped and then repackage the solution and deploy it in central admin either using Power shell or stsadm commands. If you go to create site page in central admin to create new site collection you will be able to see the newly deployed template. Now you can create site collection using this template. See how simple it is for admin or site owner to maintain the look and feel across all sites by using web templates.


How easy it is and how good the life is for creating from UI. But for the developers the life is not always smooth sailing. We updated to 2010 Sharepoint recently in our organization and we decided to use web templates. We built a site provision code that automatically provisions the site when some one submits request. There are lot of site templates that we built over years on MOSS 2007. We converted those site templates to web templates as first step. Now is the bad part of web template showed up. In our 2007 code we used to pass the name of the site template directly to create site, it worked because we were only subsites. But now since we made these web templates a Farm feature and deploy it globally the provisioning code needs to change. The problem sprang up when we provisioning the site automatically.


Code:


site.WebApplication.Sites.Add("/project/testsite", testsite,testsite 1033,"NewWebTempalte", usr.LoginName, usr.Name, usr.Email));


This code is expected to work. Here comes the bouncer. The site got created and the templates never got applied. Then changed the code to create the site with null and apply the template in object model.


Code:


using(spsite newsite = site.WebApplication.Sites.Add("/project/testsite", testsite,testsite 1033,null, usr.LoginName, usr.Name, usr.Email))
{
newsite.RootWeb.ApplyWebTemplate("NewWebTemplate");
}

This failed too. After doing some research and doing some search that takes me to no where i decided to see how the templates are stored. I found the templates are stored in the same as other WSPs are stored in database. Since I deployed globally I decided to get all the templates available in the site. To my surprise i noted that the template is available but the name of the template is not same as I thought. The name is preceded by the feature GUID.

Code:

{a0006016-915d-4008-b0f1-c25d1665ec9b}#NewWebTemplate;

This is how the name is stored. This not the name with which the template was created. After reading through some of MSDN documents i found that in 2010 since the templates are created to use in different places the name that we enter is always appended with the feature guid. so when you save it sharepoint creates a feature and appends it with the name that is entered in "Save Site as Template" page in site settings. This is what I am talking about. It is hard for a regular user to know this and when some one else creates the template and sends you then they are not going to give you the entire name including the guid. No wonder my first code and second one failed. 


Then what is the right way to get the templates and apply it. Luckily that is not a daunting tasks. You have to get all the templates and then get your template out of it. Here is snippet of code that will come handy.


Code:



using(spsite newsite = site.WebApplication.Sites.Add("/project/testsite", testsite,testsite 1033,null, usr.LoginName, usr.Name, usr.Email))
{
        SPWebTemplateCollection tempaltes = newsite.RootWeb.GetAvailableWebTemplates(1033);
       SPWebTemplate temp = (from SPWebTemplate t
                               in tempaltes
                                                                  where t.Title == "NewWebTemplate"
                                                                  select t).FirstOrDefault();

                                            newsite.RootWeb.ApplyWebTemplate(temp.Name);
    }



I am using LINQ because it is better than enumerating . Also I am using "Title" because title is what is going to contains the name that I entered in the test box.  Remember that you can enter different name and title for your templates. 

In the same way you can also use the web services to get the templates in remote servers. In case of webservices you will get an array and sent in out object.


Code:


   SharepointSiteService.Template[] templates;
                                                        siteWS.GetSiteTemplates(1033, out templates);
                                                        SharepointSiteService.Template template = (from SharepointSiteService.Template t
                                                        in templates
                                                                                                   where t.Title == FeatureConstants.Project_Template
                                                                                                   select t).FirstOrDefault();





I decided to write this down here because it may be useful to some one else as sharepoint is growing in leaps and bounds.

No comments:

Post a Comment