none
How to Custom Site Template in SharePoint O365? RRS feed

  • Question

  • Hi,

    I have a requirement to create a custom Team Site Template with my own list and libraries and given master page. 

    Is it possible to do this in SharePoint O365? If so, How to do that and what are the best practices i have to follow?

    Thank you !

    Wednesday, January 7, 2015 6:23 PM

Answers

  • Few pointers. Site templates are indeed still supported in the Office 365, they might though bite you with the future updates.

    Infinite loop you get in Azure, but not with F5 is caused by time out in the process, which for Azure web sites is 1 minute and you can't increase that. What you can do however is use WebJobs or other

    Here's Office 365 Developer Patterns and Practices sample for async site collection creation - https://github.com/OfficeDev/PnP/tree/master/Samples/Provisioning.Cloud.Async . Smoothest model most likely would be to use Azure storage queues for request queue and then process those using WebJob. This unfortunately not yet shown with PnP samples.

    If you have any questions related on the Office 365 Dev PnP, we would suggest to use the Office 365 Dev PnP Yammer group where we have close to 1500 members from community with active assistance on any issues. Easiest way to access the group is following address: http://aka.ms/officedevpnpyammer

    SPMeta2 is also great community driven library for CSOM operations.

    Best Regards,
    Vesa Juvonen

    Monday, January 12, 2015 7:42 PM

All replies

  • You can't deploy site templates  to the Office 365, so you have to use templates that they offer you for site-collection creation.

    But we can use Remote provisioning in which we do the template system outside of the SharePoint by using the new SharePoint app patterns. In this case we would be using provider hosted pattern to provide customizable sub site creation experience for the end users of the SharePoint.

    This link may help you

    https://newsignature.com/articles/feature-stapling-with-sharepoint-online-kind-of

    http://blogs.msdn.com/b/vesku/archive/2013/09/09/sharepoint-2013-site-provisioning-techniques-presentation-video-recording.aspx

    http://blogs.msdn.com/b/richard_dizeregas_blog/archive/2013/04/04/self-service-site-provisioning-using-apps-for-sharepoint-2013.aspx

    Thursday, January 8, 2015 7:27 AM
  • Hi,

    Thank you for the useful links.

    Im able to deploy this(https://github.com/OfficeDev/PnP/tree/master/Samples/Provisioning.SiteCollectionCreation) in SPO and able to create SiteCollections. One issue is after clicking on Create button the page goes in infinite loop and gets stuck in "Really working on it...". I verified in another tab, the site collection is created and working fine, but the page never redirects to new site.

    But when i debug with F5 its working fine. The problem is only at the app level. 

    This is the code i am using. Any Idea?

    using Microsoft.Online.SharePoint.TenantAdministration;
    using Microsoft.SharePoint.Client;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    namespace SPRIDERSSPWeb
    {
        public partial class Default : System.Web.UI.Page
        {
            protected void Page_PreInit(object sender, EventArgs e)
            {
                Uri redirectUrl;
                switch (SharePointContextProvider.CheckRedirectionStatus(Context, out redirectUrl))
                {
                    case RedirectionStatus.Ok:
                        return;
                    case RedirectionStatus.ShouldRedirect:
                        Response.Redirect(redirectUrl.AbsoluteUri, endResponse: true);
                        break;
                    case RedirectionStatus.CanNotRedirect:
                        Response.Write("An error occurred while processing your request.");
                        Response.End();
                        break;
                }
            }

            protected void Page_Load(object sender, EventArgs e)
            {
                // define initial script, needed to render the chrome control
                string script = @"
                function chromeLoaded() {
                    $('body').show();
                }

                //function callback to render chrome after SP.UI.Controls.js loads
                function renderSPChrome() {
                    //Set the chrome options for launching Help, Account, and Contact pages
                    var options = {
                        'appTitle': document.title,
                        'onCssLoaded': 'chromeLoaded()'
                    };

                    //Load the Chrome Control in the divSPChrome element of the page
                    var chromeNavigation = new SP.UI.Controls.Navigation('divSPChrome', options);
                    chromeNavigation.setVisible(true);
                }";

                //register script in page
                Page.ClientScript.RegisterClientScriptBlock(typeof(Default), "BasePageScript", script, true);


                listSites.Items.Add(new System.Web.UI.WebControls.ListItem("Team", "STS#0"));
                listSites.Items.Add(new System.Web.UI.WebControls.ListItem("Super Team", "STS#0"));
                listSites.Items.Add(new System.Web.UI.WebControls.ListItem("Über Team", "STS#0"));
                listSites.SelectedIndex = 0;

                lblBasePath.Text = Request["SPHostUrl"].Substring(0, 8 + Request["SPHostUrl"].Substring(8).IndexOf("/")) + "/";
            }

            protected void btnCreate_Click(object sender, EventArgs e)
            {
                var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);
                string newWebUrl = string.Empty;
                using (ClientContext ctx = spContext.CreateUserClientContextForSPHost())
                {
                    newWebUrl = CreateSiteCollection(ctx, Page.Request["SPHostUrl"], txtUrl.Text,
                                                    listSites.SelectedValue, txtTitle.Text, txtDescription.Text);
                }


                Response.Redirect(newWebUrl);
            }

            protected void btnCancel_Click(object sender, EventArgs e)
            {
                Response.Redirect(Page.Request["SPHostUrl"]);
            }

            private string CreateSiteCollection(ClientContext ctx, string hostWebUrl, string url, string template, string title, string description)
            {
                //get the base tenant admin urls
                var tenantStr = hostWebUrl.ToLower().Replace("-my", "").Substring(8);
                tenantStr = tenantStr.Substring(0, tenantStr.IndexOf("."));

                //get the current user to set as owner
                var currUser = ctx.Web.CurrentUser;
                ctx.Load(currUser);
                ctx.ExecuteQuery();

                //create site collection using the Tenant object
                var webUrl = String.Format("https://{0}.sharepoint.com/{1}/{2}", tenantStr, "sites", url);
                var tenantAdminUri = new Uri(String.Format("https://{0}-admin.sharepoint.com", tenantStr));
                string realm = TokenHelper.GetRealmFromTargetUrl(tenantAdminUri);
                var token = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, tenantAdminUri.Authority, realm).AccessToken;
                using (var adminContext = TokenHelper.GetClientContextWithAccessToken(tenantAdminUri.ToString(), token))
                {
                    var tenant = new Tenant(adminContext);
                    var properties = new SiteCreationProperties()
                    {
                        Url = webUrl,
                        Owner = currUser.Email,
                        Title = title,
                        Template = template,
                        StorageMaximumLevel = 100,
                        UserCodeMaximumLevel = 100
                    };

                    //start the SPO operation to create the site
                    SpoOperation op = tenant.CreateSite(properties);
                    adminContext.Load(tenant);
                    adminContext.Load(op, i => i.IsComplete);
                    adminContext.ExecuteQuery();
                   
                    //check if site creation operation is complete
                    while (!op.IsComplete)
                    {
                        // wait 30seconds and try again
                        // System.Threading.Thread.Sleep(30000);
                        op.RefreshLoad();
                        adminContext.ExecuteQuery();

                    }                
                }

               
                //get the new site collection
                var siteUri = new Uri(webUrl);
                token = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, siteUri.Authority, realm).AccessToken;
                using (var newWebContext = TokenHelper.GetClientContextWithAccessToken(siteUri.ToString(), token))
                {
                    var newWeb = newWebContext.Web;
                    newWebContext.Load(newWeb);
                    newWebContext.ExecuteQuery();

                    new LabHelper().SetThemeBasedOnName(newWebContext, newWeb, newWeb, "Orange");

                    // All done, let's return the newly created site
                    return newWeb.Url;
                }
                
                

            }
        }
    }





    Sunday, January 11, 2015 2:21 AM
  • Although not recommended (deprecated feature) you can still use Sandboxed solutions with webtemplates.

    A more recommended solution is remote provisioning. It will have a learning curve but we have goed experiences with provisioning new sites with https://github.com/SubPointSolutions/spmeta2

    Monday, January 12, 2015 10:00 AM
  • Few pointers. Site templates are indeed still supported in the Office 365, they might though bite you with the future updates.

    Infinite loop you get in Azure, but not with F5 is caused by time out in the process, which for Azure web sites is 1 minute and you can't increase that. What you can do however is use WebJobs or other

    Here's Office 365 Developer Patterns and Practices sample for async site collection creation - https://github.com/OfficeDev/PnP/tree/master/Samples/Provisioning.Cloud.Async . Smoothest model most likely would be to use Azure storage queues for request queue and then process those using WebJob. This unfortunately not yet shown with PnP samples.

    If you have any questions related on the Office 365 Dev PnP, we would suggest to use the Office 365 Dev PnP Yammer group where we have close to 1500 members from community with active assistance on any issues. Easiest way to access the group is following address: http://aka.ms/officedevpnpyammer

    SPMeta2 is also great community driven library for CSOM operations.

    Best Regards,
    Vesa Juvonen

    Monday, January 12, 2015 7:42 PM
  • Your video helped to understand 100% on this. Thank you for sharing  

    https://www.youtube.com/watch?v=GbYzzubLGEI 


    Monday, January 12, 2015 8:31 PM
  • Ran across this post while looking. Just wanted to say YES it is possible, however note that custom security does not carry over but that is the same on Prem.

    For online, the initial part is the same. Create your Site like you want it and via Site --> Settings, select the Create Template. Once done, click on the FileName and it will download to your computer.

    Then, go into your SharePoint Admin and select to create a new site. In the Template box, click on the Custom tab and select  the "I'll decide later option".

    When the site has been created and you go to it, it will present you with a "Pick your Template". On that page their will be a link for the "Gallery". Click that link and UPLOAD + ACTIVATE your Template file. 

    Then go back to that "Pick your Template", click on the Custom Tab (you may have to refresh the page) and your new Template should show up. .. Go from there.



    Thursday, June 23, 2016 7:40 PM
  • Hi,

    I have just tried this method but I keep getting an Error  at the final step which says I should troubleshoot in SharePoint Foundation. After this the site cannot be found when I click on the link to it from SharePoint Admin in O365. Any ideas?

    Thanks!

    Monday, March 13, 2017 1:15 PM