IF-Blueprint Blog

Categorize, organize and layout your Office 365 intranet with PnP Templates

Categorized sites based on PnP templates

Categorized sites based on PnP templates


The out of the box functionality of SharePoint Online to organize your intranet is getting better and better and covers a lot of standard use cases. You have the possibilities to organize it by Hub-Sites, Highlighted Content-, News, Sites- and many more Webparts. But in real life they often do not fulfill all requirements. Also, you are restricted when it comes to customizing the layout and the look & feel. Recently, a customer of mine needed an overview page for different project types. My idea to solve the problem was to use PnP Provisioning Templates to provision and tag different project types/sites and then use the SharePoint Online search to display them in the required overview page.

The ingredients to implement this solutions are:

Check out the whole post to see how I implemented it…

Setup the PnP Templates

For each project type I created a separate PnP Template xml file. In these templates, you can let your creativity off. Important for this solution is that you name the templates in a logic manner.

The important XML tag / line is

<pnp:ProvisioningTemplate ID=”CONTOSO.HR.PROJECT” Version=”1″ BaseSiteTemplate=”GROUP#0″ Scope=”RootSite”>

Later on, this ID will be searchable and will help to differentiate single project templates in the search webpart. In my demo example I create a HR (CONTOSO.HR.PROJECT) and a SALES (CONTOSO.SALES.PROJECT) project template. Each template creates its own folder structure in the default document library, but as I said before, you have nearly endless possibilities to create customized Team- and Communication Sites with PnP Provisioning Templates.

You can get more information about PnP Provisioning Templates here Remote Provisioning Schema

Create modern TeamSites and apply the templates

After you have created awesome templates you can now create some modern SharePoint TeamSites and apply the templates to them. In my example I do this with some simple PowerShell commands, but it is up to you to do this  with the magic of SiteDesigns, SiteScripts, Flow and AzureFunctions (you can find a good overview here).

There a two important steps in this script:

  1. Set-SPOsite $hrProject1 -DenyAddAndCustomizePages 0 ⇒ By default scripting is disabled by modern Team- and CommunicationSites. You must allow scripting for your site. If you don’t do that the necessary property will not be written into the site properties! In my little script I did not disable scripting again. But to be save you can of course do this with the command Set-SPOsite $hrProject1 -DenyAddAndCustomizePages 1 . (Read more about this topic here)
  2. Add-PnPSiteCollectionAdmin -Owners “yourAdmin@contoso.com” ⇒ When creating a modern Team- or Communication site, the related AD-Group will be set as SiteCollection admin. And for some reasons,  the search crawler will not index the site properties although they are correctly registered in the vti_indexedpropertykeys property. But after setting an additional SiteCollection admin the properties will be indexed (I will explain which property matter to us latter). In my case this account is my global admin, and because I was so annoyed about the fact that it is not working when only the AD-Group is the SiteCollection admin, I stopped my investigations here. (Please let me know if you have more information about this behavior! For example, is it necessary to and a second SiteCollection admin or is it ok to add an user to the owner group, or is it required that the user has Office 365 SharePoint admin right?). Thanks to Jonne Klein her article led me into the right direction!

The crawled property relevant to us is the _PnP_ProvisioningTemplateId. This property stores information about which PnP template was applied to the site (CONTOSO.HR.PROJECT or CONTOSO.SALES.PROJECT). When you check the properties of one of this new created site (e.g. my HR project 1 site) with the following REST call:

You will get a result like this:

The interesting values are these two (NOTE if scripting had not been enabled for the sites,  these entries would not have been written into the site properties!)

But as we enabled it, the _PnP_ProvisioningTemplateId property is registered in the vti_indexpropertykeys (to decode the base64 coded values, you can use this tool).


So, if everything works fine, the crawled property will appear sooner or later in your SharePoint Online search schema (NOTE: only when you added a second SiteCollection admin!)

Setup the SharePoint Online Search

When the crawled property _PnP_ProvisioningTemplateId appears as crawled property you must map it to a managed property. In my example I used the RefinableString00 managed property. I did this on the global tenant search level.


Crawled property mapped to a managed property

Crawled property mapped to a managed property

After that step you can use the RefinableString00 to search and filter for it in the search webpart.

Deploy the SPFx Search

With the awesome and super configurable SPFx Search WebPart you can search and filter by your previously created ManagedProperty RefinableString00. But first, you must upload it to your App-Cataloge (this article describes how you can setup a SharePoint Online App-Catalog). If your App-Cataloge is available you can upload the pnp-react-search-refiners.sppkg .The SharePoint Online App CatalogeIf you have not chosen a tenant wide deployment, then you must add the SPFx WebPart on the site on which you want to use it.

Site gear &gt; Add an app &gt; Apps from your organization

Site gear > Add an app > Apps from your organization

Add the WebPart to you page

After this, you can place the Search WebPart on a page. In my example I have placed two Search WebPart with different configurations.

Edit page &gt; add Search Results with Refiners WebPart

Edit page > add Search Results with Refiners WebPart

Configure the WebPart

Now it is time to demonstrate the power of this awesome WebPart. What we want to do is, adding  a search query to get the sites filtered by the _PnP_ProvisioningTemplateId (exactly by the mapped ManagedProperty RefinableString00). Afterwards, we will pimp the layout with a handlebar template.

  1. Configure the Search query keywords
    Setup search query keywords field

    Add * into the search query keywords field

  2. Add the following Query template:
    ContentClass=sts_site RefinableString00:”CONTOSO.HR*”
    The template returns only elements which are of type sts_site and whose RefinableString00 attribute starts with “CONTOSO.HR*”. Remember this is the PnP Template ID which we have defined in our PnP template. In my example I removed the Sort order, Sortable properties and the Refiners.

    Add query template

    Add query template

    As you see in the image above, the search returns only site on which the PnP ProvisioningTemplate ID=”CONTOSO.HR.PROJECT”.  Nice! But the look is a bit old school, so it is time to pimp it up.

  3. To change the look we can use the integrated handlebars templating engine.
    Customize the look with the handlebars templating engine

    Customize the look with the handlebars templating engine

    This is my simple code:


VOILA! If you add a second search WebPart with a different Query template, you can create a nice landing page like this:

Overview page of different project types

Overview page of different project types