WebParts – Inquisitive M365 https://thomasdaly.net Yet another SharePoint / Office 365 blog Fri, 06 Mar 2026 14:51:02 +0000 en-US hourly 1 116451836 Sort Your SharePoint Site Directory Alphabetically https://thomasdaly.net/2025/02/02/sorting-your-sharepoint-site-directory-by-title-with-pnp-search/ https://thomasdaly.net/2025/02/02/sorting-your-sharepoint-site-directory-by-title-with-pnp-search/#comments Sun, 02 Feb 2025 21:53:07 +0000 https://thomasdaly.net/?p=3339 In my previous article, Build a Site Directory with PnP Search Web Parts, I walked through how to create a dynamic site directory using PnP Modern Search. While that setup provides a powerful and flexible way to display SharePoint sites, you may have noticed a limitation—SharePoint doesn’t allow sorting by the Site Title property out of the box.

This article covers the extra step needed to sort your site directory alphabetically by title. The trick? Leveraging RefinableString fields to make the Site Title sortable. It’s a simple process with just a few tweaks, and by the end of this guide, you’ll have a properly sorted site directory in no time. Let’s dive in.

Updating the Search Schema

Navigate to the SharePoint Admin Center

Expand ‘Advanced’ then click ‘More Features’ and finally click ‘Open’ under the ‘Search’ group

Next click ‘Manage Search Schema’

Next enter ‘RefinableString’ in the search box and click the green button

Hover over any of the available properties and find the drop down, then click ‘Edit Map Property’

It’s not critical on what number refinable string you choose

Scroll all the way to the bottom and click ‘Add a Mapping’

Enter ‘display’ and click ‘Find’, then select Basic:displaytitle and click O

Verify the mapped managed property and click ‘OK’

This completed the Search Schema changes. These can take quite some time to take effect so be patient. It could be a day before you see it working.

Next navigate to the SharePoint page with the PnP Search Web Part configured as a Site Directory

NOTE: The following steps are only necessary if you have customized the Custom template.

  1. Edit the page and open the web part properties of the Search Results web part
  2. On the second page, click on the curly braces { }
  3. Take a copy of the entire

Change the template to Debug. This is so that you can visually see the property to ensure that the search property has taken effect.

Go back to the first page of the web part properties, enter the name of the RefinableString## you modified and hit Enter.

The result should appear on the left hand site – most likely it will read null to begin with. It will eventually populate. It can appear at any time but at least wait 8 hours or a full day. Recheck the steps in the search config but at this point there is not much more to do but wait.

What to do if the site title will no show up?

If it’s just not showing for a few sites

  • Update the Site Title of the site. Change it temporarily and then change it back
  • Trigger a reindex on the 1 site

If it’s not showing up for many sites

Recrawling puts strain on the service as a whole so it’s not meant to be run over and over as it can take weeks to finish on very large sites.

After the crawl property appears move on to the next step.

Apply the Sort

Navigate back to the Search web part page and edit the web part properties

Click ‘Edit sort settings’

Type in your RefinableString## into the Field name box, click Default Sort and then click ‘Add and save’

The sorting is now set to alphabetical order from A-Z by default.

Next go to the second page of the web part properties

Set the template back to what it previously was. In our case Custom and then click on the { } to edit the custom template

Copy / Paste in the template, Save and Republish.

The final result should be in order by site title.

Wrap Up

Sorting your SharePoint site directory by title might not be possible out of the box, but with a little creativity—leveraging RefinableString fields—it becomes a straightforward solution. By following these steps, you can ensure your directory is organized in a way that makes finding sites easier for users.

This small but impactful tweak enhances usability and keeps your directory structured exactly how you need it. If you’re already using PnP Search Web Parts, this is a great optimization to implement. Have questions or run into issues? Drop a comment—I’d love to hear how this worked for you!

]]>
https://thomasdaly.net/2025/02/02/sorting-your-sharepoint-site-directory-by-title-with-pnp-search/feed/ 2 3339
Build a Site Directory with PnP Search Web Parts https://thomasdaly.net/2025/01/20/build-a-site-directory-with-pnp-search-web-parts/ https://thomasdaly.net/2025/01/20/build-a-site-directory-with-pnp-search-web-parts/#comments Tue, 21 Jan 2025 04:07:34 +0000 https://thomasdaly.net/?p=3324 This article will demonstrate how PnP Search Web Parts can be used to build a comprehensive Site Directory that not only enhances navigation but also improves the overall user experience by providing a centralized resource for accessing various sites within your organization.

Pre-Requisites

PnP Modern Search – Search Web Parts – v4

From your SharePoint site

Instructions

Create a new Page

Edit the Page

Add the PnP Search Results Web Part

Next click ‘Configure’

Next click ‘SharePoint Search’

Next click ‘Customize’ under ‘Layouts slots’

Add SiteUrl — mapped to SPSiteUrl, click ‘Save’

Edit the Query Template, using this as my base. It will show all ‘Sites’ and not the app catalog or my sites.

contentclass:STS_Site -"{TenantUrl}/sites/contenttypehub" -"{TenantUrl}/sites/appcatalog" -SiteTemplate:SPSPERS

** Thanks Kasper Larsen for the comment and suggestion to use the tokens for more resuability! **

Make sure to hit Apply to save the query.

Scroll down to the Paging Options

For our example we want to show as many sites as possible.

Set the number of items per page to 500

Click ‘Next’ to go to the second page of the property pane

Click ‘Custom’ Template and then {}

Replace this CSS

 /* Insert your CSS overrides here */
       .example-themePrimary a {
            color: {{@root.theme.palette.themePrimary}};
        }

        .site-logo {
            width: 35px;
            margin-right: 10px;
        }

        .icon {
            width: 20px;
            height: 16px;
        }

        ul.template--custom {
            list-style: none;
            padding-left: 5px;
	 columns: 4;
        }

        ul.template--custom li {
            display: flex;
            padding: 8px;
        }
        
        .site-link {
            line-height: 20px;
        }
        
        .site-link > a {
            display: flex;
            align-items: center;
        }
        
        .site-link, .site-link a, .site-link a:visited, .site-link a:hover, .site-link a:link {
            color: #000 !important;
            text-decoration: none;
        }

Next replace the item template

<template id="content">

 {{#> resultTypes item=item}}
                            {{!-- The block below will be used as default item template if no result types matched --}}
                            <li class="site-link">
                                <a href="{{slot item @root.slots.SiteUrl}}">
                                   <img class="site-logo" src="{{slot item @root.slots.SiteUrl}}/_api/siteiconmanager/getsitelogo?type='1'"/>
                                   <span class="site-name">{{slot item @root.slots.Title}}</span>
                                </a>
                            </li>
                        {{/resultTypes}}

                    </template>

Click ‘Save’

Click Republish

Your page should now look something like this

Conclusion

This is the first step toward making a Site Directory with all the sites you have access to. You could easily extend this to use a search box to filter these items down or change the KQL query to show only certain types of sites. You might also notice that the sites are not in order. In the next article I’ll walk you through the process of implementing the sort on the Site Name.

]]>
https://thomasdaly.net/2025/01/20/build-a-site-directory-with-pnp-search-web-parts/feed/ 5 3324
Adding Font Awesome to SPFx React project https://thomasdaly.net/2022/01/20/adding-font-awesome-to-spfx-react-project/ https://thomasdaly.net/2022/01/20/adding-font-awesome-to-spfx-react-project/#comments Thu, 20 Jan 2022 18:39:00 +0000 https://thomasdaly.net/?p=2688 Introduction

I love the FontAwesome library and use it on many projects. I was a huge fan of FontAwesome 4.0 and had a little struggle moving over to using 5.0 + 6.0 in my projects. I was use to the old way of including the link to the CSS files and using the class names. You can still do that if you wish but this article shows using the React component approach. It’s simple once you’ve done it a few times.

Install React Font Awesome

npm i –save @fortawesome/react-fontawesome

Install the Core Packages [required]

npm i --save @fortawesome/fontawesome-svg-core

Install the Icon Packages, use only the ones you need. If you only use solid icons then choose that. If you are not sure right now then you can include them all and remove them later.

npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/free-regular-svg-icons
npm i --save @fortawesome/free-brands-svg-icons

Go Find a Fonthttps://fontawesome.com/icons

Keep in mind that you only have the free library so you can only use those unless you buy the pro license

If you pick an icon and it says ‘Start Using this Pro Icon’ then you need to choose something else or purchase a license

You can filter the free ones by clicking this on the left.

I’ve selected the fish icon, next you need to take note of the type ‘Solid’ or ‘Regular’

Now import the FontAwesomeIcon component and the icon you want from the correct package

This fish icon is in the Solid package.

If I wanted to use something from the regular package like this icon

This font is in ‘Regular’ package you would import it from that package instead

There is intellisense inside visual studio to help get the correct name of the icon

Now the result

If you wanted to use the brand icons you would follow the same approach. I believe that all the brands icons are free.

I love FontAwesome library of icons and use them in many projects. The PRO version unlocks so many more fonts and customizations that it’s worth buying if you plan to use them and want to support this project.

]]>
https://thomasdaly.net/2022/01/20/adding-font-awesome-to-spfx-react-project/feed/ 2 2688
Making SPFx Web Parts Searchable – Lessons Learned https://thomasdaly.net/2020/06/19/making-spfx-web-parts-searchable-lessons-learned/ https://thomasdaly.net/2020/06/19/making-spfx-web-parts-searchable-lessons-learned/#comments Fri, 19 Jun 2020 08:00:00 +0000 https://thomasdaly.net/?p=1892 I recently built a handful of amazing content entry web parts for Office 365 using SharePoint Framework (SPFx). The client I was working with wanted various combinations of responsive columns, rich text editor, links, and pictures. This ultimately led to building out a few custom web parts to meet their needs.

About a months later, as we started focusing on search, I noticed a huge problem. The contents of my web parts were not searchable! We couldn’t find anything. This was the first time I had to ensure the content was indexed on a modern page. It’s not the same as classic – lesson learned.

Step 1 – Mark Your SPFx Web Part Properties

I came across the official Microsoft guidance which tells you to mark your properties. I will not go into details of the article, you can read the full article here.

As you can clearly see you need to mark the web parts as image, html, string, or link. If you have a combination of those then use html.

Microsoft’s Example

Yet another issue. What about web parts that have arrays, objects, arrays of objects or props that leverage lists as a data source?

How to handle an arrays / objects / both … simplify

Here is an example from one web part. I have a web part property which is an Array of Objects, that have multiple properties. According to the guidance, how do you mark it?

There is no immediate way to tag this properties where it would get indexed correctly and make the content searchable. So how do you solve this? The list below are the main points.

  1. Create a new property ‘searchableText’
  2. Mark the new property ‘isHtmlString’
  3. Create an update function

Step 1 and 2 are very straightforward. These are used inside the main .ts file of the web part. It will not be passed into the child components.

Create New Property
Mark New Property

The 3rd step is to pass a function to child component. When the items are changed inside the web part, it will loop over the items and create an html string of the text & links to update searchableText. Once that is complete we will be able to search on the content of the web part properly.

The purpose of this example is give you an idea of converting your objects / arrays into a String. It’s a little extra work but making it worthwhile when users can search the contents of your web parts. I have yet to figure out a way to make list based web part content searchable on the page. [I do not want to hit the list items directly in many cases] That might be a blog for another time.

]]>
https://thomasdaly.net/2020/06/19/making-spfx-web-parts-searchable-lessons-learned/feed/ 6 1892
Content Query Web Part + Calendar = Mad Problems https://thomasdaly.net/2014/04/01/content-query-web-part-calendar-mad-problems/ https://thomasdaly.net/2014/04/01/content-query-web-part-calendar-mad-problems/#respond Tue, 01 Apr 2014 14:58:00 +0000 http://tommdaly.wordpress.com/?p=651 I recently had to assemble a content query web part (my least favorite thing) pulling data from a Calendar list and experienced hours of pain trying to get it to pull the locations field as well as the start/end time consistently. I share my pain so that other won’t have to endure, and hopefully some tips so that you can skip all the BS and just make a quick web part that should have took about 30 minutes.

I had an extremely painful time working with the Location field for some reason. It would show on ctrl-f5 or the first load of the web part. Then disappear or show intermittently. It was basically unreliable until I used the ID and renamed the fields as described below.

Getting the fields right

Step 1 – Calendar list settings

If you go to the list settings and copy or inspect the link to the Start Time field you’ll see something like this.

/_layouts/15/FldEdit.aspx?List=%7BE84FD6F2%2D11AD%2D443B%2D84A2%2DA6E1B198458D%7D&Field=EventDate

This is good to give you what the field name is but we actually just want the field ID. Next I move up to the parent content type and click “Event”

image

In these columns I copy or inspect Start Time field again and you’ll see this

/_layouts/15/ManageContentTypeField.aspx?ctype=0x010200D536EDB0AB69A047B200ABF60FFE33EF&List=e84fd6f2-11ad-443b-84a2-a6e1b198458d&Field=EventDate&Fid=%7B64cd368d%2D2f95%2D4bfc%2Da1f9%2D8d4324ecb007%7D

This is what I want – I’ll get the actual field ID. using a url decoder [http://meyerweb.com/eric/tools/dencoder/]

Fid=%7B64cd368d%2D2f95%2D4bfc%2Da1f9%2D8d4324ecb007%7D

Fid={64cd368d-2f95-4bfc-a1f9-8d4324ecb007}

Step 2 – Content Query

Once you’ve exported the content query so we can edit it in notepad, search for CommonViewFields

Add the Start Time field to this property

<property name=”CommonViewFields” type=”string”>{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},DateTime;</property>

Next search for DataColumnRenames, add the following. The EventStartDateTime is what you would use in the xslt to pull this property. You can call it what you like at this point.

<property name=”DataColumnRenames” type=”string”>{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},EventStartDateTime;</property>

Below is a snippet of me using the EventStartDateTime in my xslt. I’m assigning it to a variable to i can further manipulate it.

image

Step 3 – Repeat

You can repeat the following steps for a fool proof method of getting the fields you want into your content query web part. If you use the column ID and rename it you should have no issues.

 

Location Field

{288f5f32-8462-4175-8f09-dd7ba29359a9},Text;

Start Time

{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},DateTime;

End Time

{2684f9f2-54be-429f-ba06-76754fc056bf},DateTime;


<property name=”CommonViewFields” type=”string”>{288f5f32-8462-4175-8f09-dd7ba29359a9},Text;{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},DateTime;{2684f9f2-54be-429f-ba06-76754fc056bf},DateTime;</property>

<property name=”DataColumnRenames” type=”string”>{2684f9f2-54be-429f-ba06-76754fc056bf},EventEndDateTime;{288f5f32-8462-4175-8f09-dd7ba29359a9},EventLocation;{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},EventStartDateTime;</property>

Troubleshooting

From this day forward I vowed to always include this debugging template in my ItemStyle.xsl. It will basically just dump the raw data to your screen, so you can see what fields you have

   
     
      = 
     
     
   
   
   
   
 

If you set the Item style: DisplayRawData, you’ll get a dump of the fields and values that are available. In the screen shot below you’ll notice then fields that we’ve renamed and they data

image

]]>
https://thomasdaly.net/2014/04/01/content-query-web-part-calendar-mad-problems/feed/ 0 651