How to display correct document links in the search results.
At the recent client project there were an interesting situation. They had a web part that was looking pretty much like a list with the only difference - it was a Content Search webpart and it was supposed to show certain the documents from all subsites. Pretty usual request.
However, the client pointed out, that the links are not the same as if they would use the "normal" documents view. The client was not happy that the links suggest to download the file instead of opening in Word/Excel/etc.
I have started to look.
There were a number of reasons why the links were different.
First reason is that they use Path managed property.
Path managed property gives what it gives. The path.
Like this
https://sp131:82/Documents/excel1.xlsx
But it does not respect existence of the Excel services or the OWA.
So I found this blog post
https://www.eliostruyf.com/three-useful-managed-properties-for-working-with-office-web-apps/
That was probably the only one explaining other important managed properties
- ServerRedirectedURL
- ServerRedirectedPreviewURL
- ServerRedirectedEmbedURL
So I have used the ServerRedirectedURL. At the customer environment it returns a link to OWA, like this:
https://server/_layouts/WopiFrame.aspx?sourcedoc={E526E4B1-6759-448F-B6C6-0C67E942173B}&file=Documents/excel1.xlsx&action=default&DefaultItemOpen=1
At my local SharePoint dev single server machine it looked like this
https://sp131:82/_layouts/15/xlviewer.aspx?id=/Documents/excel1.xlsx&DefaultItemOpen=1
Another difference was the way the links work. In the library itself the links tried to open the corresponding app - word or excel or the OWA. In the search results there were no prompt for opening the App.
There is a setting that affects this behaviour It is well described in this article
https://technet.microsoft.com/en-us/library/ee837425.aspx
You can find it under "advanced" settings in the document library, and there are some other system wide settings that affect it.
I have looked at the links in the list and found out that the links look like this
When the library setting is like "open in the client application".
<a class="ms-listlink ms-draggable" href="/Documents/doc1.docx" onmousedown="return VerifyHref(this,event,'0','SharePoint.OpenDocuments','')" onclick="return DispEx(this,event,'TRUE','FALSE','FALSE','SharePoint.OpenDocuments.3','0','SharePoint.OpenDocuments','','','','1','1','0','0x7fffffffffffffff')" dragid="1" draggable="true">doc1</a>
When the library setting is like "open in the browser".
<a class="ms-listlink ms-draggable" href="/Documents/doc1.docx" onmousedown="return VerifyHref(this,event,'1','SharePoint.OpenDocuments','')" onclick="return DispEx(this,event,'TRUE','FALSE','FALSE','SharePoint.OpenDocuments.3','1','SharePoint.OpenDocuments','','','','1','1','0','0x7fffffffffffffff')" dragid="1" draggable="true">doc1</a>
In my case the customer was ok with hardcoding the option one. So the final resulting code was like this
<!--#_ var linkURL = $getItemValue(ctx, "Path"); linkURL.overrideValueRenderer($urlHtmlEncode); var ServerRedirectedURLValue = ''; var ServerRedirectedURL = $getItemValue(ctx, "ServerRedirectedURL"); ServerRedirectedURL.overrideValueRenderer($urlHtmlEncode); ServerRedirectedURLValue = ServerRedirectedURL.defaultValueRenderer(ServerRedirectedURL); if ( (ServerRedirectedURLValue == null) || (ServerRedirectedURLValue == undefined) || (ServerRedirectedURLValue == '')) ServerRedirectedURLValue = linkURL.defaultValueRenderer(linkURL); var onmousedown = "return VerifyHref(this,event,'0','SharePoint.OpenDocuments','1" +ServerRedirectedURLValue +"')"; var onclick = "return DispEx(this,event,'TRUE','FALSE','FALSE','SharePoint.OpenDocuments.3','0','SharePoint.OpenDocuments','','1"+ServerRedirectedURLValue+"','','2','0','0','0x7fffffffffffffff')"; _#--> <a class="cbs-Line1Link ms-noWrap ms-displayBlock" onmousedown="_#= onmousedown =#_" onclick="_#= onclick =#_" href="_#= linkURL =#_" title="_#= $htmlEncode(line1.defaultValueRenderer(line1)) =#_" id="_#= line1LinkId =#_">_#= line1 =#_</a>