Contents tagged with SharePoint 2013

  • Announcing new Visual Studio 2012 tool for JavaScript Localization in SharePoint 2013

    Tags: SharePoint 2013, Visual Studio, Downloads

    In SharePoint 2013 JavaScript is the new default language and all our (at least mine) solutions and projects are using JavaScript more and more, even though everything is not built as SharePoint Apps. Farm or Full-trust solutions built using JavaScript will in many situations create a better user interface and an improved perceived performance. The more we build user interfaces using JavaScript we cannot just forget about some of the basic UX rules, such as using localization. End-users really hate when they see mixed content in different languages. We’ve known for quite some time how to do localization server-side, but how do we do it in a smart way in JavaScript?

    Localization in JavaScript

    As always when it comes to cool stuff my mate Waldek Mastykarz already covered this topic pretty well in his post called “Globalizing JavaScript in SharePoint 2013”. In that blog post he shows how you actually can use a feature in SharePoint 2013 that allows you to get JavaScript objects, generated from RESX files, to localize the user interface. His guide pretty well covers everything you need, but I’m going to re-iterate some of it here anyways, and here is a sample on how to do it.

    Assume that you have a resource file (RESX) in your solution in a SharePoint Mapped folder (to the Resources folder). By adding a script link to the ScriptResx.ashx HTTP Handler with the resource file name and the culture as parameters you can get all the resources as a JavaScript object. For instance a simple Hello World alert in a Visual Web Part could looks something like this.

    First of all we need a resource file in the project (mapped to the Resources folder) and if you want localization, you of course have to translate it. This Resource file contains only one resource called HelloWorld.

    A Resource file

    To use this resource in JavaScript I have to write some code to load the ScriptResx.ashx HTTP Handler and pass in the name of the resource file and the name of the current culture.

    SP.SOD.executeOrDelayUntilScriptLoaded(function () {
      SP.SOD.registerSod("demoresources", 
        "/_layouts/15/ScriptResx.ashx?name=demoresources&culture=" + 
        STSHtmlEncode(Strings.STS.L_CurrentUICulture_Name));
    
      SP.SOD.executeFunc("demoresources", 'Res', function () {
        alert(Res.helloWorld);
      });
    }, "strings.js");

    In the sample above I use the Script-On-Demand (SOD) JavaScript functions to first make sure that the Strings.js is properly loaded. I need that to get the name of the current culture (String.STS.L_CurrentUICulture_Name). Then I do a SOD registration and registers the script link for the ScriptResx.ashx file using the name of the RESX file and the name of the culture. Finally I wait for the SOD to load and then shows an alert using the Res.helloWorld object.

    The ScriptResx.ashx file automatically creates a JavaScript object called Res and that object contains strings of all the resources in the RESX file. Note that the resources are using Camel Casing.

    What is the problem with this approach?

    This works fantastically great in most cases, and it is extremely hard to find anything on Waldeks posts that can be improved, but what if you don’t want to use the default namespace Res? It could be a matter of taste or a collision in names from different resource files. Fortunately there is a solution to this built into the ScriptResx.ashx HTTP Handler. You can actually specify two resheader elements in the Resource file to indicate that you want a custom namespace and the name of it – and this is exactly what SharePoint 2013 do for some of the built-in resource files.

    <resheader name="scriptResx">
      <value>true</value>
    </resheader>
    <resheader name="classFullName">
      <value>SPResXDemo.Resources</value>
    </resheader>

    The resheader with the scriptResx name attribute tells the ScriptResx.ashx handler that we would like to generate vanity namespaces and the one with the classFullName name attribute tells the handler the namespace to use.

    Unfortunately Visual Studio (not really, but the .NET ResXResourceWriter) does not handle this at all, as soon as you save your RESX file these two resheader elements will be removed. (And this is where I felt challenged!)

    SPResX to the rescue!

    To handle this situation and to be able to use custom namespaces for my JavaScript localizations I’ve created a small tool called SPResX that replaces the default RESX Custom Tool, the ResXFileCodeGenerator, and correctly preserves the resheader attributes.

    The SPResX tool can be downloaded from the Visual Studio Gallery and installed on any Visual Studio 2012 system, or found in the Extensions and updates in Visual Studio.

    SPResX in the Extension gallery

    Once you have the tool installed you just need to change the Custom Tool to SPResX and save you Resource files. You need to do this on all resource files, including the different language and region variants. Now you will get a namespace that corresponds to your default project namespace. For instance if I have a project called Wictor.WebParts, the namespace will be Wictor.WebParts.Resources (since it is in the Resources folder). If you would like some namespace that is completely different, then you can just specify that namespace in the Custom Tool Namespace. (Yes, I know you will get a notification that the file has to be reloaded – that is just the way it is).

    Configure the Custom Tool

    This is how the code from above can then be re-written using this tool, it works in the exactly same way but with a fancy vanity namespace of the resources.

    SP.SOD.executeOrDelayUntilScriptLoaded(function () {
      SP.SOD.registerSod("demoresources", 
        "/_layouts/15/ScriptResx.ashx?name=demoresources&culture=" + 
        STSHtmlEncode(Strings.STS.L_CurrentUICulture_Name));
    
      SP.SOD.executeFunc("demoresources", 'SPResXDemo', function () {
        alert(SPResXDemo.Resources.helloWorld);
      });
    }, "strings.js");

    Summary

    I hope this little tool will help somebody out there and I would appreciate feedback on it, either on this post or in the Visual Studio gallery.

  • SharePoint 2013: Enabling PDF Previews in Document Libraries with Office Web Apps 2013

    Tags: SharePoint 2013, Office Web Apps

    Introduction

    A couple of weeks back I blogged about the March Update for Office Web Apps 2013 and also how you could use that update to show PDF previews in a SharePoint 2013 Search Center. Since then I’ve received a lot of requests on how to enable PDF Previews in a Document Library, which isn’t there by default. Of course it is not a WAC thing, it’s a SharePoint 2013 thing – but the SharePoint 2013 updates (up until now at least) does not provide this capability either.

    In this post I will show you that it can be done. It’s a JavaScript thing and can be done using a Content Editor Web Part added on all pages where you want the PDF previews or as Farm solution which uses a delegate control and a custom JavaScript file.

    Build the PDF Preview solution

    I assume that you are familiar with SharePoint 2013 development and knows what a delegate control is. What you need to do is create a new empty Farm solution project. In this project we’ll create a new web control that will add a JavaScript (which we will create in just a minute) to the page. The implementation should look like below:

    [MdsCompliant(true)]
    public class PdfPreviewControl: WebControl
    {
        protected override void OnPreRender(EventArgs e)
        {
            ScriptLink.RegisterScriptAfterUI(this.Page, "wictor.pdfpreviews/previews.js", false);
        }
    }

    The JavaScript file, added as a Layouts file, is what makes the magic happen. We’re using the Script-On-Demand features in this script to make sure that the scripts aren’t executed before the SharePoint filepreview.js file is loaded. Once that file is loaded two new JavaScript objects are created; the filePreviewManager and the embeddedWACPreview. To enable the PDF previews we only need to add the PDF extension to these objects and specify the previewer objects and the dimensions. In this case I use the same settings as the other Word previewers.

    function WictorsPdfPreviews() {
        SP.SOD.executeOrDelayUntilScriptLoaded(function () {
            filePreviewManager.previewers.extensionToPreviewerMap.pdf = 
                [embeddedWACPreview, WACImagePreview];
            embeddedWACPreview.dimensions.pdf= { width: 379, height: 252}
        }, "filepreview.js");
        notifyScriptsLoadedAndExecuteWaitingJobs("wictor.pdfpreviews/previews.js");
    }
    WictorsPdfPreviews();

    Now we need to make sure that this control loads the JavaScript on all pages. This is done by adding a new Empty Element SPI and creating a Control element pointing to the web control, like this:

    <Control 
      ControlAssembly="$SharePoint.Project.AssemblyFullName$" 
      ControlClass="Wictor.PdfPreviews.PdfPreviewControl" 
      Id="AdditionalPageHead" 
      Sequence="100"/>

    As you can see we’re adding this control to the AdditionalPageHead, which means that we will have it on every page. Do not forget to add the web control as a Safe Control in the project!

    The final thing we need to do is to modify the Feature that was automatically created when the Empty Element SPI was added to the project. You can scope it to whatever you like, but I want it for all Document Libraries in my farm so I set the scope to Farm. The image below shows all the files in the project.

    The Visual Studio 2012 solution

    Deploy and Test

    Now all we have to do is to deploy the solution. Once the solution is deployed and the Farm feature activated we can navigate to any document library and upload a PDF file. Note that you have to be on at least the March 2013 update of Office Web Apps Server and that you have enabled the WordPDF application (see previous blog post). Once you have the PDF file in the library you can click on the ellipsis button and see the PDF Preview:

    PDF Previews in SharePoint 2013

    Disclaimer

    As always when it comes to stuff that is not documented. I do not give any guarantee that this will work on your machine(s) or after any upcoming SharePoint patches.

    Summary

    Enabling PDF Previews are not (yet) a default feature of SharePoint 2013 but can easily be added to your SharePoint farm – if you’re allowed to use Full Trust solutions.  If you don’t feel like you want to do some hacking yourself you can download the WSP here and deploy it yourself to try it out.

  • Recertified as Microsoft Certified Solutions Master (MCSM) for SharePoint

    Tags: MCSM, SharePoint, SharePoint 2013

    Yesterday I got the really cool news that I completed all recertification requirements for the Microsoft Certified Solutions Master: SharePoint certification. Couldn’t be a happier SharePoint professional right now!

    MCSM: SharePoint

    What is the MCSM and what about MCM?

    The Microsoft Certified Master (MCM) program has during the latest year transitioned into the Microsoft Certified Solutions Master (MCSM) program. It is not only a change in name but also a change made to adapt to the new world order. The program is not longer focusing on one specific version of the product but instead focus on what’s in the market at the current moment and specifically it covers both on-premise and cloud solutions. This is good in many senses – this allows the program to always be current, always use the latest techniques and technologies etc. The MCM was a certification without expiration date (well eventually the product cease to exist, but you still have the cert) whereas the MCSM has a three year life span and you must recertify to stay on top.

    The first MCSM : SharePoint rotation!

    I was fortunate to be able to participate in the rotation called U3, or Upgrade 3, which was the first MCSM rotation for SharePoint. It was two weeks on site, in the always sunny and warm Seattle, in January. I had the opportunity to spend these two weeks in a class room with the finest SharePoint professionals there is. We had great instructors, awesome labs, and fantastic discussions over the two weeks duration. It all led up to one written exam, called the Knowledge Exam, and one hands on lab, called the Qualification Lab. As always the QL was basically doing a couple of weeks worth of deep dive SharePoint work in about 8 hours time. Taken into account that this was a beta it was just about the hardest work I’ve ever done – but it was pure fun. And I made it! Phew…

    Congrats to all my other friends that made it through this rotation and best of luck to the ones who will have the joy of doing the exams one more time! You can do it!

  • Introducing Open WOPI - an open WOPI Client for SharePoint, Exchange and Lync

    Tags: SharePoint 2013, WOPI, Office Web Apps, Open WOPI

    Today at the SharePoint Evolutions 2013 Conference I announced my latest pet project called Open WOPI. Open WOPI is an open WOPI client that allows you to extend SharePoint 2013, Exchange 2013 and Lync 2013 with file previews and editors for any type of file formats.

    Open WOPI

    The project is now (at least very, very soon) available to download from openwopi.codeplex.com and is published under the Ms-PL license. This is currently an early beta (or what you would like to call it) but will be improved over time.

    Standards

    Open WOPI is based on the [MS-WOP] protocol, published by Microsoft, and used by Office Web Apps Server 2013, SharePoint 2013, Exchange 2013 and Lync 2013.

    File format support

    Currently Open WOPI has support for the following formats:

      • GPX - Uses Bing maps
      • TXT - Viewing and editing
      • VSDX - Thumbnail viewing

    More formats are in the works…

    Documentation

    Not much yet, but I’ll try to add that over the next few weeks.

    More information

    For more information, feedback and ideas about the project please refer to the Codeplex site: openwopi.codeplex.com. I’d like to hear what file formats you would like Open WOPI to support.

    The slides from the presentation at the SharePoint Evolutions conference and links can be found here.

    Contributors

    Thanks to Sam Dolan, aka Pinkpetrol, for the really cool logo for Open WOPI.

  • SharePoint 2013: Enabling cross domain profile pictures

    Tags: SharePoint 2013

    Just discovered a really interesting and just awesome nugget in SharePoint 2013 that solves a problem that have been annoying me for a long time. The problem manifests itself when you’re having multiple URL’s for your SharePoint farm or when using SAML or Forms based login (like in Office 365 and SharePoint Online) and you’re using the profile pictures on sites not residing on the My Site Host Web Application (or host named site collection). Then the user profile picture is not shown, you get the default image not found image or you’re prompted to authenticate with the My Site Host.

    Let’s take an example. Assume I have one site at intranet.contoso.com and the My Site host exists on mysite.contoso.com. I have not configured any Internet Explorer zones or anything and I’m promted to log in at each location. This is how the Newsfeed Web Part will look like on intranet.contoso.com, if I cancel out the authentication prompt or if I’m using some forms based login:
    No picture...

    You see, no fancy picture of Mr administrator! There’s a couple of ways to solve this using IE Zones, anonymous access etc, but none are perfect and comes with consequences.

    So how can I get the picture to be shown without messing with security, cross domain issues etc. Fortunately I guess I was not the only one that was annoyed by this (most likely everyone using Office 365 as well) so the SharePoint team has added a new feature to SharePoint that allows us to show profile pictures cross-domain.

    It’s a very simple operation and just requires some basic PowerShell skills. Basically all you need to do is to set the CrossDomainPhotosEnabled property on the SPWebApplication object to true, like this:

    asnp Microsoft.SharePoint.PowerShell
    $wa = Get-SPWebApplication http://intranet.contoso.com
    $wa.CrossDomainPhotosEnabled = $true
    $wa.Update()

    Now the Newsfeed, in the sample above, will look like below. And I was not prompted for any authentication or anything! Isn’t that sweet! And it works very well on Host Named Site Collections as well.

    Look at that guy!

    Basically what happens behind the scenes is that the request for the user picture is sent via a “proxy” .aspx page called userphoto.aspx which takes a couple of parameters; URL of the picture, the account name (or e-mail) as well as the picture size (S, M or L). This page will return a JPEG stream of the user profile picture without crossing any domains on the client side.

    I hope this little nugget will save you and your customers a lot of time and annoyance..

  • SharePoint 2013 Managed Metadata field and CSOM issues in 2010-mode sites

    Tags: SharePoint 2013, SharePoint 2010, CSOM, JSOM

    Introduction

    SharePoint 2013 introduces a new model on how Site Collections are upgraded using the new Deferred Site Collection Upgrade. To keep it simple it means that SharePoint 2013 can run a Site Collection in either 2010 mode or 2013 mode, and SharePoint 2013 contains a lot of the SharePoint 2010 artifacts (JS files, Features, Site Definitions) to handle this. When you’re doing a content database attach to upgrade from 2010 to 2013, only the database schema is upgraded and not the actual sites (by default). The actual Site Collection upgrade is done by the Site Collection administrator when they feel that they are ready to do that and have verified the functionality of SharePoint 2013 (or you force them to upgrade anyways). But, the Site Collection admin might have to upgrade sooner than expected for some sites.

    Upgrade troubles

    This post is all about what has happened to us when our Office 365 SharePoint Online (SPO) tenant had been upgraded (and right now the Site Collection upgrade is disabled for us so we can’t do anything about it). The limitations of customizations in the 2010 version of SPO was very limited (to be kind) and we embraced JavaScript (which people have despised for a decade and now suddenly think is manna from heaven). We also leveraged Managed Metadata in a lot of lists, libraries and sites. We’ve built Web Parts using JavaScript CSOM to render information and also .NET CSOM stuff running in Windows Azure doing background work. Once our tenant was upgraded to 2013 all of the customizations using Managed Metadata stopped to work…

    JSOM sample with Managed Metadata

    I will show you one example of what works in SharePoint 2010 and what does not work in SharePoint 2013 when you’re site is running in 2010 compatibility mode.

    Assume we have a simple list with two columns; Title and Color, where Color is a Managed Metadata Field. To render this list using JSOM we could use code like this in a Web Part or Content Editor or whatever.

    var products;
    function loadProducts() {
    	document.getElementById('area').innerHTML = 'Loading...';
    	var context = new SP.ClientContext.get_current();
    	var web = context.get_web();
    	var list = web.get_lists().getByTitle('TestList');
    	products = list.getItems('');
    	context.load(products, 'Include (Title, Color)');
    	
    	context.executeQueryAsync(function() {
    		var collection = products.getEnumerator();
    		var html = '<table>'
    		while(collection.moveNext()) {
    			var product = collection.get_current();
    			html +='<tr><td>'
    			html += product.get_item('Title');
    			html += '</td><td>'
    			html += product.get_item('Color').split('|')[0];
    			html += '</td></tr>'			
    		}
    		html += '</table>'
    		document.getElementById('area').innerHTML = html;
    	}, function() {
    		document.getElementById('area').innerHTML = 'An error occurred';
    	});
    }
    ExecuteOrDelayUntilScriptLoaded(loadProducts, 'sp.js');

    As you can see a very simple approach. We’re reading all the items from the list and rendering them as a table, and this html table is finally inserted into a div (with id = area in the example above). This should look something like this when rendered:

    JSOM Rendering in SharePoint 2010

    The key here is that Managed Metadata in 2010 JSOM is returned as a string object (2010 .NET CSOM does that as well). This string object is a concatenation of the Term, the pipe character (|) and the term id. So in the code sample above I just split on the pipe character and take the first part. There was no other decent way to do this in SharePoint 2010 and I’ve seen a lot of similar approaches.

    Same code running in SharePoint 2013 on a SharePoint 2010 mode site

    If we now take this site collection and move it to SharePoint 2013 or recreate the solution on a 2010 mode site in SharePoint 2013. Then we run the same script, then this is what we’ll see, something goes wrong…

    Failed JSOM Rendering

    You might also see a JavaScript error, depending on your web browser configuration. Of course proper error handling could show something even more meaningful!

    JSOM Runtime exception

    Something is not working here anymore!

    What really happens is that the CSOM client service do not return a string object for Managed Metadata but instead a properly typed TaxonomyFieldValue. But that type (SP.Taxonomy.TaxonomyFieldValue) does not exist in the 2010 JSOM. Remember I said that SharePoint 2013 uses the old 2010 JavaScripts when running in 2010 compatibility mode. Unfortunately there is no workaround, unless we roll our own SP.Taxonomy.TaxonomyFieldValue class (but that’s for another JS whizkid to fix, just a quick tip to save you the trouble – you cannot just add the 2013 SP.Taxonomy,js to your solution).

    So why is this so then?

    If we take a closer look at what is transferred over the wire we can see that when running on SharePoint 2010 the managed metadata is transferred as strings:

    Fiddler trace on SharePoint 2010

    But on SharePoint 2013 it is typed as a TaxonomyFieldValue object:

    Fiddler trace on SharePoint 2013

    It’s a bit of a shame, since the server is actually aware of that we’re running the 2010 (14) mode client components! (SchemaVersion is what we sent from the CSOM and LibraryVersion is the library used on the server side)

    Fiddler trace on SharePoint 2013

    I do really hope that the SharePoint team think about this for future releases – respect the actual schema used/sent by the Client Object Model!

    Of course, this JavaScript solution will not work as-is when upgrading the Site Collection to 2013 mode. That is expected and that’s what the Evaluation sites are for.

    What about .NET CSOM?

    We have a similar issue in .NET CSOM, even though we don’t get a SharePoint CSOM runtime exception. Instead of returning a string object you will get back a Dictionary with Objects as values – but if you’re code is expecting a string you still get the exception. So in 99% of the cases it will fail here as well.

    Nothing exciting here, move along...

    Summary

    Deferred Site Collection update might be a good idea and you might think that your customizations will work pretty well even after an upgrade to SharePoint 2013, just as long as you don’t update your actual Site Collections to 2013. But you’ve just seen that this is not the case.

    Happy easter!

  • SharePoint 2013: Enabling PDF Previews with Office Web Apps 2013 March 2013 update

    Tags: SharePoint 2013, Office Web Apps

    In my last post (still smoking fresh) I showed you how to update your Office Web Apps 2013 farm to the March 2013 update, connect it to SharePoint 2013 and being able to view PDF documents in the browser. What I didn’t explain or show in that post was how to enable the PDF Previews in Search – but I’ll do it now.

    Pre-requisites

    Before you start fiddling with this, you need to make sure that you have the March 2013 update of Office Web Apps Server 2013 (WAC) installed and connected to your farm – if you don’t know for sure, ask your admins – sometimes they know…if they don’t give them the link to my previous blog post.

    Note: You don’t have to have a patched SharePoint 2013, this will work on the RTM bits.

    Default PDF Search Experience

    SharePoint 2013 natively supports crawling PDF documents, through the new document parsers. That is you don’t have to fiddle with any custom PDF IFilters etc. The native PDF document parser is a good enough solution, but have some room for improvements.

    The Search Experience and display in SharePoint 2013 is based upon Display Templates. Display Templates decide how the result should be shown and how the fly-out of the result should look like. For Office documents, when SharePoint 2013 is connected to a WAC farm, SharePoint displays inline previews which you can use to skim through the results really quick. For PDF this is not the case – not even if you use a WAC farm with the March 2013 update (even though the WOPI binding supports the interactivepreview action). This is a sample on how a PDF document could look like in SharePoint 2013 Search:

    Default PDF Search Experience

    Enabling PDF Previews in the Search Result

    Since we have the opportunity to modify the Display Templates and create our own Search Experience we can very easy modify the fly-out/hover panel of the PDF results to show the interactive preview. We can do this in two different ways…

    Create a new Result Type

    The easiest and fastest approach to enable our previews for PDF documents is by creating a custom Result Type. This is done by going to Site Settings > (Search) Result Types and then finding the PDF Result Type. Choose to Copy the Word Result Type. This will create a new Result Type.

    Copy the Result Type

    Give the new Result Type an appropriate name, “PDF with Preview” for instance. Then scroll down to Actions and in the “What should these results look like?” drop-down, choose to use the Word Display Template.

    Word or PDF?

    Then just click Save, go back to your Search Center and search for a PDF document and voilá – we have PDF Previews.

    PDF Previews in da house!

    Modifying the PDF Display Templates

    The second approach, which is a bit more advanced is to actually modify the PDF Flyout Design Template. You do this by going to Site Settings > Design Manager then choose 5. Edit Display Templates. Locate the PDF Flyout item by filtering on the Target Control Type column and use SearchHoverPanel, then scroll down to PDF Hover Panel. To modify the PDF Hover Panel, use the Word Hover Panel as a template. I’m not going in to all the details on how to modify the actual HTML file (see my similar post on how to achieve this here). But once you’ve modified it, make sure to save it to the gallery so the JS file is generated, and publish it. Now (if you made the correct updates) you will have Custom Search Previews for PDF documents.

    Summary

    You’ve now seen how you quick and easy can enable PDF Search Previews in SharePoint 2013 using the March 2013 update for Office Web Apps 2013. All you need to do is either create a custom Result Type and use the Word Display Templates or modify the default PDF Display Template. I really hope that Microsoft makes this a standard feature for upcoming SharePoint 2013 releases.

  • Office Web Apps 2013: Patching your WAC farm with no downtime

    Tags: Office Web Apps, SharePoint 2013

    I’m really glad to see some patches being rolled out for Office 2013, SharePoint 2013 and Office Web Apps 2013. There’s some really important fixes and some very interesting fixes that I’ve been waiting for. In this post we’ll take a look at the first Office Web Apps 2013 (WAC) update – specifically we’re looking at how to patch your WAC farm to minimize the downtime. If you follow my instructions you will have zero downtime (except for a brief moment where Excel stuff will not be accessible).

    Background and preparations

    RTM WACsFor this sample I will have a SharePoint 2013 (RTM) farm connected to a WAC 2013 (RTM) farm. The WAC farm is load balanced using NLB, like illustrated on the right.

    On order to update our WAC farm we need to download the March 2013 patch for Office Web Apps 2013. You can find it at Microsoft Download center and it is called “Update for Microsoft Office Web Apps Server 2013 (KB2760445)”. The KB article does not reveal much of what has changed, but if you take a look at an earlier patch KB2760486 (March 5th) you’ll notice some really cool things. If you don’t have time to read it – I’ll show you some of them at the end of this post. Ok, you do not have to install KB2760486, you only need the KB2760445 one.

    Patching the first WAC Server

    After downloading the patch and copying it to our WAC machines we can start the patching process. We would like to do this without the users even noticing it. First of all we need to take one of the servers out of rotation in the WAC farm. You do this using the load balancer. In my case I’m using Microsoft NLB and using PowerShell this is an easy task. Next thing to do is just remove the WAC server from the WAC farm – that is also a one-line PowerShell command. WAC Servers should only be patched with the binaries installed, not when they are participating in a WAC farm.

    These two lines does the trick:

    Get-NlbClusterNode -NodeName $env:COMPUTERNAME | Stop-NlbClusterNode -Drain
    Remove-OfficeWebAppsMachine
    
    NOTE: You MUST remove the machines from the old farm before patching and then later create a new WAC farm (follow the instructions thoroughly). You cannot patch a running WAC Farm!

    Once this is done the server is no longer receiving requests and it’s no longer a part of the WAC farm and we can start patching this machine. All our end-user requests are now going to the remaining server(s) in the WAC farm.

    One RTM and one patching going on...

    To patch the machine start the downloaded .exe file (wacserver2013-kb2760445-fullfile-x64-glb.exe) and just follow the instructions; accept license agreement etc. You will be asked to close any PowerShell (IDE) windows that has the Office Web Apps module loaded and you might get asked to reboot once the update is finished (there’s of course no harm in doing it anyways).

    When the patching is done (and you rebooted) we need to create a new WAC farm, on the patched server. You do this using the same way as you did for the RTM version. Use the same server name as your old farm, same settings and the same certificate.

    Patching the rest…

    Once the new farm is created you have a few options depending on how many servers you have in your WAC farm. For instance if you have more than two, then you can take another one out of rotation, patch it and join it to the new and patched farm and then you flip the load balancer so it points to the new WAC farm. Depending on your load balancer you might have a brief moment where end-user request might be served by both versions. A bit funky situation but it works, as the illustration below shows:

    Dual versions...

    In my case I have two servers, so once I created the new farm I just put the patched server into the NLB rotation and then immediately take the RTM server out of rotation. Once the RTM WAC Server is taken out of rotation I remove WAC from that machine and start the patching process. All requests to the WAC farm are now on our patched server(s).

    One March 2013 and the other one is being patched

    As you can see, simple PowerShell operations this time as well, and this can (and should) be automated.

    # On the new patched WAC Server
    Get-NlbClusterNode -NodeName $env:COMPUTERNAME | Start-NlbClusterNode
    
    # On the RTM WAC Server
    Get-NlbClusterNode -NodeName $env:COMPUTERNAME | Stop-NlbClusterNode -Drain
    Remove-OfficeWebAppsMachine
    
    

    Once the other server(s) are patched, you need to join it to the newly created (and patched) WAC farm – just as you normally join a server to a WAC farm. And then you’re done. You’re farm is now patched and ready! But wait, there’s some stuff you have to do on the SharePoint side to enjoy all the new cool features.

    All new and shiny!

    Configuring new WOPI bindings

    One of the most interesting new features in the March 2013 update of Office Web Apps is the ability to view PDF documents! Yup, you heard me right! The March 2013 update contains a couple of new WOPI bindings that enable viewing and previewing (even mobile views) for PDF documents. These new WOPI binding has an application name called WordPdf. If you try to use the New-SPWOPIBinding cmdlet and just specify the WAC server name, you will get an error – since you already have those WOPI bindings. What you need to do is to specify the name of the application as an extra parameter to the command, like this:

    New-SPWOPIBinding - ServerName wac.corp.local -Application WordPdf

    WOPI Bindings

    Another approach could be to remove all the bindings and then add them all back again – of course this would cause a few seconds of downtime, and that’s not how I roll…

    Once you’ve run that command (and waited a couple of seconds) you can start previewing PDF documents in your Document Libraries. And now we got yet another good reason not to install the crapware called Adobe Reader!

    Viewing PDF documents

    Now, your end users can start taking advantage of all the new features in the March 2013 update.

    New Excel WOPI Bindings!

    If you’re examining the WOPI bindings provided by the March 2013 update really carefully, you’ll notice that the Excel application has six new bindings, three each for the two new actions syndicate and legacywebservice. We cannot use these two bindings in SharePoint 2013 RTM – the New-SPWOPIBinding cmdlet does not accept those actions. They are not a part of the well-known WOPI action values (as specified in the WOPI specification available when this post is written) – and I have at the moment no clue of what they are doing…stay tuned…

    Summary

    You’ve just seen how simple patching an Office Web Apps 2013 farm is. Compare that to patching SharePoint! By using the load balancer effectively you can make sure that the end-users can continue to use the Office Web Apps features while you’re doing the patching. Enjoy!

  • SharePoint 2013: Intelligent Promoted Results and Best Bets

    Tags: SharePoint 2013

    Introduction

    The search engine and search experience in SharePoint 2013 has been totally re-written, since its predecessors. In SharePoint 2010 we had something called Best Bets or Visual Best Bets if you worked with FAST for SharePoint. A best bet was a promoted result that was triggered by one or more keywords, used by the search admins to promote certain links or banners for specific search queries. In SharePoint 2013 this is now called a Promoted Results and the procedure of creating them is different and so much better – there’s more ways to trigger on, more ways to render the results etc, but the actual shown result isn’t that smart, until now…

    In this post I will show you how to create an even smarter and more intelligent Promoted Result – a best bet that actually uses the search query to do something interesting with. In this sample I will let users enter simple math questions and then we let the promoted result calculate the math question for you (just as the big search engines on the interwebz does).

    SNAGHTML5e5971

    Creating Promoted Results aka Best Bets

    A Promoted Result is created either on Search Service Application, Site Collection or Site level using the Search Query Rules option. To create a new Site Collection scoped Promoted Result you navigate to Site Settings > Search Query Rules. Next thing to do is to choose which scope to create this Query Rule for, choose Local SharePoint Results in this case. You have the option to further narrow down the Query Rule using segments and topic categories, but that’s not relevant for this exercise. Next thing to do is to click on New Query Rule. The Add Query Rule page contains quite a few options to make sweet things happening. First we have to give it a name and then we have to specify the query conditions. Query Conditions is what is used to trigger this promoted result. In order to trigger on our “mathematical” question we need to use a regular expression. To use a regular expression as the Query Condition you have to select Advanced Query Text Match and then write a regular expression.

    SNAGHTML6b29a7

    I’m no regular expression savant, but this regular expression works for this blog post. Anyone with a cooler or smarter or more complex regex – feel free to post it in the comments.

    \d+\s*[/\+\-\/*]\s*\d+

    Using a custom page as the Promoted Results

    Next up is to add the Promoted Results Action to this Query Rule. This is done by clicking on the Add Promoted Result further down on the Add Query Rule page. When adding a promoted result you will be asked for a Title, a URL and a description. In our case the URL is of interest – we want to render a page containing our logic to calculate the math query.

    I let the URL point to a page (an .aspx page we’ll create in a few seconds) and then I pass two query string parameters to it; IsDlg=1 to get rid of the chrome in the page and query={SearchTerms} to pass the actual query to the page. I also check the check box Render the URL as a banner instead of as a hyperlink so that the promoted result will be rendered as an iframe instead of a link.

    SNAGHTML70ca44

    Seem simple, doesn’t it, but wait – this will not work until you followed all the steps in this post. There is no thing out of the box that allows you to pass the search query to the Visual Best Bet.

    Now click Save on the Add Promoted Result page and then Save on the Add Query Rule page.

    Creating the custom promoted results page

    Now, before we test this (and it also takes a couple of seconds before this promoted result can be used – don’t ask me why!) let’s create our page that should calculate the result from the query. For this demo we create a fairly simple .aspx page with a JavaScript section and a small HTML snippet, as shown in the snippet below:

    <%@ Page Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, 
    Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
    MasterPageFile="~masterurl/default.master" Language="C#" %> <asp:Content ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server"> <script type="text/javascript"> function getQueryStringValue(name) { var qs = window.location.search.substring(1); var pairs = qs.split("&"); for (var i = 0; i < pairs.length; i++) { var pair = pairs[i].split("="); if (pair[0] == name) { return pair[1]; } } return ''; } _spBodyOnLoadFunctions.push(function () { var query = getQueryStringValue("query") try { document.getElementById("result").innerHTML = eval(query) } catch (e) { document.getElementById("result").innerHTML = "error" } }); </script> <style> #s4-ribbonrow { display:none; } </style> </asp:Content> <asp:Content ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server"> Intelligent Best Bet </asp:Content> <asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server"> <h1>SharePoint Search Calculator</h1> <h2>The result is: <span id="result"></span></h2> </asp:Content>

    The first section contains a simple JavaScript that extracts the Search Query from the query string and then uses the JavaScript eval() method on it to “calculate” the value. In the PlaceHolderMain I added a span element which is where the calculator writes the result.

    So let’s upload this page to the Documents library in the Search Center – which was the location I specified when creating the Promoted Results. If we now search for something that should be triggered by the Query Rule you will see the page rendered as a banner, but  it will not calculate the query as we expected.

    Passing the search query to the custom promoted results page

    So, why aren’t our result rendering properly? It all comes down to that the default Display Template for Best Bets/Promoted Results does not pass the search query to the iframe. In order to fix this we need to modify this Display Template. The Display Template that we need to edit is the Item_BestBet.html file.

    First we add two lines, directly following the var isVBB = … line, like this

    var isVBB = ctx.CurrentItem.IsVisualBestBet;
    
    var url = ctx.CurrentItem.Url
    url = url.replace('{SearchTerms}',ctx.CurrentItem.ParentTableReference.Properties.QueryModification)
    

    The code is crafting the URL to use in the iframe by retrieving the URL from the CurrentItem and then replacing the text {SearchTerms} with the actual search terms used.

    Next we need to modify the line where the iframe is rendered.

    <iframe id="_#= $htmlEncode(id + Srch.U.Ids.visualBestBet) =#_" 
        class="ms-srch-item-visualBestBet" title="_#= $htmlEncode(ctx.CurrentItem.Title) =#_" 
        scrolling="no" frameborder="0px" 
        src="_#= $urlHtmlEncode(url) =#_"></iframe>
    
    Modify the src attribute of the iframe element so that it uses our new url property instead of the default URL value from the current context. Save the file and go back to the Search Center…

    See it in action

    Now we can take it for a test drive. Search for simple mathematical questions and see the results being rendered as a promoted result.

    SNAGHTML80e9e4

    Summary

    I’ve just shown you how to make the Promoted Results aka Visual Best Bets more intelligent by creating a Query Rule that promotes a web page that does operations on the search query. To get this all to work the secret ingredient was to modify the Display Template for promoted results to allow it to pass the search query to the promoted results page.

    I can really see this being extended to provide the users with even more interesting “intelligent” promoted results.

Facebook

About Wictor...

Wictor Wilén is a Director and SharePoint Architect working at Connecta AB. Wictor has achieved the Microsoft Certified Architect (MCA) - SharePoint 2010, Microsoft Certified Solutions Master (MCSM) - SharePoint  and Microsoft Certified Master (MCM) - SharePoint 2010 certifications. He has also been awarded Microsoft Most Valuable Professional (MVP) for three consecutive years.

And a word from our sponsors...

SharePoint 2010 Web Parts in Action