Deploying our branding to SharePoint Online

We’ve had our SharePoint Online demo ready for a while now. Appie deployed the Fabrikam demo using the scripts provided by Microsoft. The enviromnent looks great to be completely honest, but in order to distinguish ourselves from competitors and have a better, more Mixit specific demo, we require our own Mixit demo environment. Also, this gave me a chance to get my hands dirty and get into SharePoint Online.

The plan was simple: copy a VS2010 branding project from one of the more generic implementations we did, restyle it and deploy to our SharePoint Online environment. Since the project was created for an on premise environment, we were expecting this to not be as smooth as it sounds, here’s an overview of the issues we (me and Dercia) encountered.

Starting with the obvious, our project was a farm solution. Fortunately making it a sandbox solution is simply a matter of setting the Sandboxed Solution project property to true and we’re done.

Let’s have a quick look at the solution before we deploy. The feature we use to staple the branding to new sites is going to be a problem since it’s a farm scope feature. Since we’re only site collection admin, we won’t be able to deploy features higher than site collection. We disable it and will worry about stapling later. Apart from the farm feature all seemed ok, so let’s do a test deploy.

Errors as far as the eye can see. The cause was quite clear though and we could have foreseen this easily. The branding attempts to write images, css and javsscript files to the _images and _layouts folders and since don’t get access to the filesystem, this fails. The solution: deploy the files to the Style Library so they end up in de virtual filesystem and we’re set for another deployment.

“Sandboxed code execution request failed”, an error we hadn’t seen before, but expect to be running into more often. Searching the web resulted in different causes, all of which didn’t seem to apply here. This makes sense of course, since it’s such a generic error. If we would have created my own sandbox solution on my local machine for testing, we would have had more details to the actual problem, but since this is such a small task, we deployed it straight to the online sandbox The error was easily found though: a Feature EventReceiver failed to apply the theme to a site using ThmxTheme.Open. Odd since MSDN assures me this is available in SharePoint Online. For now, we simply removed it and activated the theme manually. This is one to look into at a later stage.

And that was it. The branding works full swing. Good thing too since I’ll be giving a demo about it soon. That meeting will probably result in a few changes and some additional functionality (webparts etc) and get me into the real nitty gritty of SharePoint Online development.

Reageren Lees verder
Frans Sharepoint Developer

CoreResultsWebPart XSLT debugging made easier

Custom styling and transformation for your search results are a great way of fitting the results into the general look & feel of the application and adding relevant metadata in one big swoop. Unfortunately, debugging the XSLT is rather limited. A quick overview:

  • if your XSLT contains a syntax error, SharePoint will load the previous version of the XSLT
  • in order to get the popup in which you can paste your XSLT, you’ll need a number of page reloads which is a hassle in itself and might be cumbersome depending on your system specs
  • XSLT error messages are hidden, only a generic error with the mapped properties might be displayed (related to the columns)

If you need to do a complete rework of the style, there’s a simple trick that I noticed many SharePoint developers don’t know about that will potentially save you a lot of time and effort.

Test your XSLT outside of the CoreResultsWebPart!

By extracting the XML for search results from the CoreResultsWebPart and linking the XSLT stylesheet to it, you have access to error details from the XSLT parser and can avoid many often slow loading SharePoint page reloads. Two simple steps will allow you to do this.

1. Extract the XML from the CoreResultsWebPart

Using the following XSLT snippet (which every other SharePoint blogger has posted at some point; I got from MSDN this time around) to style the search results, the webpart dumps the generated XML on th screen. Simply copy and paste the XML code into a file on your local machine and step 1 is finished.

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xmp><xsl:copy-of select="*"/></xmp>
</xsl:template>
</xsl:stylesheet>

The XML results should look similar to this:

<All_Results>
<Result>
<id>1</id>
<workid>5015</workid>
<rank>87098240</rank>
<title>TEST</title>
<author>Frans</author>
<size>0</size>
<url>http://server:2002/default.aspx</url>
<urlEncoded>http%3A%2F%2Fserver%3A2002%2Fdefault%2Easpx</urlEncoded>
<description></description>
<write>29-9-2011</write>
<sitename></sitename>
<collapsingstatus>0</collapsingstatus>
<hithighlightedsummary><ddd /> </hithighlightedsummary>
<contentclass>ContentClass</contentclass>
<isdocument>False</isdocument>
<picturethumbnailurl></picturethumbnailurl>
<serverredirectedurl></serverredirectedurl>
<Result>
<All_Results>

2. Link your XSLT to the XML

Paste your XSLT code into a file and store it in the same folder as the XML file. Now all we need to do is link the stylesheet file to the XML file. The snippet to accomplish this looks like this:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="searchresults_styling.xslt"?>

More info about this on w3schools. And that’s it. Now just open the XML file in a browser and start styling and transforming the search results using real data!

Note: since the XSLT most likely won’t be generating a full HTML document styling you’ll most likely be lacking CSS and such. The structure however will be just fine.

Reageren Lees verder
Frans Sharepoint Developer

Search Driven Sharepoint – Custom sorting van zoekresultaten

Het CoreResultsWebPart in Sharepoint 2010 is een rijke feature. Out-of-the-box kan het onwijs veel, biedt het veel configuratiemodelijkheden en kan het de meeste scenario’s zonder problemen aan. Maar, het CoreResultsWebPart is bedoeld voor traditionele zoekimplementaties. Zodra je meer “search driven” oplossingen gaat implementeren, loop je snel tegen de beperkingen aan. In dit blog belicht ik één van de vele aspecten van search driven oplossingen: de noodzaak tot custom sorting.

Wat? Waarom?

Sharepoint search geeft je weinig opties tot het sorteren van je zoekresultaten. Vanuit de gedachte dat het zoekresultaten zijn en je dus de meest relevante opties bovenaan wilt hebben, is dit natuurlijk prima. Maar wat doe je als je het nieuws uit alle sites in je sitecollecties wilt tonen, relevantie wordt dan opeens publicatiedatum. Wat doe je als je een productsuggestiefunctie voor een webshop bouwt? Dan is relevantie een stuk complexer dan tekstuele overeenkomsten en wil je zelfs direct invloed kunnen uitoefenen op de resultaten. Dit is het topje van de ijsberg met betrekking tot search driven applicaties en in dit blog licht ik een simpel voorbeeld toe van hoe je dit voor elkaar kunt krijgen in Sharepoint 2010.

Allereerst: FAST

FAST Search kan dit soort operaties (en meer) OOB. Het grootste voordeel van FAST werkt helaas in het nadeel.  FAST is een beest van een applicatie en dat leidt tot een behoorlijke footprint, licentiekosten, expertise en consultancy en stevige hardware vereisten. Dat maakt FAST niet geschikt voor alle implementaties, het is al snel een kanon om een mug dood te schieten.

Dus je kunt niet altijd FAST inzetten, maar wilt wel beschikken over custom sorting

Dat kan! Maar het kost wel wat werk. Het CoreResultsWebPart is niet sealed. Door een webpart te maken dat overerft uit CoreResultWebPart heb je de mogelijkheid om het gedrag van je zoekapplicatie te beïnvloeden. In dit specifieke geval overriden we de DataSourceView voor de resultaten. Dit doen we in 3 stappen: eerst maken we een overriding class voor CoreResultsWebPart en specificeren we een nieuwe DataSource.

public class CustomSortedResultsWebPart : CoreResultsWebPart {

   protected override void CreateChildControls() {
      base.CreateChildControls();
   }

   // override the DataSource to allow overriding the DataSourceView
   protected override void CreateDataSource() {
      this.DataSource = new CustomSortedResultsDataSource(this);
   }
}

Vervolgens geven we in deze custom DataSource aan dat we een custom CoreResultsDatasourceView willen gebruiken.

public class CustomSortedResultsDataSource : CoreResultsDatasource {
   public CustomSortedResultsDataSource(CoreResultsWebPart ParentWebpart) : base(ParentWebpart) {
         //create the View that will be used with this datasource
         this.View = new CustomSortedResultsDataSourceView(this,"CustomSortedResults");
      }
}

En tot slot geven overriden we in de custom CoreResultsDatasourceView de AddSortOrder om onze eigen sorteren te tonen.

public class CustomSortedResultsDataSourceView : CoreResultsDatasourceView {

     public CustomSortedResultsDataSourceView(SearchResultsBaseDatasource DataSourceOwner, string ViewName) : base(DataSourceOwner, ViewName) {
         //make sure we have a value for the datasource
         if (DataSourceOwner == null) {
             throw new ArgumentNullException("DataSourceOwner");
         }

         //get a typed reference to our datasource
         CustomSortedResultsDataSource ds = this.DataSourceOwner as CustomSortedResultsDataSource;

         //configure the query manager for this View
         this.QueryManager = SharedQueryManager.GetInstance(ds.ParentWebpart.Page).QueryManager;
     }

     // Add a custom Sort Order for the results
     public override void AddSortOrder(SharePointSearchRuntime runtime) {

         #region Ensure Runtime
         //make sure our runtime has been properly instantiated
         if (runtime.KeywordQueryObject == null) {
             return;
         }
         #endregion

         // use the following to get a handle to the CoreResultsWebPart, allowing this webpart to be configurable though properties etc
         //CustomSortedResultsWebPart webPart = DataSourceOwner.ParentWebpart as CustomSortedResultsWebPart ;

         // remove any other sorted fields we might have had to ensure our custom sort
         runtime.KeywordQueryObject.SortList.Clear();

         // configure the sort list with sort field and direction
         runtime.KeywordQueryObject.SortList.Add("MyCustomField", SortDirection.Ascending);
     }
 }
Reageren Lees verder
Frans Sharepoint Developer

Nieuwsbrief

WE WON WINNING!!!