NAnt task for SharePoint: Save SPWeb as site template to the filesystem

I love NAnt as a tool to automate deployment processes. Kris Syverstad created a nice set of NAnt tasks for SharePoint that he uploaded to a GotDotNet workspace. My latest task was to save a site as a site template to the filesystem for deployment to another system. I decided to create a task in the same spirit to Kris his tasks. You can add it to the set of tasks that Kris already created. That is what I did.

The code:

//

// NAnt.SharePoint Microsoft Sharepoint Server utility tasks.

// Copyright (C) 2006 Macaw, Serge van den Oever

//

// This library is free software; you can redistribute it and/or

// modify it under the terms of the GNU Lesser General Public

// License as published by the Free Software Foundation; either

// version 2.1 of the License, or (at your option) any later version.

//

// This library is distributed in the hope that it will be useful,

// but WITHOUT ANY WARRANTY; without even the implied warranty of

// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU

// Lesser General Public License for more details.

//

// You should have received a copy of the GNU Lesser General Public

// License along with this library; if not, write to the Free Software

// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

//

using System;

using System.IO;

using System.Globalization;

 

using Microsoft.SharePoint;

 

using NAnt.Core;

using NAnt.Core.Attributes;

using NAnt.Core.Types;

 

namespace NAnt.SharePoint.Tasks

{

    /// <summary>

    /// Save SPWeb as template.

    /// </summary>

    /// <remarks>

    ///   <para>

    ///   Save a template of the SPWebs pecified by a Url on the local machine.

    ///   </para>

    ///   <note>

    ///   If the <see cref="Url" /> specified does not exist, a

    ///   <see cref="BuildException" /> will be raised.

    ///   </note>

    /// </remarks>

    /// <example>

    ///   <para>Delete a SPSite.</para>

    ///   <code>

    ///    <![CDATA[

    /// <deletespsite Url="http://myserver/sites/mysite" />

    ///    ]]>

    ///   </code>

    /// </example>

    /// <example>

    ///   <para>

    ///   Save SPWeb as template. If the SPWeb does not exist, the task does nothing.

    ///   </para>

    ///   <code>

    ///    <![CDATA[

    /// <savespwebastemplate url="${url}" templatename="myTemplate" title="My Template" description="A Template Of My Site" savedata="true" tofile="c:\template.stp" failonerror="false" />

    ///    ]]>

    ///   </code>

    /// </example>

    [TaskName("savespwebastemplate")]

    public class SaveSPWebAsTemplateTask : Task

    {

 

        private string _url = "";

        private string _templatename = "";

        private string _title = "";

        private string _description = "";

        private bool _savedata = false;

        private string _tofile = null;

 

        /// <summary>

        /// The URL for the SPWeb to save as template.

        /// </summary>

        [TaskAttribute("url", Required = true)]

        public string Url

        {

            get { return _url; }

            set { _url = value; }

        }

 

        /// <summary>

        /// The name for the template.

        /// </summary>

        [TaskAttribute("templatename", Required = true)]

        public string TemplateName

        {

            get { return _templatename; }

            set { _templatename = value; }

        }

 

        /// <summary>

        /// The title for the template.

        /// </summary>

        [TaskAttribute("title", Required = false)]

        public string Title

        {

            get { return _title; }

            set { _title = value; }

        }

 

        /// <summary>

        /// The description for the template.

        /// </summary>

        [TaskAttribute("description", Required = false)]

        public string Description

        {

            get { return _description; }

            set { _description = value; }

        }

 

        /// <summary>

        /// Boolean specifying if data of the SPWeb should be included in the template.

        /// Only data up to 10Mb can be included.

        /// </summary>

        [TaskAttribute("savedata", Required = false)]

        public bool SaveData

        {

            get { return _savedata; }

            set { _savedata = value; }

        }

 

        /// <summary>

        /// The file to save the template to.

        /// </summary>

        [TaskAttribute("tofile", Required = false)]

        public string ToFile

        {

            get { return _tofile; }

            set { _tofile = value; }

        }

 

        /// <summary>

        /// Because ExecuteTask is protected added this function to debug the task.

        /// </summary>

        public void DebugTask()

        {

            ExecuteTask();

        }

 

        /// <summary>

        /// Task for saving a SPWeb as template.

        /// </summary>

        protected override void ExecuteTask()

        {

            string templateFilename = TemplateName + ".stp";

            try

            {

                using (SPSite site = new SPSite(Url))

                {

                    try

                    {

                        using (SPWeb web = site.OpenWeb(site.ServerRelativeUrl))

                        {

                            // Delete site template with name TemplateName if it exists

                            SPDocumentLibrary webTemplates;

                            try

                            {

                                webTemplates = site.GetCatalog(SPListTemplateType.WebTemplateCatalog) as SPDocumentLibrary;

                            }

                            catch (Exception ex)

                            {

                                throw new BuildException(

                                    string.Format("The site collection of the SPWeb '{0}' does not contain a Site Template Gallery.",

                                    Url), Location, ex);

                            }

                            SPFolder folder = web.Folders["_catalogs"];

                            SPFolder subfolder = folder.SubFolders["wt"];

                            subfolder.Files.Delete(templateFilename);

                        }

                    }

                    catch (Exception)

                    {

                        // ignore, no template to delete

                    }

 

                    // Save the SPWeb as template

                    using (SPWeb web = site.OpenWeb())

                    {

                        // If no title is specified, use same as template name

                        if (Title.Length == 0)

                        {

                            Title = TemplateName;

                        }

 

                        web.SaveAsTemplate(templateFilename, Title, Description, SaveData);

                    }

                }

 

                Log(Level.Info, LogPrefix + "Save SPWeb '{0}' as template with name '{1}'.", Url, TemplateName);

            }

            catch (Exception ex)

            {

                // The SPS API will throw an exception when you try and create an

                // instance of SPSite for a URL that doesn't exist. 

                throw new BuildException(

                    string.Format("Cannot save SPWeb '{0}' as template. Either the SPWeb does not exist, or savedata is true and the size of the SPWeb > 10MB, or there is already a template by this name.",

                    Url), Location, ex);

            }

 

            if (ToFile != null)

            {

                try

                {

                    using (SPSite site = new SPSite(Url))

                    {

                        string templateUrl = site.Url + "/_catalogs/wt/" + templateFilename;

                        System.Net.WebClient objWebClient = new System.Net.WebClient();

                        objWebClient.Credentials = System.Net.CredentialCache.DefaultCredentials;

                        objWebClient.DownloadFile(templateUrl, ToFile);

                    }

                }

                catch(Exception ex)

                {

                    throw new BuildException(

                        string.Format("The SPWeb '{0}' is saved as template '{1}' in the Site Template Gallery, but downloading the template to file '{2}' failed.",

                        Url, Name, ToFile), Location, ex);

                }

            }

        }

    }

}

Published Wednesday, June 28, 2006 12:06 AM by svdoever
Filed under:

Comments

Friday, May 04, 2007 8:48 AM by Richa

# NAnt Script for compiling Deployment projects

Plz tell me what other than NAnt Compiler must be present on the system for compiling Deployment Projects using NAnt Scripts

Friday, May 04, 2007 8:52 AM by svdoever

# re: NAnt task for SharePoint: Save SPWeb as site template to the filesystem

Hi Richa, you need visual studio!! Or the .Net SDK and compile manually.

Wednesday, February 20, 2008 8:34 AM by Sander's Blog

# Programmatically Add/Remove Site Templates in the Site Gallery

Took me a while to find out how to connect to the Site Gallery, so this might save you some time. .csharpcode

Wednesday, February 20, 2008 12:06 PM by SHAREPOINTBlogs.com Mirror

# Programmatically Add/Remove Site Templates in the Site Gallery

Took me a while to find out how to connect to the Site Gallery, so this might save you some time. using

Leave a Comment

(required) 
(required) 
(optional)
(required)