Saturday, September 14, 2013

SharePoint 2013 and Ember.js

Ember.js is great and I'm really enjoying writing apps using it. Well, it's possible to use any modern framework with SharePoint, including Ember.js. Let's see how to write simple Ember.js app using new SharePoint 2013 app model. I'll use SharePoint-hosted app ( for this example - this is an app that is coded using only html and javascript, no server side code at all.

Let's display list of items and item details from some SharePoint list using Ember. First of all we need to create new SharePoint-hosted app:

Then we need to add references to Ember.js and handlebars (the default templating engine). I'll be using ember.js 1.0.0 and handlebars 1.0.0 - latest versions as of this writing. Define the root of our application (div with id "main"):

After all prepartions we can create an instance of Ember.Application - this is the very first step of creating an Ember app:

Ember uses pretty strong conventions for Routes, Controllers and Views. This allows to hide lots of code behind as Ember generates it for us. For example even if we not define controller it will still be generated which is pretty cool I think - we can focus on implementation of our the logic rather than doing some boilerplate code.

We need to define routes for news list and for news details:

This routes map tells us that we need to define NewsRoute and NewsControoler (because of Ember conventions). If those objects will not be found Ember will generate them for us. The default route also will be NewsRoute:

And the last thing we need to do is to create News model and load actual data. It's pretty straightforward on how to use SharePoint javascript object model and proxy requests from app to main site. So here is the code:

And here is the result. This simple SharePoint application loads data from Announcements list from the root site:

Sample code for Visual Studio 2012 has been uploaded here:

Monday, May 13, 2013

SharePoint: exclude files from WSP

Publishing of WSPs in Visual Studio is very simple and straightforward. But this process includes absolutely everything into WSP (aspx, ascx, css, js, etc), even if we don’t need them. For example, if we have minified versions of javascript files, we definitely don’t need debug versions in production. SharePoint tooling doesn’t really help us when we need to customize building process for our solutions. But luckily we have MsBuild! I’ll come up with simple solution on how it’s possible to exclude some files from Layouts directory. Everything that will be described below has been tested in Visual Studio 2012 and SharePoint 2010.

When we click Publish button from VS menu, it executes the following MSBuild file:

c:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\SharePointTools\Microsoft.VisualStudio.SharePoint.targets

A closer look to this file shows that we can officially override two targets here: BeforeLayout and AfterLayout. We need to do two things - exclude file from WSP and exclude it from manifest.xml. Excluding from WSP is simple enough. According to Microsoft.VisualStudio.SharePoint.targets file there is EnumeratedFiles ItemGroup created before BeforeLayout target, so we can exclude some files in this target like that:

ExcludedFiles ItemGroup should be defined earlier. FindInEnumeration is simple task that finds files in MSBuild ItemGroup array. Using MSBuild 4.0 we can use little C# snippets in order to create tasks:

After we excluded items from WSP let’s exclude them from manifest.xml. We have to do it separately because manifest files are gathered before BeforeLayout target and we have no control over it. We need to define the following AfterLayout target:

ExcludeFromManifest task reads manifest.xml file from pkg folder and removes ExcludedFiles items from it:

Please note that I added Condition="'$(Configuration)'=='Release'" condition to both targets, so only Release version of WSP will not contain excluded files, Debug version should stay untouched for development mode of course.

Here is the link to the whole build file:

You can just include it in your project, import it through  <Import Project="build-release.targets" /> and modify ScriptsDir, ManifestPath, ExcludedFiles variables according to your project needs.