Problems with PnP Provisioning News Filtering – For the Developer

If you haven’t read my previous post, Understanding SharePoint News Filtering Pitfalls, I encourage you too.  It will provide some insight into how I got myself into this mess.  If you want to jump right in the short version is.  News filtering is almost a necessity in any communication site, but it comes with some edges with filtering that you should understand.

In a recent project of ThreeWill’s, we worked closely with a customer of our’s communications team to define different PnP site templates. These templates were complete with unique layouts and web part configurations for the home page of each.  Many of these templates included a “Featured News” web part as a key home page element.  Our definition of “Featured News” is basically the News web part configured to filter only News that had been tagged with a category of “Featured”.

Using the PnP Provisioning Engine, we extracted the PnP Templates out using Get-PnProvisioningTemplate and integrated this into a whole site request process, complete with approvals and site provisioning based on the appropriate template.  During our pilot testing, we ran into a pretty complex bug that had me scratching my head for quite a bit.  I logged two different issues on GitHub that, I didn’t learn until later, are really related to the same thing. Spoiler, they can’t be fixed until Microsoft makes a change first.

Old Newsreel vs. New News Web Part

Initially, I dove headlong into the source for Microsoft 365 Dev PnP Core components since these components are what do the heavy lifting in the PnP Provisioning engine. My testing proved fruitless until I finally looked at all the JS files loaded by a SharePoint Page. I then compared a broken (added via PnP Template) vs working (added via the UI).  This clued me in to the fact there were different JavaScript files loaded for what I thought was the same News web part.

  • If you provisioned a News web part with the PnP, the sp-newsreel-webpart-bundle*.js is loaded
  • If you added a News web part through the UI, the sp-news-webpart-bundle*.js is loaded

Armed with this information I was able to determine that the web part ids were different (again for what I thought was the same News web part).

  • If you provisioned a News web part with the PnP, the web part id is a5df8fdf-b508-4b66-98a6-d83bc2597f63. From now on I’ll call this old newsreel.
  • If you added a News web part through the UI, the web part id is 8c88f208-6c77-4bdb-86a0-0c47b43165. From now on I’ll call this new news.

The Verdict

I’d like to say this was obvious and easy to figure out but based on getting and apply templates and comparing the web part properties, it took me far too long to realize this. My initial reaction of course was, why is PnP putting the “wrong” web part on the page.

Backtracking through the logic in ClientSidePage.cs, it became clear that PnP is just a victim of circumstance.

  • In ClientSidePage.cs it relies on a call to the SharePoint REST API GetClientSideWebParts to tell it what web parts can be added along with their manifest information and so on.
  • Only the old newsreel is returned (a5df8fdf-*). The new news is not returned (8c88f208-*)
  • In ObjectClientSidePages.cs the list of AvailableClientSideComponents from the API is used to find and instantiate the web part from its default manifest.
  • Because both the old newsreel and new news are currently exported as “Newsreel” AND more importantly because new news isn’t returned from the API, the old Newsreel is instantiated as the base, regardless of which web part id comes in from the PnP template. Meaning PnP Template can only put the old newsreel on a page, for now.

Short Term Fix

While I’m waiting to hear back from Microsoft Premier support about my concerns with the new news not coming back in the API, I had to figure out a work around.  Turns out it’s simple after you’ve applied the PnP template you can execute the script below fixup the CanvasContent1 and things look good.  All this code does is query for the Home.aspx page and update it’s underlying list item with the new web part ids.

$homeItem = Get-PnPListItem -List "Site Pages" -Query "Home.aspx"
if($null -ne $homeItem) {
     $canvasContent = $homeItem["CanvasContent1"];
     $canvasContent = $canvasContent `
          -replace "a5df8fdf-b508-4b66-98a6-d83bc2597f63","8c88f208-6c77-4bdb-86a0-0c47b4316588"
     # update the canvas content after id's are replaced
     $updatedItem = Set-PnPListItem -List "Site Pages" `
          -Identity $homeItem.ID `
          -Values @{"CanvasContent1" = $canvasContent}
     # make sure updates are published and visible
     $page = Set-PnPClientSidePage -Identity "Home" -LayoutType Home -HeaderType None -Publish

Post Short Term Fix

I’ll be keeping my fingers crossed that API is fixable (if Microsoft agrees that it’s broken).  When it is fixed, I think the changes to the PnP should be very easy and I’ll hopefully get make my first contribution there.

Share and Enjoy !

Related Content: