Setting Your SharePoint Framework WebPart Icon

Applies To: SharePoint Framework

When you create a SharePoint Framework (SPFx) webpart, you can customize the icon displayed in the Authoring Canvas Toolbox. Here’s what it looks like by default:

DefaultToolboxIcon
Default “Page” icon for your webpart

By default, the Office Fabric Page icon is used but this can and should be changed before packaging up your app. This makes sure your webpart doesn’t get lost among all the other webparts and is a very simple way to add a professional touch.

There are 2 ways to customize this icon. You can specify the name of an icon from the Office UI Fabric icons or you can provide a URL to a custom image.

Both of these are accomplished by editing your webpart’s manifest.json file and changing a simple property.

Office UI Fabric Icon

The easiest way to customize your icon is to simply specify the name of an icon class in the Office UI Fabric. You can find all the icons here: https://dev.office.com/fabric#/styles/icons

The Page icon shown above is doing exactly this. You can find this setting in the src/webparts/[YOURWEBPARTNAME]/[YOURWEBPARTNAME].manifest.json file in the preconfiguredEntries/officeFabricIconFontName property:

DefaultManifest

You can simply change this value from Page to any of the available icon names. Here’s what it looks like with a value of Emoji2:

SmileyToolboxIcon

Keep in mind that this value is CASE SENSITIVE. Also, note that changes to your manifest file (unlike your code files) will require you to stop the gulp serve command and do it again to have those changes reflected in the workbench.

If you inspect the actual toolbox you’ll see that the class name for the span is simply concatenating “ms-Icon–“ and the property value:

IconMarkup

This approach is super easy (just change the name) and ensures your webpart matches the official Office styles. But what if you want your own custom icon or logo?

Custom Icon

There is another property available called preconfiguredEntries/iconImageUrl and allows you to specify an image URL.

In order to use this property, create a 40x28px icon and upload it somewhere. For this example I’m just going to use my blog, but ideally you would include it in the webpart and then pull this value from your CDN.

You’ll also have to remove the preconfiguredEntries/officeFabricFontIconName property (or the iconImageUrl will be ignored). Here’s what my property looks like:

imageIconUrlManifest

Again, note that changes to your manifest file (unlike your code files) will require you to stop the gulp serve command and do it again to have those changes reflected in the workbench.

So here’s what it looks like in my local workbench:

iconImageUrlLocalWorkbench
Smells like a bug to me

What happened!?! For whatever reason, the local workbench continues to try and use a class icon as seen above (You can even see it sets a class of ms-Icon–undefined). However, the O365 workbench (/_layouts/15/workbench.aspx) works just fine:

iconImageUrl365Workbench

A quick inspection shows that the property value is just being inserted as the src attribute for an img tag.

This means (and I’m not suggesting you should) that if you happen to have a weird Christopher Walken eyeball gif:

WalkenEyes

You could simply resize it and get something like this:

AnimatedIcon
Why you make Vesa cry?

Documentation Discrepancies

Looking at the documentation for the manifest properties (json schema) you may see some misleading outdated information. (If you haven’t setup config file intellisense in VSCode, go do it now! Here’s an awesome guide.)

The description for the officeFabricIconFontName property looks like this:

officeFabricFontIconNameTooltip

It directs you to a site with 600+ icons many of which are present in the UI Fabric Icon styles. However, these names do NOT often match the actual class names and so cannot be reliably depended on to locate your icons (for example, the “Emoji2” icon we used in the sample above is listed as “smiley2” on the font site. It took going to the Office UI Fabric Icons page to find the correct class name).

The description for the iconImageUrl property looks like this:

iconImageUrlTooltip

You are instructed to use an icon that is exactly 38x38px. This is no longer accurate. You can use whatever size you want but it will be scaled to 40x28px.

Targeted JSLink for List View Web Parts

Introduction

Standard Client Side Rendering (CSR) is a powerful technology introduced in SharePoint 2013. Out Of The Box (OOTB) you can apply this technology to list view web parts through use of the JS Link property. Using this technique, developers can quickly and easily apply display logic through JavaScript.

Unfortunately, despite its continued support in SharePoint 2016 and Office365, CSR with list view web parts still suffers from a major flaw. When you have multiple web parts that display list items from lists that share a ListTemplateType and BaseViewID, OOTB CSR provides no way to correctly target your display logic (JSLink) to individual web parts.

How to Get the Code

The example code used in this document can be found in full as part of the csrShim repository:
https://github.com/thechriskent/csrShim/tree/master/Examples/Multiple%20List%20Views

The full project can be found on GitHub:
https://github.com/thechriskent/csrShim

You can download or clone the repository directly from that site. You can also view the code directly on the site.

The Problem

When a user adds 2 or more web parts displaying list items from a list that share a ListTemplateType and BaseViewID, standard CSR has no way of distinguishing between the web parts.

The result is that if only a single web part has a JS Link property specified, all matching web parts will be drawn with that logic (even ones intended to use the OOTB display!). If more than one web part has the JS Link property, then only the last one loaded will be applied.

This is especially problematic because custom lists all share a ListTemplateType of 100 and will present with a BaseViewID of 1. This issue often surprises developers that have developed their web part in isolation where they worked perfectly just to have them break entirely when placed on a page with other web parts.

A Demonstration

  1. We will add a web part using JSLink as configured in the List View Client Side Rendering (JSLink) Primer to have a web part using JS Link (The example code can be downloaded from the repository mentioned above):
    Single CSR
    This is a pretty standard team site page with a Site Feed, a Document Library, and a custom list with JSLink applied using standard CSR (Hall of Fame)
  2. Now if we add another Custom List web part (just an OOTB view):
    Broken CSR
    Immediately we see the someList web part is full of errors (these are JS errors from missing fields where the CSR attempted to apply the JSLink file)
  3. Removing the Hall Of Fame web part from the page fixes the someList web part:
    No CSR Fixed

There are many solutions for this to be found online. Most of these solutions are hacky workarounds at best, at worst they create fragile code and dependencies on management code outside of the web parts themselves.

It is often suggested to “override” the standard CSR template registration function and then create your own system to route CSR requests by dynamically changing the BaseViewID of the ContextInfo (ctx) objects. This technique requires you to have knowledge ahead of time of all possible web parts on the page or to have some additional way to uniquely identify/register your parts. The override is just taking advantage of JavaScript’s ability to alter objects you don’t own and introduces serious risk to your solutions (upgrades, users adding unknown web parts, and more).

The Solution

Fortunately, there is a solution that addresses many of the risks laid out above. The best part is that it can be independently implemented for individual web parts. These web parts never need to know or care about other web parts on the page (no management system required).

The solution is to use csrShim with your list view web parts. csrShim was originally developed to bring CSR capabilities to web parts without JS Link properties (Content by Query Web Parts and XMLViewer), but it can easily be applied to XSLTListView web parts. When doing so, you can specify a BaseViewID that is not tied to the original value allowing you to target web parts very specifically to CSR templates!

In addition, using csrShim this way allows you to add as many web parts to the page with the same underlying ListTemplateTypes and BaseViewIDs as needed and each can direct which CSR (JSLink) should be used for themselves. This technique can even be used alongside the standard CSR JS Link usage without causing issues for those parts or themselves.

A Demonstration

  1. Going back to our csrSad page from above, let’s add the Hall Of Fame web part back to the page but this time we’ll skip specifying the JS Link property:
    No JSLink
    When the JS Link property is not used, the OOTB views of custom lists can live side by side on a single page. But that’s not very exciting!
  2. Instead of specifying the JS Link property, we will specify the csrShim Parameters of BaseViewID and JSLink:
    Parameters
  3. Now when we refresh the page:
    WorkingWow
    Voila, someList web part is just fine! (If you don’t have any profile pictures showing up be sure you used the halloffame.js for this example)
  4. We can even add additional views of the Hall of Fame list:
    Multiple Hall Of Fame
    We could apply CSR to this web part without issue as well by simply specifying a different BaseViewID (assuming we wanted it to render differently).

Benefits

  • A single property is all that’s required to distinguish web parts (BaseViewID)
    • This property is exported with the web part so that it can be added to the web part gallery and safely added to any unknown page without causing conflict
  • Utilizes OOTB XSL system
  • Utilizes OOTB Rendering system

Drawbacks

  • Some properties must be accessed differently
    • An example can be seen with how the user id was pulled to generate the link for the hall of fame. Standard CSR provides an array of user objects with individual properties. csrShim provides multiple strings for those values. Using the ctx.csrShim boolean property, you can easily create a JSLink file that can handle either:
var sip, userId;
if(ctx.csrShim){
    sip = ctx.CurrentItem["Person.sip"];
    userId = ctx.CurrentItem["Person.id"];
} else {
    sip = ctx.CurrentItem.Person[0].sip;
    userId = ctx.CurrentItem.Person[0].id
}
  • Reliance on another component (csrShim)
    • To solve this problem, you would have to introduce something, likely something requiring more overhead and support issues
  • csrShim only returns a subset of properties that standard CSR returns (all list values are returned) but nearly every property used in rendering is included

Client Side Rendering (JSLink) with RSS Feeds

Applies to SharePoint 2013, 2016, Office 365

Introduction

Standard Client Side Rendering (CSR) cannot be applied to RSS feeds when consumed through the RSSViewer or XMLViewer web parts. However, using the open source csrShim stylesheet, XMLViewer web parts can consume XML based feeds while utilizing JavaScript based rendering.

This is not a comprehensive guide to the XMLViewer web part or csrShim but provides the information necessary to enable CSR. For additional details about how to use csrShim see the csrShim Documentation on GitHub.

How to Get the Code

The example created using the steps in this post can be found in full as part of the csrShim repository:
https://github.com/thechriskent/csrShim/tree/master/Examples/XML%20Feeds

The full project can be found on GitHub:
https://github.com/thechriskent/csrShim

You can download or clone the repository directly from that site. You can also view the code directly on the site.

Background

Why the XMLViewer and not the RSSViewer

The RSSViewer does not allow the execution of code within script blocks generated by XSL. XMLViewer is able to support all of the same feed types as the RSSViewer but it allows csrShim script blocks to be executed.

Supported Feeds

  • RSS
  • RDF
  • Atom
  • Atom2

Additionally, csrShim can easily be extended to support custom XML Feeds.

Standard Client Side Rendering

Client Side Rendering (CSR), often referred to as JSLink, is a technology introduced with SharePoint 2013 that provides extension points to use JavaScript to render SharePoint data. CSR continues to be supported in SharePoint 2016 and Office 365.

Additional information about how to use standard client side rendering with list views can be found in my earlier List View Client Side Rendering (JSLink) Primer series.

SharePoint does not support using standard CSR with XMLViewers (No JS Link property is defined). However, csrShim exposes parameters that will enable this functionality including the same set of event callbacks and templates described in the above guide.

csrShim

csrShim is an open source solution that fills the gap of many of the limitations presented by the OOTB client side rendering.

csrShim is an XSLT solution that can be used to:

csrShim is available through GitHub at:
https://github.com/thechriskent/csrShim

Getting Started

In the following example, we will be targeting on premise SharePoint 2013. We will be using a publicly available RSS feed from Netflix regarding their DVD service. However, csrShim easily handles other common feed types as well.

csrShim Setup

To use csrShim, an XMLViewer web part only needs the csrShim.xsl stylesheet from the csrShim project. However, an XSL Wrapper will also be required to pass parameters.

Upload the csrShim.xsl stylesheet to a library on your site (The Style Library of the root site of a site collection is a great spot for this!).

XSL Wrapper

The XMLViewer webpart does not expose XSLT Parameter properties as do the XSLTListView and Content by Query web parts. There are no ParameterBindings elements to be found in their definition.

In order to pass parameters to csrShim, an XSL Wrapper stylesheet is required. This is a very simple file (A sample wrapper is included in the csrShim Examples folder). Here is what ours will look like:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema"   xmlns:d="http://schemas.microsoft.com/sharepoint/dsp"   version="1.0"   exclude-result-prefixes="xsl msxsl x d ddwrt asp SharePoint ddwrt2 o __designer"   xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"   xmlns:asp="http://schemas.microsoft.com/ASPNET/20"   xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   xmlns:msxsl="urn:schemas-microsoft-com:xslt"   xmlns:SharePoint="Microsoft.SharePoint.WebControls"   xmlns:ddwrt2="urn:frontpage:internal"   xmlns:o="urn:schemas-microsoft-com:office:office"   ddwrt:ghost="show_all">

    <xsl:import href="/Style Library/csrShim/csrShim.xsl"/>
    <xsl:variable name="BaseViewID" select="50"/>
    <xsl:variable name="JSLink" select="'/intranet/Style Library/csrShim/FeedDisplay.js'"/>
</xsl:stylesheet>

Here’s what’s happening up there:

  • Lines 1-14 are just standard XSL boilerplate. Just copy this into your own, you shouldn’t need to change this at all.
  • Line 16 imports the csrShim stylesheet (just adjust the href value to point to your csrShim location (relative to the site))
  • Line 17 sets the value for the BaseViewID parameter
  • Line 18 sets the value for the JSLink parameter. Update this to point to your JSLink file(s) relative to the domain

Upload the XSL Wrapper stylesheet to a library within your site (The Style Library of the root site of a site collection is a great spot!).

Script Setup

A simple JSLink file, FeedDisplay.js, has been put together (available in the Example folder in the csrShim project) to display this particular feed.

For details about how CSR templates and event callbacks work see the List View Client Side Rendering (JSLink) Primer series. For this sample, we’ll just take a look at the parts unique to this solution.

The header and footer templates take advantage of the csrShim ContextInfo (ctx) object’s RootData property since this contains additional information about the feed itself. In this case the title of the feed and the description are used. These values are not guaranteed and are up to the feed provider.

The item template could be an item template for standard list items. The only thing of note here is that the Netflix feed supplies an HTML description and we are breaking it apart to show the included picture next to the description (rather than above it as it comes from the feed).

Upload the FeedDisplay.js file to a library within your site (The Style Library of the root site of a site collection is a great spot!).

Configuring an XMLViewer to use csrShim

Adding an XMLViewer to a Page

On a web part page where you want to display your feed:

  1. Edit the page
  2. Click the Add a Web Part button in the zone where you wish your feed to end up
  3. Choose XML Viewer under Content Rollup

XMLViewer Configuration

  1. Using the web part dropdown, choose Edit Web Part to open the toolpane
  2. Set the value of the XML Link property to: http://dvd.netflix.com/Top25RSS?gid=307
    csrxml01

Using csrShim

  1. Set the value of the XSL Link to the XSL Wrapper uploaded earlier (NOT csrShim directly):
    csrxml02
  2. Click OK
  3. Stop Editing the Page

The RSS feed should now use the CSR display:

csrxml03

The craziest part of this whole solution is how outdated these movies are!

Best Practices for csrShim with XMLViewers

  • Always use an XSL Wrapper around csrShim so that you can set parameters
  • Provide a unique BaseViewID to prevent conflicts with the default value of 1 (standard CSR with list views uses this value)
  • If reusing JSLink files between CQWPs, list views, and/or feeds, use the ctx.ShimType property to create conditional property retrieval as needed
  • Explore the ctx object to see what properties are available in the RootData and the ListSchema objects
  • Feed properties are not guaranteed. Always check for the values existence before using it
  • Wrap your JS Link code in an Immediately Invoked Function Expression (IIFE)
  • Unlike an RSSViewer web part, there is no row limit property for the XMLViewer. If you wish to restrict the number of results, increment a count in the Item template and stop returning values when that count is exceeded

Client Side Rendering (JSLink) with Content by Query Web Parts

Applies to SharePoint 2013, 2016

Introduction

Standard Client Side Rendering (CSR) cannot be applied to Content by Query web parts (CQWP). However, using the open source csrShim stylesheet, CQWPs can also utilize JavaScript based rendering.

Content by Query Web Parts were heavily utilized in earlier versions of SharePoint but have fallen out of favor due to their complexity and limitations. However, they have proven to be performant options (in on premises deployments) that can continue to solve a variety of problems.

When used in appropriate situations, CQWPs can be very powerful assets. Unfortunately, the Out Of The Box (OOTB) limitation against CSR has made it inaccessible to newer developers. However, csrShim enables CSR for CQWPs using OOTB configurations and rendering tools.

This is not a comprehensive guide to using CQWPs or csrShim but provides the tools needed to bridge the gaps and enable CSR. For additional details about how to use csrShim see the csrShim Documentation on GitHub.

How to Get the Code

The example created using the steps in this document can be found in full as part of the csrShim repository:
https://github.com/thechriskent/csrShim/tree/master/Examples/CQWP

The full project can be found on GitHub:
https://github.com/thechriskent/csrShim

You can download or clone the repository directly from that site. You can also view the code directly on the site.

Background

Content by Query Web Parts

The Content by Query Web Part (CQWP), often just called the Content Query Web Part is part of SharePoint’s Enterprise Content Management (ECM) toolset. CQWPs aggregate list items across a site hierarchy while providing query optimization and caching.

Benefits

  • Aggregation of list items across a single site collection
    • Can aggregate items from a single list, multiple lists by list type or contenttype, and more
  • Basic queries can be configured using OOTB web part tool pane
  • Respects Audiences
  • Powerful caching leading to high performance in on-premises deployments
  • Is not subject to search’s limitations (use of managed properties, crawl delay, search language, etc.)
  • OOTB display templates

Limitations

  • Cannot cross site collections
  • Advanced configuration can be difficult
  • Custom display requires complicated XSL (unless using csrShim)
  • Caching benefits are nullified when used in Office 365 leading to poor performance
  • Does not have some of search’s benefits (pre-aggregated results, cross site collection, extreme scalability, etc.)
  • Some fields (such as user fields) do not return as much detail as list view web parts

When to Use

You can use the CQWP when:

  • You are using Audiences with list items
    • Standard list views and APIs do NOT support audience filtering
  • You are aggregating across lists/contenttypes and the search crawl delay is unacceptable (or the configuring of search schema is prohibited)

Don’t use the CQWP when:

  • You need to cross site collections
  • Targeting Office 365
  • Search can be used instead

Standard Client Side Rendering

Client Side Rendering (CSR), often referred to as JSLink, is a technology introduced with SharePoint 2013 that provides extension points to use JavaScript to render SharePoint data. CSR continues to be supported in SharePoint 2016 and Office 365.

Additional information about how to use standard client side rendering with list views can be found in my earlier List View Client Side Rendering (JSLink) Primer series.

SharePoint does not support using standard CSR with CQWPs (No JS Link property is defined). However, csrShim exposes a parameter that will enable this functionality including the same set of event callbacks and templates described in the above guide.

csrShim

csrShim is an open source solution that fills the gap of many of the limitations presented by the OOTB client side rendering.

csrShim is an XSLT solution that can be used to:

csrShim is available through GitHub at:
https://github.com/thechriskent/csrShim

Getting Started

In the following examples, we will be targeting on premise SharePoint 2013 using SharePoint Designer 2013. We will be using a publishing site to have access to the Content by Query web part.

Additionally, we will be using the same list from the List View Client Side Rendering (JSLink) Primer series (with the exception that the Person field has a different Show field property). The CSR JavaScript file has also been adapted from the HallOfFame.js file created with that guide. Thus, many of the details around how CSR works are left out of this post. However, if you are already familiar with CSR basics you shouldn’t have any trouble following along.

The goal of this post, and this example, is not how CSR works but only how to use it with CQWPs.

List Setup

For this example, we will be using a custom list with just 3 columns:

  • Title (Text)
  • Person (User)
  • Color (Choice)

A HallOfFame.xml PnP template with this list is available if you are familiar with how to apply PnP provisioning templates.

Otherwise, to manually create the list:

  1. From a site where you have full control or design permissions, using the Site Actions menu (gear) choose Add an App
  2. Choose Custom List
  3. Name the list Hall of Fame and click Create
  4. From Site Contents, hover over the Hall of Fame icon and click the ellipsis to show the panel and choose Settings:
    cqwp01
  5. Under Columns, click Create column
  6. Give a name of Person and set the type to Person or Group and set the Show field to Account then click OK:
    cqwp02
  7. Under Columns, click Create column again
  8. Give a name of Color and set the type to Choice (menu to choose from). Replace the choices with Tomato, YellowGreen, DeepSkyBlue, Gold (each on separate lines):
    cqwp03
  9. Navigate to the Hall of Fame list and add several entries:
    cqwp04

You now have a basic list and you could simply use standard CSR to display the contents if that’s all you wanted. For this example, we will only have the one list since our goal is to demonstrate how to use the CQWP with csrShim.

Generally, however, you might have multiple copies of this list across several subsites and you would use a CQWP to roll all the results up to a single view. In this scenario, standard CSR would be unavailable to you and is exactly where csrShim fills that gap.

Also, note that we specifically set the Person Field’s Show field property to Account. Unlike with list views, CQWPs get very little information from user fields. Most of the Show field options will return the user’s name (and nothing else). List views return many properties including ID, account, email, etc. So, we must choose carefully so that we retrieve additional information if needed (in this case the profile picture).

Script Setup

We will be using a modified version of the JSLink file created with the List View Client Side Rendering (JSLink) Primer series. This script is available at the sample code location mentioned in the introduction (HallOfFame.js).

A full description of each of the templates/functions was provided in the primer series and should be consulted for any questions. The primary differences between that version and this one are:

  • The BaseViewID has been set to 40
    • This isn’t strictly necessary but is recommended when using csrShim so that you know your JSLink is very specifically targeted and can therefore be hosted alongside standard CSR and other csrShim implementations without conflict
  • The Item template was modified
    • Since the CQWP doesn’t return a full user object, we can’t simply get the profile picture from the Person field. So, the photo is always set to the placeholder image and has its visibility set to hidden
    • The user URL is also not set since we don’t have a user ID
  • The PostRender callback was modified
    • Code has been added to retrieve the PictureUrl and UserUrl from the User Profiles for each of the users based on their account name. Once those properties have been retrieved, the placeholder image is replaced (where appropriate) and visibility is set to visible. The href for the link is also set to the retrieved UserUrl.

Upload the HallOfFame.js file to a library within your site (The Style Library of the root site of a site collection is a great spot!).

csrShim Setup

To use csrShim, a CQWP only needs 2 files:

Place these in a library within your site (The Style Library of the root site of a site collection is great spot for these!).

Configuring a CQWP to use csrShim

Adding a CQWP to a Page

On a web part page where you want to display your CQWP:

  1. Edit the page
  2. Click the Add a Web Part button in the zone where you wish your CQWP to end up
  3. Choose Content Query under Content Rollup (if you don’t have this option then the publishing features are not enabled)
  4. Using the web part dropdown, choose Edit Web Part to open the toolpane
  5. Expand the Query section and select Show items from the following list then click Browse and locate the Hall Of Fame list created earlier:
    cqwp05
  6. Again, this is a simple example (generally a single list CQWP view is not a great use case for a CQWP). However, any query that returns results with the CQWP (even complicated ones) can still take advantage of CSR display using csrShim.
  7. Click OK and choose to Stop Editing the page
    cqwp06

You now have results on the page but only the Title field is showing and there is no custom display at all.

CQWP Configuration

Basic queries and sorting can be applied using the toolpane. However, you are fairly limited in how these results are displayed (including which fields are returned) and even in how complicated you can make your filters (query).

For all but the most basic CQWPs, you’ll likely end up manually editing the CQWP configuration either through SharePoint Designer or by exporting the definition, making your edits, and reimporting.

Since we used a web part page, we will simply use SharePoint Designer (SPD) to edit the configuration of the part directly. Other types of pages cannot always be edited in SharePoint Designer. In which case, you must apply the following changes into an exported web part definition file (XML). These changes are the same, but end up looking different from this example (You use property elements rather than setting the properties directly).

The easiest way to overcome this limitation is to use a web part page temporarily until your web part is properly configured using the below methods. Then export the web part from there and import into your other page types.

To edit the web part in SharePoint Designer:

  1. Connect to your site in SharePoint Designer
  2. In the navigation pane choose the library where you stored your page (if not listed, use the All Files node)
  3. Right-click on your page and choose Edit File in Advanced Mode
  4. SharePoint Designer often “helpfully” changes things that can cause problems. For instance, it is very common that it will escape double quotes within existing script blocks that should not be escaped. This will throw errors on your page.
  5. Look for the following:
    <SharePoint:ScriptBlock runat="server">
    var navBarHelpOverrideKey = &quot;WSSEndUser&quot;;
    </SharePoint:ScriptBlock>
    
  1. You will need to replace the values with actual double quotes (Again, this has nothing to do with this solution, this is just a common problem with SPD that may come up repeatedly):
    <SharePoint:ScriptBlock runat="server">
    var navBarHelpOverrideKey = “WSSEndUser”;
    </SharePoint:ScriptBlock>
    
  1. Look for the following:
    <SharePoint:ScriptBlock runat="server">
    if(typeof(MSOLayout_MakeInvisibleIfEmpty) == &quot;function&quot;)
    {MSOLayout_MakeInvisibleIfEmpty();}</SharePoint:ScriptBlock>
    
  1. Again, you will need to replace the values with actual double quotes:
    <SharePoint:ScriptBlock runat="server">
    if(typeof(MSOLayout_MakeInvisibleIfEmpty) == “function”)
    {MSOLayout_MakeInvisibleIfEmpty();}</SharePoint:ScriptBlock>
    
  1. Go ahead and save the page. In the Site Definition Page Warning dialog, click Yes:
    cqwp07

Using csrShim

To use csrShim, you need to tell the CQWP to use the csrShim stylesheet. The CQWP uses 3 stylesheets (Main, Item, and Header). Unlike most web parts with a single XslLink property, the CQWP has one for each.

We will only use the Main, but you must provide a link for the Item and Header values or your web part will get an error. That is where the EmptyStyleSheet included with csrShim comes in handy.

  1. Add the MainXslLink property directly to the ContentByQueryWebPart element on your page and give it the address of the xsl stylesheet
  2. Add the HeaderXslLink property directly to the ContentByQueryWebPart element on your page and give it the address of the xsl stylesheet
  3. Add the ItemXslLink property directly to the ContentByQueryWebPart element on your page and give it the address of the xsl stylesheet
    cqwp08
  4. Save the page in SPD and refresh it in the browser. You should now see many more fields in a strange display (this is the OOTB template-less CSR view)
    cqwp09

Adjusting the Query

Now we’re getting somewhere! Clearly, this isn’t the display we’re going for just yet but csrShim is in place and ready to have a JS Link file applied.

First, however, it’s a good idea to get your query adjusted before introducing the complication of custom rendering. Often, you’ll accomplish this by using the QueryOverride attribute with your own CAML. For this example, we want to return all the items but we want it sorted in order of creation, ascending. For simple sort changes, we’ll just use existing properties (we could have done this in the toolpane as well).

  1. By default, the SortBy attribute should already be set to Created. The SortByDirection is set to Desc by default. Change this to Asc and Save the page in SPD.

Additional Fields

If you look through the many fields that are returning on the page, you’ll notice that the Person and Color fields are missing. You can request additional fields using the CommonViewFields property:

  1. Add the CommonViewFields property directly to the ContentByQueryWebPart element on your page and give it the value of Title,Text;Person,User;Color,Text;
    cqwp10
  2. Save the page in SPD

Refreshing the page in the browser will show that the values for these columns are now showing up, yay!

A Note about Field Types

Although there is a Choice option for the type (the text following the comma after the internal name), Text always works and Choice only sometimes. In the sample’s case, either is fine, but a multi-choice column will cause your CQWP to not return any data if Choice is used but will work fine with Text. Therefore, it is recommended to always use Text for Choice columns.

Other types that can be used:

  • Text
  • Note
  • Number
  • Currency
  • Integer
  • Boolean
  • DateTime
  • Threading
  • Lookup
  • Choice
  • URL
  • Counter
  • DisplayOnly
  • RichHTML
  • Image

Applying Client Side Rendering

Technically, we’ve already applied client side rendering simply by using csrShim as the stylesheet. If you check using your development tools, you’ll find a ContextInfo object in the global namespace (likely ctx500).

cqwp11

Now to apply our JS Link file to the CQWP!

With list views, you can simply open the toolpane and put your script reference(s) in the JS Link property of the XSLTListView web part. There is no JS Link property on the CQWP. Instead, csrShim exposes several parameters including a JSLink parameter where we can specify these. This is done through the CQWPs ParameterBindings element.

  1. Add a ParameterBindings Add a ParameterBinding element with a Name of BaseViewID and a Default value of 40. Add another ParameterBinding element with a Name attribute of JSLink and a Default value of the address to the HallOfFame.js file we uploaded earlier.
    cqwp12

    <ParameterBindings>
      <ParameterBinding Name="BaseViewID" Default="40"/>
      <ParameterBinding Name="JSLink" Default="/Intranet/Style Library/csrShim/HallOfFame.js"/>
    </ParameterBindings>
    

If you refresh the page, you’ll see the glory that is CSR with a CQWP!

cqwp13

Best Practices for csrShim with CQWPs

  • Set the XslLink for ALL 3 CQWP properties
    • MainXslLink = address of csrShim.xsl
    • ItemXslLink = address of EmptyStyleSheet.xsl
    • HeaderXslLink = address of EmptyStyleSheet.xsl
  • Use the CommonViewFields property of the CQWP to include additional fields
  • Use Text for Choice fields in the type portion of the CommonViewFields property
  • If fields are coming back as GUIDs instead of their internal name, use the DataMappings property of the CQWP
  • Provide a unique BaseViewID to prevent conflicts with the default value of 1 (standard CSR with list views uses this value)
  • If reusing JSLink files between CQWPs, list views, and/or feeds, use the ctx.ShimType property to create conditional property retrieval as needed

Changing Web Part Properties When the Page is Unavailable

Applies To: SharePoint

The other day we made some changes that caused some issues with how one of our web parts was configured. Unfortunately, I hadn’t wrapped the problem in a try/catch and my error blew up the whole page. I’m sure I’m the only one that’s ever done that. So obviously I’ve got some code changes to make, but what do I do in the meantime? Fortunately, there’s some straight forward Powershell that lets you change web part settings (even custom properties like mine).

I found the solution to this over on Aarebrot.net where he was using the technique to change a web part that automatically redirected the user. I’ve just reproduced his code here and added some explanation and background.

When I first went to solve this problem I tried the ?contents=1 querystring trick to pull up the Web Part Administration page. If you’re looking for a quick solution you can add that query string to the end of your page’s URL and then delete the web part from the page and start over. But a more elegant solution is to just change the offending property using some easy Powershell.

Using the SharePoint 2010 Management Shell, run the following commands:

$web = Get-SPWeb "http://somedomain.com/sites/someweb"
$page = $web.GetFile("default.aspx")
$page.CheckOut()
$wpm = $web.GetLimitedWebPartManager("default.aspx",[System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
$part = $wpm.WebParts[0]
$part.SomeProperty = "The correct setting!"
$wpm.SaveChanges($part)
$page.CheckIn("Fixed that property")
$page.Publish("Fixed that property")
$web.Close()

What Just Happened?

In line 1 we’re just getting a reference to the web site (SPWeb) where your web part lives using Get-SPWeb. Just replace the URL shown with yours.

Lines 2-3 and 8-9 are only required if the page you’re modifying is on a publishing site or check in/out is required. Feel free to skip these (go directly to line 4) if you’re just editing a simple page. If your page does require check out to be edited, line 2 is simply retrieving the file (SPFile) using the GetFile method using the relative location of the page. Then line 3 calls the CheckOut method which, of course, checks out the file.

In line 4, we’re grabbing a reference to the Web Part Manager for the page (SPLimitedWebPartManager) using the GetLimitedWebPartManager method. Just replace the first parameter with the relative location of your page. The second parameter is the PersonalizationScope enumeration and can be User or Shared. You’re going to want to use Shared to affect everybody. The Web Part Manager object is what lets us get access to all the web parts on the page and screw with em.

In line 5, we grab the web part (WebPart) we want by index using the WebParts collection. In the example above I already knew that the web part I wanted was the first one in the collection. You can also pass the uniqueID property of the web part (instead of the index). You can find out both by simply calling the WebParts collection by itself ($web.WebParts) and everything will get listed to the screen.

To see all the available properties of the web part you can just type ($part) and it will list everything out including any custom properties. Then you can just set them like we do in line 6.

Line 7 uses the Web Part Manager’s SaveChanges method to incorporate all your changes. Lines 8-9 are again only required if your pages library requires check in/out and publishing. If it’s a simple page just skip to line 10. Line 8 uses the CheckIn method which takes a string for a check-in comment. Line 9 uses the Publish method which also takes a string for a comment.

Line 11 just calls the Close method and ensures we clean up all our resources.

That’s it! Now you can wrap that up in a script to loop through multiple pages and change properties on all sorts of web parts or just one-off fix those web parts you might have broken.

Refinement Panel Customization Saving Woes

Applies To: SharePoint 2010

Editing the Filter Category Definition of a Refinement Panel web part can make your search result pages so much better. This is one of the first things we customize and every time we do, I get tripped up by a really annoying setting in the web part.

Problem Scenario

I replace the XML in the Filter Category Definition property in the Refinement properties section of the web part. I hit Apply and everything validates. I save the page and run the results – No custom refinements! In fact, when I open the web part back up for editing, my custom Filter Category Definition is totally wiped out! Why isn’t it saving!?!?!?! Why am I weeping ever so softly?!?!! Why would I confess that on the internets?!?!?!?!

Solution

There’s a checkbox at the bottom of the Refinement properties section labeled, Use Default Configuration. This is checked by default. Unless you uncheck this when you place your custom XML in the property, it is going to completely ignore you and replace it with the default XML.

RefinementSettings

I can see why things work this way, but it is extremely unintuitive. It would seem that the web part should recognize there is custom XML in the Filter Category Definition and understand that’s what it should use. Then a button (NOT a checkbox) that says something along the lines of “Revert to Default Configuration” would be used to reset that XML when needed.

Oh well, nobody is asking my opinion anyway. So do yourself a favor and remember to uncheck that box whenever customizing the Filter Category Definition.

Broken Add New Document Links

Applies To: SharePoint 2010

We ran into an interesting problem the other day where a user called and said that everytime they clicked the Add New Document link they got a giant error message. I went to the site and was able to confirm that it was indeed blowing up.

This was only happening when the document library was being exposed through a web part on another page. Going directly to the library and clicking New Document or Upload Document in the ribbon worked just fine. The problem was obviously with the web part toolbar, which in this case was set to Summary Toolbar.

It appears this is something left over from our upgrade from SharePoint 2007 to SharePoint 2010. I would’ve thought the Visual Upgrade would have fixed this and it’s amazing no one noticed for well over a year! It seems that Microsoft changed not only the look of the link (switching the icon from a little square to a green plus and removing the word new) the underlying address also changed.

AddNewDocumentLink
Broken Old Style Link
NewDocumentLink
Correct Style Link

Taking a look at where these links were pointed, I could see that the old style link was pointed at listform.aspx:

/_Layouts/listform.aspx?PageType=8&ListId={LISTGUID}?RootFolder=

While the new style link was pointed at Upload.aspx:

/_layouts/Upload.aspx?List=LISTGUID&RootFolder

Fixing this is pretty easy. Just edit the web part and change the Toolbar Type to No Toolbar and click Apply:

ToolBarTypeNone

Then immediately switch the Toolbar Type back to Summary Toolbar and press OK:

ToolBarTypeSummary

Interestingly, other web parts sometimes show the old style link too (links, announcements, etc.) but since these all seem to still use the listform.aspx they continue to work. However, you can use the above technique to get them to match visually as well (green plus icon).