Brand new page templates on SharePoint Online are a great way to unify your content and help your content authors for creating pages and news. Page templates can be created easily just by promoting a page to a template, giving it a title, maybe changing some content and settings, and finally publishing it. Template will available for all content authors on that current site. But what if you would like have uniform page templates available on all of your modern sites on the hub. Well, a bit of Flow magic can help you out.

Please note that template folder is localized based on site’s default language, so in English it’s “Templates” and in Finnish it’s “Mallit”. Same goes when using library names, in English “Site Pages”, in Finnish “Sivuston sivut”. These need to be taken care of when building this Flow on multilingual/global environment.

Main idea of this example is to copy page templates from a hub site to sites belonging that hub when template is changed.

#1 Triggering

Setup a SharePoint Flow trigger, which fires when new file is created or modified in a folder. Hub site is selected as source site and Folder Id is set to /SitePages/Templates (notice localization issues here).

#2 Get all sites from your hub

First, an array for storing site urls is needed.

All sites in the hub are retrieved with a search query using Send HTTP request to SharePoint Flow action. Hub is identified with DepartmentId managed property with hub site’s id.

Here is a template, which returns only sites on selected hub identified with hub site’s id.

_api/search/query?querytext='ContentClass%3dSTS_Site+DepartmentId%3d{ffb63bae-428a-4233-b953-3386bbd849a3}'&rowlimit=50&selectproperties='Path'&clienttype='ContentSearchRegular'&trimduplicates=false 

Where can I find hub site id? For example doing a REST API call on your hub site with a browser: https://<hubsiteurl>/_api/site/?$select=HubSiteId.
It returns:

<d:HubSiteId m:type="Edm.Guid">ffb63bae-428a-4233-b953-3386bbd849a3</d:HubSiteId>

For finding needed site Urls, some parsing of returned search results needs to be done. First parsing the individual search results. For Apply to each action, following expressions is needed.

body('Send_Search_Query')?['d']?['query']?['PrimaryQueryResult']?['RelevantResults']?['Table']?['Rows']?['results'] 

Site urls from individual search results are added to an array with following expression.

 items('Apply_to_each')?['Cells']['results'][2]['Value'] 

I just couldn’t find a better way to reference to Path property than an indexer, it seems to always be the third property of the search result. If you find a better way to do this, please ping me on Twitter/LinkedIn.

#3 Copying templates

At first, Flow checks is Templates folder available on SitePages library. If actions fails, Copy folder action is run. Copy folder action copies whole Templates folder to target site.

If Get folder metadata action succeeds, just the template file is copied to target site and no other actions are required. (Notice localization issues here).

After copying a folder, I noticed that page templates are not available when creating a new page or a news post. Files were in correct folder and Site Page Flags metadata was correctly set as Template. Something was still missing, so I check what is happening when page is actually promoted and saved as a template. I noticed that there is a HTTP POST call to /_api/sitepages/pages(15)/SavePageAsTemplate and {“__metadata”:{“type”:”SP.Publishing.SitePage”}} as payload. After testing that with Flow, I also noticed that you need to publish a template based on a page to get other templates also visible. So, I was lazy and just get a list item from Site Pages library get an id for SavePageAsTemplate call.

API call actually creates a new page template, which needs to be removed with Flow. Remember to put Accept header to SavePageAsTemplate call to get the list item id, which is needed to removing the item.

Afterword & Learnings

Flow is really powerful for lightweight automation like this one. But as soon as there is some data handling included, it needs more testing round to get it working correctly. And that is the fun part of it – try-fail-learn-repeat until you succeed.

This example Flow still needs some polishing . Once that is done, I will make an export of this Flow available.

Thanks you for reading! Hopefully this article was useful and worth of your time.

Blog updated on September 30th, 2019.