Customize SharePoint Online Site Template

 SharePoint Online Site Design (renamed as Site Template) and site scripts used to automate modern SharePoint sites provisioning with your own custom or pre-defined set of actions and configurations.



Site Template can be applied (Navigate to Site Collection -> Settings -> Apply a Site Template),


Once the user clicks to "Apply a Site Template", select a template that shows two options,

1. From Microsoft -> It shows the template from the lookbook (https://lookbook.microsoft.com/). Site Template appears differently as per Communication Site or Modern Teams Site Collection.

2. From your organization -> It shows all custom-designed Site Template.


Let's get started with customize Site Template,

Scenario

In an organization, when people want to apply department or business unit specific defined "Site Template" to newly created or existing Modern Site Collection, it assists to maintain the consistency across the site collection with respect to theme, schema, master data, association with hub sites as well as security. It's quite useful, you need to push the Site Collection level changes as Site Template to existing Site Collection with never version of Site Scripts & Site Template (which consists of a pre-defined set of activities and configurations).

For example, IT Department people create a new Site Collection for each and every project, Once it is created with OOTB templates like Communication or Teams Site Template, Customize designed Site Template can be applied to maintain consistency with the look and feel, schema, permission, etc. In the future, if you want to release new changes to the Site Template, the user can release a new version of the Site Template associated with scripts and make it available. It can be easily available to the site owners to apply or update the existing sites.


SharePoint online site Template is used to apply configurations or actions to existing modern sites, like,

  • Create additional list
  • Apply a theme
  • Join a hub site etc.

There are almost 300 actions or 100,000 characters that can be bumped into site scripts. A site design can be associate with one or more associated site scripts. Site Scripts are JSON files that contain the ordered list of actions that will apply the custom configurations (ex. creating a list, joining a hub site, etc.) onto the new or existing created site.

Generate Site Scripts

Site Scripts is a collection of actions and sub-actions such as creating a list, site column, content type, theme. Each action is specified as "Verb". Verb actions run in the order they specified or appear in JSON script. Check out the JSON Schema for all actions available.

Site Script sample can be downloaded from Github to re-use into your own scripts.

Below scripts have reference to create Site Column, Site Content-Type, SP List, Data Column Formation, and add navigation.

{
    "$schema": "https://developer.microsoft.com/json-schemas/sp/site-design-script-actions.schema.json",
    "actions": [

{
    "verb": "createSiteColumnXml",
    "schemaXml": "<Field Type=\"Choice\" DisplayName=\"Project Status\" Required=\"FALSE\" Format=\"Dropdown\" StaticName=\"ProjectStatus\" Name=\"ProjectStatus\"><Default>In Progress</Default><CHOICES><CHOICE>In Progress</CHOICE><CHOICE>In Review</CHOICE><CHOICE>Done</CHOICE><CHOICE>Has Issues</CHOICE></CHOICES></Field>"
},
{
    "verb": "createSiteColumnXml",
    "schemaXml": "<Field Type=\"Choice\" DisplayName=\"Project Category\" Required=\"FALSE\" Format=\"Dropdown\" StaticName=\"ProjectCategory\" Name=\"ProjectCategory\"><Default>Operations</Default><CHOICES><CHOICE>Operations</CHOICE><CHOICE>IT</CHOICE><CHOICE>Legal</CHOICE><CHOICE>Engineering</CHOICE><CHOICE>HR</CHOICE><CHOICE>Services</CHOICE><CHOICE>Consulting</CHOICE></CHOICES></Field>"
},
{
  "verb": "createContentType",
  "name": "ContosoProjects",
  "id": "0x0100B609FEFDEFAA484299C6DE254182E666",
  "description": "custom list content type",
  "parentId": "0x01",
  "hidden": false,
  "subactions": [
    {
      "verb": "addSiteColumn",
      "internalName": "ProjectStatus"
    },
    {
      "verb": "addSiteColumn",
      "internalName": "ProjectCategory"
    }
  ]
},
{
  "verb": "createSPList",
  "listName": "Project Tracker",
  "templateType": 100,
  "subactions": [
    {
      "verb": "addContentType",
      "name": "ContosoProjects"
    },
    {
      "verb": "addSPFieldXml",
      "schemaXml": "<Field DisplayName=\"Project Progress\" Percentage=\"FALSE\" Title=\"Project Progress\" Type=\"Number\" ID=\"{1a2f5cd6-3734-4afa-927d-bd11d38e78a4}\" StaticName=\"ProjectProgress\" Name=\"ProjectProgress\" />"
    },
    {
        "verb": "setSPFieldCustomFormatter",
        "fieldDisplayName": "Project Status",
        "formatterJSON": {
            "$schema": "http://columnformatting.sharepointpnp.com/columnFormattingSchema.json",
            "elmType": "div",
            "attributes": {
                "class": {
                "operator": "?",
                "operands": [
                    {
                    "operator": "==",
                    "operands": [
                        "@currentField",
                        "Done"
                    ]
                    },
                    "sp-field-severity--good",
                    {
                    "operator": "?",
                    "operands": [
                        {
                        "operator": "==",
                        "operands": [
                            "@currentField",
                            "In progress"
                        ]
                        },
                        "sp-field-severity--low",
                        {
                        "operator": "?",
                        "operands": [
                            {
                            "operator": "==",
                            "operands": [
                                "@currentField",
                                "In review"
                            ]
                            },
                            "sp-field-severity--warning",
                            {
                            "operator": "?",
                            "operands": [
                                {
                                "operator": "==",
                                "operands": [
                                    "@currentField",
                                    "Has issues"
                                ]
                                },
                                "sp-field-severity--severeWarning",
                                "sp-field-severity--blocked"
                            ]
                            }
                        ]
                        }
                    ]
                    }
                ]
                }
            },
            "children": [
                {
                "elmType": "span",
                "style": {
                    "display": "inline-block",
                    "padding-left": "4px"
                },
                "attributes": {
                    "iconName": {
                    "operator": "?",
                    "operands": [
                        {
                        "operator": "==",
                        "operands": [
                            "@currentField",
                            "Done"
                        ]
                        },
                        "CheckMark",
                        {
                        "operator": "?",
                        "operands": [
                            {
                            "operator": "==",
                            "operands": [
                                "@currentField",
                                "In progress"
                            ]
                            },
                            "Forward",
                            {
                            "operator": "?",
                            "operands": [
                                {
                                "operator": "==",
                                "operands": [
                                    "@currentField",
                                    "In review"
                                ]
                                },
                                "Error",
                                {
                                "operator": "?",
                                "operands": [
                                    {
                                    "operator": "==",
                                    "operands": [
                                        "@currentField",
                                        "Has issues"
                                    ]
                                    },
                                    "Warning",
                                    "ErrorBadge"
                                ]
                                }
                            ]
                            }
                        ]
                        }
                    ]
                    }
                }
                },
                {
                "elmType": "span",
                "txtContent": "@currentField",
                "style": {
                    "padding-left": "4px"
                }
                }
            ]
        }
    },
    {
      "verb": "addSPView",
      "name": "All Items",
      "viewFields": [
        "LinkTitle",
        "ProjectProgress",
        "ProjectStatus",
        "ProjectCategory"
      ],
      "query": "",
      "rowLimit": 30,
      "isPaged": true,
      "makeDefault": true,
      "formatterJSON": {"additionalRowClass": "=if([$ProjectCategory] == 'Legal', 'sp-field-severity--blocked', '' )"}
    }
  ]
},
{
  "verb": "addNavLink",
  "url": "Lists/Project Tracker/AllItems.aspx",
  "displayName": "My Projects",
  "isWebRelative": true
}
    ],
    "version": 1
  }
Scheme

Add Site Script

Site Scripts must be registered with SharePoint Online. New Site Scripts can be added with the below PnP Powershell commands.

$credentials =Get-Credential
$tenantURL="https://mittal1201-admin.sharepoint.com"
Connect-SPOService -Url $tenantURL -credential $credentials
BASIC

where mittal1201 should be your domain name.

$sitescriptLocation="C:\Path\ProjectSiteScriptV1.json"
Get-Content $sitescriptLocation -Raw | Add-SPOSiteScript -Title "ProjectSiteScriptV1"
BASIC

After running the script, you get a result with script ID. Keep track of ID, it will be used to associate with Site Template.





Create Site Template

The Site Template appears in the drop-down list of choose designs while provisioning the Site Collection. It can run one or more site scripts.

Add-SPOSiteDesign -Title "Project Site TemplateV1"
-WebTemplate "68"
-SiteScripts "efc8a372-7da3-497d-b3a2-2ee64611e4a3"
-Description "Project Site TemplateV1 site template designed for IT department projects to create and maintain the consistency of project sites with common schema across all site Project Site Collections."
JavaScript

WebTemplate value selected which base template associated with

  1. WebTemplate 64 - Modern Team Site
  2. WebTemplate 68 - Modern Communication Site
  3. Web Template 1 - Team site (no O365 group connected)

After running the script, you get a result with Site Template ID. Keep track of ID, it will be used to update or remove the Site Template in the future.

Id                  : be42d063-f67b-4d35-88df-88db0a79a59e
Title               : Project Site TemplateV1
WebTemplate         : 68
SiteScriptIds       : {efc8a372-7da3-497d-b3a2-2ee64611e4a3}
Description         : Project Site TemplateV1 site template designed for IT department projects to create and maintain the consistency of project sites with common
                      schema across all site Project Site Collections.
ThumbnailUrl        :
PreviewImageUrl     :
PreviewImageAltText :
IsDefault           : False
Version             : 1
DesignPackageId     : 00000000-0000-0000-0000-000000000000
DesignType          : Site
BASIC

Navigate to existing Modern Communication Site -> Select Gear Icon from Top left -> Select Apply Template -> Choose "From your organization" options. You will find customize Site Template.


Once you click to customize Site Template i.e. Project Site TemplateV1, you will navigate to the detail window, which shows the action details, which template is going to apply.


Click the "Use Template" button. it will apply all defined actions into Site Collections.

Once you browse to applied changes, you can find the below update,

  • Create Site Column
  • Create Content-Type
  • Create custom List
  • Associate Site Column and Content-Type to List
  • Add Data Column Formatting
  • Add List to Top Navigation


Get existing Site Template and Site Scripts information

Once you have deployed Site Templates or Site Scripts to your tenant, you need to get information on deployed site templates or site scripts. you need to execute the below scripts,

$spoadminSiteUrl = "https://mytenant-admin.sharepoint.com"
$cred = Get-Credential
Connect-SPOService $spoadminSiteUrl -Credential $cred
Get-SPOSiteDesign
Get-SPOSiteScript
BASIC

Delete existing Site Template and Site Scripts

Currently, there is no manual option to delete existing Site Templates or Site Scripts. You need to execute the below scripts to delete it. Deletion of existing Site Template will not delete associated Site Scripts. Site Scripts need to delete separately.

$spoadminSiteUrl = "https://mytenant-admin.sharepoint.com"
$siteDesignId = "be42d063-f67b-4d35-88df-88db0a79a59e"
$siteScriptId = "5f99d2b8-c0f4-41e2-81c0-67bb5e3ba1bd"
$cred = Get-Credential
Connect-SPOService $spoadminSiteUrl -Credential $cred
Remove-SPOSiteDesign -Identity $siteDesignId
Remove-SPOSiteScript -Identity $siteScriptId
BASIC

I hope you enjoyed and learned something new in this article and stay tuned for the next step.