Wednesday 21 August 2013

Working with web parts within a SharePoint app

I’ve previously mentioned that “you don’t get very much” when you start creating an app which has some SharePoint-hosted components (e.g. pages). You get a bare bones ASPX page, and from there it’s down to you as the developer. Whilst playing around with apps I’ve found it interesting to experiment by adding out-of-the-box components (e.g. web parts/controls in the SharePoint namespace) to app pages. The results are quite interesting, and lead to a couple of findings which might be useful tricks in the toolbox. If nothing else, you might find this an interesting “leftfield” post about some questions you hadn’t thought to ask.

Before we dive in, here’s where we are in my overall app series:

  1. SharePoint 2013 apps – architecture, capability and UX considerations
  2. Getting started – creating lists, content types, fields etc. within a SharePoint app (provisioning)
  3. Working with data in the app web, and why you should
  4. Access end-user data (in the host web) from a SharePoint 2013 app
  5. Rolling out SharePoint 2013 apps to the enterprise - tenant scope and PowerShell installs
  6. Azure is the new SharePoint ‘_layouts’ directory
  7. “Host web apps” – provisioning files (e.g. master pages) to the host web
  8. “Host web apps” – provisioning fields and content types
  9. Deploying SP2013 provider-hosted apps/Remote Event Receivers to Azure Websites (for Office 365 apps) 
  10. Working with web parts within a SharePoint app [this article]

Deploying web parts within an app

If you create a SharePoint-hosted app, you might notice that the default page you get is an ASPX page rather than HTML. Also, it has several declarations at the top, allowing SharePoint controls to be used:

App page default markup 

The idea here is that you might want your app to take advantage of some SharePoint building blocks (web parts/controls) rather than recreating that functionality from scratch. But since you don’t have the full page editing model in an app (it’s not SharePoint content that a contributor would edit, after all), any web parts would have to be included in the markup of the page (by the developer). I did some testing to see which web parts appear to work, and this post is really about my findings.

I expanded the markup to include some common web parts within web part zones (and added any @Register directives which I started to need). My markup was then:

** N.B. My newer code samples do not show in RSS Readers - click here for full article **

Which web parts can I (probably) use within an app?

Here’s a summary of my results:

Web part

Usable?

Content Query web part No
Content Search web part Yes
XsltListView web part Yes
Core Search Results web part Yes
Page Viewer web part Yes
Data View web part No
Result Script web part (for search results) No EDIT: Yes

Content Query web part:

The CQWP appears to be a flat “no”. If you don’t have publishing enabled on the host web, you’ll get this:

CQWP
This seems to be related to being unable to fetch ContentQueryMain.xsl. I notice it is a 401 rather than a 404, which is kinda interesting, but anyway if you activate publishing you then get:

CQWP 2

So, it feels like the Content Query web part may not have received any attention to make it work within an app web. It’s worth noting here that path to the XSL references the app web (in my case, https://cob-387fbe6473fe0b.spapps.dev/Style%20Library/XSL%20Style%20Sheets/ContentQueryMain.xsl)– although it is “structurally” correct (in that the Style Library is referenced at the root), I think effectively it’s not possible to “browse” host web content on the app web domain. I even tried providing an absolute host web URL to the XSL file, but that fails also with the ‘page not found’ error.

So, perhaps the CQWP would need to be re-engineered for it to work within an app.

Content Search web part:

This web part appears to work fine, which is good news:

Content Search web part

It’s worth knowing that Display Templates are still pulled from the host web (master page gallery), but it seems no problems arise from that.

XsltListView web part:

As I’ve mentioned in previous articles, it’s somewhat confusing the first time you add a list to an app you are developing - by default, there’s nothing on the page (e.g. a navigation link to the list) which tells you if the list is being provisioned successfully. However, since you’ll know the list URL, typing the address in the browser address bar shows it is there. To display items from the list, you’ll most likely want to use the XsltListView – you’ll need to add the markup to one of your pages manually. And when you do, you’ll see that displaying items from a list in your app web works just fine:

List view web part

I wondered if it was possible to use this web part to show items from a list in the host web. Putting aside potential issues of including a token such as ~site in the URL (by testing with a hardcoded absolute URL), I found that it is not:

XsltListViewWebPart - host web 

Page Viewer web part:

The idea of using the Page Viewer web part in an app could be quite interesting. I was intrigued to see if I could display a page from the host web within my app, and I found that it is, with caveats (below). The image below shows just that – a page from the host web. Some points:

  • The “This page is allowed to be IFramed” message is just some text on the page
  • The yellow “customized” message is because I manually edited the page in SPD to add the <WebPartPages:AllowFraming ID="AllowFraming" runat="server" /> tag. If this was provided by something else higher up (page layout/master page), this message would not be present

Page viewer web part

But the main caveat is probably that it all works fine with a hardcoded/absolute URL, but tokens such as ~site do not appear to work. So in real life you might struggle if you need to have any kind of relative URL here. Still, useful to know perhaps.

Result Script web part (search results):

[UPDATED AUGUST 22 2013: Scot Hillier got in touch, telling me that it IS possible to use this web part. The solution can be found at the bottom of this section.]

[Original text follows, to show errors you might run into:] The Result Script web part is effectively the modern day “search results” web part in SharePoint 2013. It can be used to display the results from a given search query – it is the web part used on the default SP2013 search results page, and very powerful it is too. It seems like this one should work in a SharePoint-hosted app, but I just couldn’t quite get there. I’m hoping I’ve overlooked something and it is actually possible, because the issue seems to simply be getting the right format of escaping quotation marks in the search query (the DataProviderJSON property). I tried various forms, but I either see this:

Result script web part

..or this:

Result script web part 2

Permutations of quotation marks/escape characters I tried include:

  • \”
  • ””
  • ..and so on

UPDATED – THE SOLUTION (thanks Scot!):

  • The answer is to use XHTML encoding of the quotation marks – i.e. &quot; 

When you do this, you’ll see the Result Script web part does actually work within your app:

Result script web part - working

So, that’s good news, and means that we CAN take advantage of this web part inside an app! 

This seems a shame, because I can imagine lots of apps which might want to display search results. For these apps, a nice web part cannot be used – code will be needed, such as I show in Calling SharePoint search using REST (e.g. from JavaScript or an app).

Core Search Results web part:

Although it turns out to be possible to use the Result Script web part, if for any reason it’s not right for your circumstance there’s always the Core Search Results web part – this is the search results web part you know and love from earlier versions of SharePoint. It uses XSL (instead of JavaScript display templates) for rendering and doesn’t have the sophisticated Query Builder (which you wouldn’t be able to use within an app anyway), but works fine for showing search results on a page:

Core Search Results web part

Conclusion

Some web parts can be used within an app, some cannot. In terms of other types of controls (e.g. SharePoint server controls), I found that the SafeControl settings of the web.config used by apps are more restrictive than normal – several namespaces and specific controls are marked as unsafe, so many server controls will be off-limits in an app page. Still, it’s quite possible that some can be used – more testing would be needed here.

The usual mantra should apply to developers of SharePoint apps as in general – check if there’s something in the box which can be used before you write code. It could be that something in there saves you considerable effort.

Next time - Using app parts (ClientWebPart) to bring app elements into the host web

8 comments:

Anonymous said...

The word manual is used so many times in this article that I can only conclude that once again, Microsoft has released a version of SharePoint (2013 in this case) without a first-class development toolset.

We saw this story for the first time back when SharePoint 2007 was released with near-zero development tools in Visual Studio 2005, the IDE for customizing SP 2007 at that time.

It wasn’t until Visual Studio 2012 that a full set of tools (e.g., content type wizard) was available for SharePoint 2010.

Now we read article after article about how you can “almost” do this or that with SharePoint 2013 and Visual Studio 2012 or 2013 Preview, but “you need a shim here and another bolt-on thingy over there” to make it really work in a production environment.

When are we going to get a proper set of tools from Microsoft for customizing SharePoint? I fear the answer is somewhere between “maybe” and “never”.

Chris O'Brien said...

@Anonymous,

I think it depends on your expectations. If you ever developed for other enterprise products such SAP, Salesforce, or other ECM platforms such as FileNet, you'll know that SharePoint is certainly no worse. In fact, it's probably much better.

Of course, if you're comparing to developing on a thinner/lower-level platform (where frankly, there are less moving parts) such as .NET or Java, then sometimes SharePoint does feel as though there's more friction. But that's because there usually is! Personally I'm not sure it's realistic to expect anything else.

It's a complex platform and developers and users will always occasionally want to explore some slightly unorthodox approaches (just like this post). But it's also helpful to recognise those as such - in the case of this article I'd say:

- no-one says you MUST use the "apps" framework in SharePoint
- Microsoft don't provide guidance to say that web parts can be used there - I see this stuff purely as a bonus which saves me some code

Would you disagree?

Chris.

Ralf said...

Excellent and extremely valuable exploratory work! Thanks for sharing Chris.

Ben Haynes said...

Hello Chris
Great Article. I found that after adding the XsltListViewWebPart the "edit this list" link did not work and returned a JavaScript error. This can be fixed by adding a script reference to SP.UI.Dialog.js to the page. Hope this helps someone.

Ben

Swati Jain said...

Hi Chris,

I like this post very much.
I have a query.The XSLTList view example references list is AppWeb

How this can be done with OOB list in HostWeb for XSLT List view WebPart

Swati

Chris O'Brien said...

@Swati,

I have two samples for the XsltListViewWebPart, one for the host web and one for the app web. Above, I note:

"I wondered if it was possible to use this web part to show items from a list in the host web. Putting aside potential issues of including a token such as ~site in the URL (by testing with a hardcoded absolute URL), I found that it is not."

So I don't believe this is possible. You'll need to write some code (e.g. JSOM/REST) to pull the items from the host web, and display them yourself. My post Access end-user data (in the host web) from a SharePoint 2013 app might help.

Cheers,

Chris.

Unknown said...

Hi Chris

Thanks for the post. It really gave a starting point for our SharePoint App development.

One question though: Is it possible to manage permissions for the XsltListViewWebPart (the appweb version)? My goal is to display a list but I do not want users to edit or add items..

Thanks for a quick answer!

Fabian

Chris O'Brien said...

@Fabian,

Well, consider that if the user has "contribute" permissions to the underlying list, they will basically be able to add/edit items. And since the list in an app is provisioned *as part of the app*, this will be the case.

HTH,

Chris.