Wednesday, September 7, 2016

JSON based Site Template – Introduction

PnP Provisioning engine is really powerful to create and provision site templates. However PnP uses CSOM – which means to use PnP provision engine, we need to develop either desktop based application (console, wpf) or Provider hosted app. Would be nice to use PnP like templating to create site using SharePoint hosted Add-in which only supports JSOM.

Recently I worked with a client who needed to create sites based on site templates but didn’t want to use Provider hosted app nor any desktop application to provision new site based on site template. This is what I did for the client (more details will be provided in later blogs):

  1. Provisioned a site collection based on PnP Provisioning Engine.
    • Common Site Columns, Content Types are provisioned at site collection level.
    • Custom js (jquery, knockout) uploaded at site collection level and referenced in master page through custom action
    • Custom css uploaded at site collection level and used in alternate css property.
  2. The actual site template is created in PnP provision template but never used. Rather the template is converted to json using ‘JsonPnPFormatter’ and saved as json file.  More details provided later in this post.
  3. A SharePoint hosted Add-in is developed to create site based on site template and installed at site collection level. The add-in creates a new site and then reads the json file created from PnP template and provision artefacts as defined in json template. The Add-In does the followings:
    • Create Site, Site Groups
    • Create lookup fields and create content types
    • create lists
    • setup navigation
    • and many more

Since provisioning site collection/site based on PnP template is not part of this post,I’ll skip step 2.  I’ll explain step 2 – ‘convert PnP template to Json’ in this post. In later posts I’ll explain step 3 – ‘provision site based on json site template’.

Convert PnP template to JSON

To convert PnP template to json, you can use the following code snippet.

public void SaveTemplateAsJson(string templateFilePath, string templateName, string outputFilePath)
var templateProvider = new XMLFileSystemTemplateProvider(Path.GetDirectoryName(templateFilePath), "");
var template = templateProvider.GetTemplate(Path.GetFileName(XmlPath));
templateProvider.SaveAs(template, outputFilePath, new JsonPnPFormatter());

You can call the above method as

SaveTemplateAsJson(@"c:\templates\PnPTempalte.xml", "TemplateName", @"c:\templates\PnPTempalte.json");

To get a visual representation of Json file you can use online tools like or


Now we are ready to use this JSON file in SharePoint Add-in to create site based on this template. If you need to convert multiple PnP templates to Json you can modify the SaveTemplateAsJson to do so.

I’ll explain how to use this json template to create SharePoint Add-in in my future posts.

Thursday, February 19, 2015

SharePoint 2013 Workflow: Code Activity Vs Service Call

SharePoint 2013 has introduced a new workflow model. The workflow model is mostly declarative (XML based). However, you might need to write custom code to implement complex business logic which the workflow itself doesn’t support. You have two options to implement code in this new workflow model:

  • Code activity
  • WCF Service

Now having these two options to implement, you need to know the pros and cons of both.

Let me compare these two options considering full-trust solution.

Options/Matrix Code Activity WCF Service Comments
Object Model You can use Client object model or server object model but better to user Client Object model as this gives you the flexibility to move the workflow manager (along with custom code activity) to non-SharePoint server for scalability.
You can use Server Object Model as the service will be hosted in SharePoint You should not use Server object model in code activity as the workflow services can be moved to non-SharePoint server for scalability
  • Since you should use client object model, you need to be familiar with client object model.
  • The development involved few manual steps like creating xml file etc.
Easy to develop – just like regular Visual Studio solution (SharePoint template)  
Deployment Deployment requires copying files in different places, no out-of-box commands to deploy Code Activity Deployment is easy if you are familiar with WSP deployment If you don’t have remote access to the server (SharePoint admin will deploy using scripts for you), then code activity deployment might be a bit troublesome
Scalability If you use Server Object model, you can’t move workflow manager to it’s own non-SharePoint Server. However if you use client object model, you can move workflow manager to it’s own non-SharePoint server. Since it’s service, you can scale it anyway, like workflow manager and SharePoint server can be hosted in on-premise, cloud or hybrid.  
Reusability If you want to reuse the logic in workflow code activity, you might find it difficult Since your logic is hosted as WCF service, you can reuse the logic in other modules  
Execution I think code activity will run faster as it’ll be executed inside workflow manager. Service call will a bit slower than code activity, I believe This is based on assumption…


Workflow Manager in SharePoint 2013 is designed in a way that it can run independently in non-SharePoint server. Basically Workflow Manager and SharePoint communicate over REST endpoints. So if you use server object model in code activity you are breaking the overall architecture and bring the server side dependency. So in code activity it’s recommended to use either client object model or REST.


For calling WCF service, you can use built-in activity HttpGet/HttpPost.



I personally prefer service approach. I can use server object model, I can reuse the service in other modules and it’s easy to deploy/manage. However, if your custom code activity is doing something non-SharePoint related, like getting data from Line of Business (LOB) system, then maybe it’s better to code activity. It’s because it’s doesn’t make sense to deploy the logic (accessing data in LOB systems) in SharePoint.

Sunday, November 30, 2014

SharePoint 2013: Client Side People Picker


SharePoint 2013 introduced client side people picker which can also be used from SharePoint apps. As like other SharePoint controls, the new people picker control is not well documented. I’ve reversed engineered the client side people picker control and tried to put some light in this dark area.



In the code snippet below, you can use user login id, email address as the key resolve the user in people picker.

Add Unresolved User

If you have user login Id or email address you can use them as key to add the user in people picker as shown below. By passing the ‘true’ as the last parameter in AddUnresolvedUser means, people picker will use the key to query the user details from server.

var peoplePicker = this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan;
var usrObj = { 'Key': loginIdOrEmail };


Add users or show auto suggest

If you would like to show auto suggest box using javascript, you can use the following code snippet. if you pass true in the second parameter for AddUserKeys function, people picker will show the auto-suggest box, otherwise it’ll try to resolve the user. In case of passing true, you can pass any search-text and people picker will show the autosuggest based on the input search text.

var peoplePicker = this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan;
peoplePicker.AddUserKeys(loginIdOrEmailOrSearchText, false); //true shows the auto-suggest box, false resolve the user


Show Error Message

You can show an error message using code snippet as shown below:

SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan.ShowErrorMessage('Error message...')

As as result you will the following error message:



You can check if People picker is empty using the following code snippet. For your information, if there’s any text in the people picker textbox IsEmpty will return false. Basically it’ll check if there’s any resolved or unresolved text in the people picker editor textbox.




You can check if there’s any resolved user by using the following code snippet. If there’s at least one resolved user in the editor, it’ll return true (even if you have resolved or unresolved user, it’ll return true). The different between IsEmpty and HasResolvedUsers is that IsEmtpy will check if there’s any text in the people picker text box. Whereas HasResolvedUsers check if there’s any resolved users in the editor.



Get Current Editor Value

If you can get the editor’s current unresolved value by using the following code snippet:

The code snippet will not return any resolved value in the editor rather unresolved value



You can use the following code snippet to enable or disable the people picker editor. However setting in disable state, prevent adding any new users in the editor but still user can remove existing resolved users by clicking cross (x) sign next to resolved user.


I think the easiest way to disable completely is to hide the delete (cross X) icon. You can do so using the following script:



Remove Resolved Users

There’s no direct support for removing resolved users using the people picker API. I’ve put the following snippet below which I think should work and removes a user by using selected user’s key.

var peoplePickerId = 'peoplePickerDiv';
var peoplePicker = this.SPClientPeoplePicker.SPClientPeoplePickerDict[peoplePickerId + '_TopSpan'];

//get selected users and select the second user (index 1) to remove
var selectedUsers = peoplePicker.GetAllUserInfo();
var userToRemoveKey = selectedUsers[1].Key; 

var resovledListElmId = peoplePicker.ResolvedListElementId;
var elementToRemove = '';
$('#' + resovledListElmId).children().each(function(index, element) {
    if ( + '_TopSpan_' + userToRemoveKey + '_ProcessedUser')) {
        elementToRemove = element;
        return false;


Simply, for all resolved users people picker creates span elements with id in the form ‘{peoplepickerid}_TopSpan_{userKey}_ProcessedUser_{index}’. So if we know the user key we want to remove, we can find the corresponding resolved user’s span element. Then finally people picker’s ‘DeleteProcessedUser’ method is used to remove the selected user.



There’s few events available in the people picker control as described below. All of these events will get two parameters – first one is the people picker id and second parameter is an array of selected users.

On Control Value Changed

This event will be fired if anything changes, like if user type text, user select a user from auto-fill list or user removes selected user. You can easily hook into the event as shown below:

    this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan.OnValueChangedClientScript=function (peoplePickerId, selectedUsersInfo) {
        console.log('inside OnValueChangedClientScript');
On Control Resolved Users Changed

This event will be fired as soon as an user is resolved ( i.e., a resolved user is selected). You can hook into the event as shown below:

    this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan.OnUserResolvedClientScript = function (peoplePickerId, selectedUsersInfo) {
        console.log('inside OnUserResolvedClientScript');


On Control Validate

The people picker control validate it’s values – sometimes when values are changed or you can fire the event by yourself by calling the method ‘Validate’. You can hook into the event as shown below:

    this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan.OnControlValidateClientScript = function (peoplePickerId, selectedUsersInfo) {
        console.log('inside OnControlValidateClientScript');



I’ve tried to explain the API but you all are welcome to provide any feedback or suggestions or enhancements in this unofficial documentation.

Monday, September 29, 2014

SharePoint 2013: Branding with Theme

Theme is a nice and quick way of applying some new styles to SharePoint site. Using theme you can apply some customisation in branding: font, color, background image etc. In this post I’ll explain SharePoint 2013 Theme and you can download a sample SharePoint 2013 Visual Studio solution from here.

There’s some out-of-the-box theme preinstalled in SharePoint. However you can install your own custom theme in SharePoint site.


Theme - Concept

A theme is combination of the following items:

  • Color palette (a file with ‘.spcolor’ extension)
  • A font scheme (a file with ‘.spfont’ extension)
  • Background Image (if you would like to apply/change background image for this theme)
  • Master page, used for theme preview mainly

You can browse the URL http://{SiteCollection}/_catalogs/design/AllItems.aspx to view all theme list items.

Let me explain the theme components:

Color Palette

If you are not already familier with color palette – simply it’s a set of consistent colors to be used for designing/painting. You can find a lots of free site to choose color palette. Some free color platte sites are listed below. If you are designing your SharePoint site then these color palette sites can be really helpful:

Once you select your color palette, you can use a tool called ‘SharePoint Color Palette Tool’ to apply your color palette to design the theme. The following image shows the tool in action:


Few points to note about the tool:

  • You can only create the spcolor file
  • Though you can use background image to test the style in the tool, it’s for preview only. The background image will not be included in the spcolor file.
  • It’s quite unfortunate that there’s no user manual or documentation on how to use the tool. However there’s some videos available online, you can check.



Font Scheme

Font scheme defines the fonts to be used in different section of SharePoint site – navigation, heading, body etc when the theme will be applied. Most of the time you don’t need new font scheme. However if needed, the easiest way of creating a new font scheme is copy an existing one – for example ‘15/Template/Layouts/default.spfont’. If you don’t need custom font scheme as part of the theme, you don’t need to develop a custom font scheme.


Background Image

As part of the theme you can specify a background image that will used when the theme will be applied. Using background image is not quite common in SharePoint sites though.


Master Page

A theme can be associated with master page – but it doesn’t mean if theme is applied to a site, the master page will be changed too. Rather, the master page will be used for previewing the theme. You can view the theme preview by navigating to Site Settings => Change the look, or browsing “http://{siteurl}/_layouts/15/designgallery.aspx”. However, for custom theme if you specify a custom master page, then the master page should have a preview file associated, otherwise you will not see the theme in this design gallery.


Theme - Development/Deployment

I’ve provided a sample Visual Studio solution that shows how to develop a theme-based branding and deploy it. You can find code details from MSDN at However, simply developing, deploying and applying themes include the following steps:

  • Uploading files: You can upload your files as SharePoint modules(themes spcolor, spfonts, master pages etc.). In your visual studio solutions add these files as modules and as you deploy the solution the files will be uploaded in appropriate locations.
  • Install Theme: You need to create list items in ‘design catalog’ with populating different properties like theme url, order, title etc. Creating this list item will make the theme available in the design gallery at http://{siteurl}/_layouts/15/designgallery.aspx
  • Apply theme: If you would like to apply them when the feature is activated, you can apply the theme on feature activation. Alternatively you can apply theme manually from Site settings. In the sample solution, I’ve installed two themes (BrandingTestLight and BrandingTestDark) but only activated the dark theme on feature activation.


To install theme, we need to create a list item in design catalog gallery as shown below:

var themeItem = designCatalog.AddItem();
themeItem["Name"] = themeTitle;
themeItem["Title"] = themeTitle;
themeItem["MasterPageUrl"] = new SPFieldUrlValue(masterUrl);
themeItem["ThemeUrl"] = new SPFieldUrlValue(Web.Site.ServerRelativeUrl.TrimEnd('/') + "/_catalogs/theme/15/" + themeName);
themeItem["DisplayOrder"] = displayOrderCounter; 

In the code snippet above, Master page URL is only for displaying purpose. In my sample application I’ve used seattle.master. This is because whichever master page you use, the master page will have to have a ‘preivew’ file. Since it’s only for display purpose and seattle master page has a preview file, I’ve reused the same preview instead of creating a custom preview of my own for my custom master page. However, if you would like to create a custom preview for your master page you can see more details at



To apply theme, you need to apply theme by using ‘Theme.ApplyTo’ method. However, there’s more. In the theme catalog (http://{sitecollection}/_catalogs/design/AllItems.aspx), you will find a list item with title ‘current’ as shown below. You need update the current theme - list item also as you can see in the sample solution provided.



Download the code

The sample solution I’ve uploaded is available here . The sample solution adds two themes (BrandingTestLight and BrandingTestDark)  and a custom master page. Once you deploy the sample WSP, there’ll be a Web scoped feature “SharePoint Branding - Theme” will be available. Activating and deactivating the feature will deploy the themes and custom master pages, modify the default and custom master page, apply the dark theme.

Sunday, June 22, 2014

SharePoint: Access large list

SharePoint list throttling limits to access maximum 5000 items through view/query. However your list can hold as much as 30,000,000 items but you can’t access more than 5000 items at once by view or query. But I’ve seen scenarios where list items goes millions in a year. So accessing large list having more than 5000 items not very rare in real life.

But have you ever asked yourself, why the limit is 5000 items?
The real limit of 5000 items is related to SQL server. I’m not a SQL server expert but let me try to explain as a non-SQL server expert – “If a SQL query returns more than 5000 items, SQL server locks the entire table – which will affect other queries on the table”.

So as a SharePoint expert you might need to be in a situation where you need to work with large list (having more than 5000 items). However, there’s few options you have when you need to access large list. I’ll explain different options with pros and cons.


Option 1: Override the throttling limit (Less preferable)

You can override the throttling limit from web application settings or through code. I would not suggest to do it from web application as it’ll be applied throughout the web application, instead if you querying your list then you can override the setting as shown below:

SPQuery spqry = new SPQuery();
spqry.QueryThrottleMode = SPQueryThrottleOption.Override;

The easy thing about this approach is that you don’t need to go through any complexity of writing complex code but downside is your query is taking excessive resources affecting other users. Points to note:

  • Easy to use, as you don’t need to include any complexity in your code if you are using SPQuery. If your list views return more than 500 items, the views will not fail
  • Also this approach will send a single (possibly) SQL query that will return all items
  • However, other users browsing the site will find the site slow – as the full table lock will be applied in SQL server delaying other users request to be queued
  • If you are loading all of the items in memory, then your server should be able to handle the items
  • You can override the throttling limit, if your server is able to handle all the items in memory and you are executing your script during off-peak hour. I would prefer overriding the throttling limit, if, for example, I’m moving all data for archiving during off peak hour. More specifically, if you need to run the script periodically or once during off-peak hour then you may be override the throttling limit.


Option 2: Access less than 5000 items Iteratively

With this approach, you don’t override the SharePoint throttling limit (always preferable). Rather you loop through and access less than 5000 items on each iteration (say, 2000 items per iteration). The following block shows the idea:

var list = web.Lists[listName];
var maxItemId = list.Items[list.ItemCount - 1].ID; //get max item id Or use below code to get max id using CAML
//spquery.RowLimit = 1;
//spquery.Query = "<OrderBy><FieldRef Name='ID' /></OrderBy>";
var startIndex = 1;
const int processByCount = 4000; //max no of items to be returned by spquery
var endIndex = startIndex + processByCount;
while (startIndex < maxItemId)
    var query = new SPQuery
        Query = string.Format(@"<Where>
                                <Geq><FieldRef Name='ID' /><Value Type='Counter'>{0}</Value></Geq>
                                <Leq><FieldRef Name='ID' /><Value Type='Counter'>{1}</Value></Leq>
                        </Where>", startIndex, endIndex)
    var items = web.Lists["ListName"].GetItems(query);
    //process items to convert to CSV
    startIndex = endIndex + 1;
    endIndex = startIndex + processByCount;

The above approach is a good option for querying items through SPQuery. However, for list view, you need to modify your views to make sure the view doesn’t return more than 500 items. Points to note:

  • You need to modify your existing views so that they don’t return more than 5000 items.
  • Once you modify your list views (as well as change the code to access less than 5000 items), the queries/views will have less affect on other live users.
  • However, you need to modify your existing code (or new code) to use the pattern to access not more than 5000 items.
  • Also for each loop, you will send a SQL query that will return the items.


Option 3: Use ContentIterator

SharePoint Server provides an API to access individual items using ‘ContentIterator’. ContentIterator is kind of complete API for processing large list items. Points to note:

  • The API has full capabilities of handling different scenarios
  • And the API is available in Office Server version not in Foundation.



Overriding throttling limit is in web application is the last option I would suggest. However overriding throttling limit through SPQuery can be used if you are running your query during off-peak hour and possibly one time. Option 2 of ‘Iteratively accessing less than 5000 items’ is more suitable as you can control how many items you would like to access on each request. ContentIterator is the preferable way, if you are using Server version of SharePoint.

Tuesday, May 13, 2014

SharePoint: Safe Control Entry using elements file

Recently I’ve discovered that it’s possible to add safe control entries through elements.xml file. To do this, add an elements.xml file (or use an existing xml file). Then select the elements.xml file and open the properties window as shown below:


Then click the ... button next to (Safe Control Entries) as shown in the above image. Then in the safe control entries dialog click ‘Add’ and edit the namespace as shown below:


Finally, add the element xml file to a web/site scoped feature. As you will deploy the WSP, the safe control entry will be added in web.config file.

Sunday, November 17, 2013

SharePoint 2013: Optimize your development Environment

SharePoint 2013 demands more resources – especially more memory. When we need to setup a SharePoint 2013 environment we can optimize resource usage in the development server by provisioning/configuring required services as well as following some other guidelines listed in this post.


Search Service Applications

Search Service is EXTREMELY resource hungry. noderunner process (Search Service process for crawling/indexing) is widely known for it’s resources usage footprint. In case you don’t need search service in your development server, you can delete the service application or at least stop the service. If you need to use the search service from time to time, you can keep the search service application running but stop the search service. However, if you try to stop the search service from windows service, you will find the service will be started again by SharePoint. The correct way to stopping service is from Central admin as shown below:



If you need the search service components (crawling/indexing) on development server, you can reduce the performance level by running the following command in SharePoint PowerShell. More information available at

Set-SPEnterpriseSearchService -PerformanceLevel Reduced

You can also control the noderunner memory consumption by changing ‘memoryLimitMegabytes’ in the config file “C:\Program Files\Microsoft Office Servers\15.0\Search\Runtime\1.0\noderunner.exe.config”. Please remember, changing the value to too low might cause the search service to fail.



Provision Required Service Applications only

If you install SharePoint using Installation wizard, different service applications are installed but you many not need all of these service applications. From Central admin you can delete unnecessary Service applications as well as stop services. As you can see below



Stop unnecessary Web Application

Even web application running in your development environment will create w3wp process (if a separate application pool is used) or at least use resources. So if you don’t nee a web application for time being, you can stop the web application as well as related application pool from IIS Manager.



Visual Studio IntelliTrace

If you use Visual Studio debugging in the server and your Visual Studio supports IntelliTrace and the feature is enabled, you can disable the option. That might improve your debugging experience. More information on how to enable/disable the feature can be found at:


Multiple Disk Drive

If you have configured multi-server farm, you can keep some servers in another disk drive. For example, I’ve a multi-server (4 servers – AD, SQL, WFE and App) farm and I’ve kept two servers in my external USB3 supported external drive. So rather than four server vying for the same disk access, two are vying for internal disk access and other two are vying for external disk.

Even if are running a single server farm, you can use an external SSD drive (or USB3) for better I/O throughput. Especially if you can move your database files in an external drive, you will experience much better performance.


Tracing Service

SharePoint uses a windows Service ‘SharePoint Tracing Service’ for logging. sometimes, like during deployment, you will find the log file is growing few hundreds megabytes in short time. So tracing service might take a bit role in performance. If you don’t need the log file for a period of time, you can disable the windows service. During development I usually disable the service and when I need to see the log file, I enable the service.

Sunday, October 27, 2013

Upgrade SharePoint 2010 Visual Studio Solution to SharePoint 2013

With every new version of SharePoint, we need to upgrade our Visual Studio solution. There’s no easy way or tool out there that can automate these upgrade. So I’ll just describe few points you need to consider when you’ll upgrade the Visual Studio 2010 project for SharePoint 2010 to Visual Studio 2012 project for SharePoint 2013. First of all, you need to upgrade your Visual Studio pre-VS2012 solution to Visual Studio 2012.

Change Target .NET Framework

SharePoint 2010 uses .Net Framework 3.5 with SharePoint 2013 uses .Net Framework 4.5. So you need to change the target framework for the project. To change the target framework version, unload the project and then edit the project file in Visual Studio and change the property as shown below:



Change SharePoint Version

Unload the project and edit in Visual Studio, then add/edit the section to ensure the following entry near to the <TargetFrameworkVersion>


Then load the project and replace all SharePoint 2010 specific DLLs with SharePoint 2013 specific DLLs (version 15). Also find out any reference of SharePoint 2010 DLLs/Controls  version ‘’ and replace with ‘’


Change Generic Setup Path in code

In SharePoint 2013, you can deploy your solution in SharePoint 2010 more or SharePoint 2013 mode or both. For example to deploy your solution to both 2010 and 2013 mode, you can use the following command:

Install-SPSolution -Identity my_solution.wsp -GACDeployment -CompatibilityLevel {14,15}

If you skip the CompatibilityLevel (and we usually skip), then the solution is deployed default compatibility level included in the WSP manifest file – which is based on Visual Studio project’s target SharePoint Version. But since we are targeting to upgrade Visual Studio solution to SharePoint 2013, we need to make sure code looks for artifacts in 15 hive, instead of 14 hive. To ensure that code looks in 15 hive, we need to find all use of ‘SPUtility.GetGenericSetupPath()’ and need to replace it with ‘SPUtility.GetVersionedGenericSetupPath()’ passing parameter 15 as shown below:


Note – If you are still deploying your solution in compatibility 14 mode, then you should also replace the ‘GetGenericSetupPath()’ with ‘GetVersionedGenericSetupPath()’ passing parameter 14, but instead of hardcoding the version inline, you can use a constant so that you can replace the version number in one place to change it to 15. You can use constant ‘Microsoft.SharePoint.Utilities.SPUtility.ContextCompatibilityLevel’ which returns the current compatibility level of the SPSite. Your code then will look like:


However, if you want to use the same code both for SharePoint 2010 and SharePoint 2013, then you can code block like below to run code in different version of SharePoint:

//if SharePoint site collection is running in 2013 (15) mode
if (SPUtility.ContextCompatibilityLevel==SPUtility.CompatibilityLevel15)
    //Code needs to be executed in SharePoint 2013
else if (SPUtility.ContextCompatibilityLevel==14)
  // Code needs to executed in SharePoint 2010
//You can also use SPSite.CompatibilityLevel to find out site collection compatibiltiy mode

Change Reference to Layouts, ControlTemplates

Finally all references to ‘_Layouts/’ and ‘_ControlTemplates/’ needs to be changed to ‘_Layouts/15/’ and ‘_ControlTemplates/15/’ to ensure the artifacts are loaded from 15 hive. Either SharePoint will try to load files from 14 hive. However if you deploying the solution in SharePoint 2010 mode, (compatibility level is 14), then you don’t need to update the reference.



After making all the above changes, finally compile the solution. However, my suggestion would be to deploy the WSP in SharePoint 2010 mode first, test the deployment and adjust/modify code to comply with SharePoint 2010 object model. Once you are comfortable with changes, then upgrade code as described in the post and then deploy/test.

Sunday, October 13, 2013

SharePoint Suite/Chrome Control

SharePoint 2013 or Office 365 introduced a new ribbon on the top of the page known as Suite Control as shown below (‘SharePoint’ text):
However, we may want to control the text to appear in the suite control and how they will appear. I’ll explain how to put static text as well as dynamic text in the suite control. For example you may want to show your environment name like ‘DEV’, ‘Test’.


Static Content

If you would like to put just some static text replacing ‘SharePoint’ or ‘Office 365’ you can do so in few different ways that are described below:
Modify using PowerShell
You can modify the text using PowerShell and apply your own static text. You can apply text to web application level as shown below:
$webApplication = Get-SPWebApplication -Identity "http://web-application-url"
$webApplication.SuiteBarBrandingElementHtml = '<div class="ms-core-brandingText">My Text</div>'

This approach will work for whole web application but if you need different text in different sites, you may not be interested in this approach. Also for Office 365, you will not have these PowerShell command available.


Modify through MasterPage

However, if you don’t have access to PowerShell (as in Office 365, you have limited PowerShell access), you can modify master page to edit the text. For your information, if you are using HTML based master page design, then this approach will not work. For your information, in SharePoint 2013, you can develop HTML design first and then can convert the HTML to master page – hence HTML based master page design. Open the default master page in your site using SharePoint Designer, or if you are using custom branding, open your custom master page in edit mode (either in SharePoint Designer or Visual Studio). Find a div with Id ‘suiteBar’ and there’s a delegate control inside the div with id ‘ID_SuiteBarBrandingDelegate’, set this delegate control visible property to ‘false’ (shown in the image below) as this will hide the default Chrome text. Then add your own chrome text in another div after the delegate control

<div class="ms-core-brandingText">My Static Chrome Text</div>

Finally the change will look like below:

However, if you are using HTML based master page design (where you have editing html page which is generating master page), this option will not work as the delegate control is not available in HTML file (rather available in master page file) and you are not supposed to edit the master page directly in HTML based master page design.

Modify Using JavaScript
If you want to use JavaScript to modify the text, edit your master page (or corresponding html file) and add the following script in the file.
<script type="text/javascript">
    $(document).ready(function () {
        ApplySuiteBranding('My Text');

        //ApplySuiteBranding("<b>My Text</b>");
        //ApplySuiteBranding("<b>My Text</b>");
        //ApplySuiteBranding("<a href=''><img src='test.jpg' alt='icon'/></a>");
    function ApplySuiteBranding(htmlToApply) {
        //find for office 365 suite control
        var brandingBox = $('#suiteBrandingBox');
        if ($(brandingBox).length == 0) {
            //office 365 suite control not found, so it's SharePoint
            brandingBox = $('#suiteBar').find(".ms-core-brandingText");


For your information, the above script need to be applied in master page html file if you are using html based master page design. Otherwise apply the script in master page directly. Also you need to add reference to jQuery in the master page as the above script make use of jQuery Library. You can also modify the script to add dynamic text, like current site title by using ‘_spPageContextInfo.webTitle’. So this approach will enable developer to provide semi-dynamic text in the chrome – like web title or any other text that is accessible from jQuery/JavaScript.


Dynamic Content

If you would like to modify the suite control text dynamically, for example add some dynamic navigation or apply different text in different site collection, then you need to create a delegate control. I would recommend this solution, if possible. Though it requires custom development/deployment but it gives you more flexibility and more robust solution. Let’s describe how to do that. I’m not going to explain it steps by steps as you can find a nice example of this at:


Chrome Control in SharePoint 2013 Apps

If you want to use Chrome Control in SharePoint apps, you can find more details on MSDN:



So in summary, if you are happy with static text for whole web application and have PowerShell command available, then use the option of PowerShell. However, if you don’t have access to PowerShell command (as in Office 365), then you can use JavaScript based or direct Master Page edit option described. Finally, if you want a decent and manageable solution (considering, you are deploying a custom WSP solution), you can use Delegate control which gives you more control to change text dynamically. Using JavaScript option will give you the option of adding static text as well as some dynamic text.

Friday, July 26, 2013

SharePoint 2013: Breadcrumb for list/library

Maybe we’ve noticed the issue in SharePoint - if a list view webpart is added to page and user navigate to different folders in the list view, there’s no way for users to know current folder hierarchy. So basically breadcrumb for the list view webpart missing. If there would be a way of showing users the exact location in the folder hierarchy the user is current in (as shown in the image below), wouldn’t be that great?
Image 1: List view webpart with folder-navigation breadcrumb

I’ll explain in the post how you can achieve this kind of folder navigation with minimum changes/customisation.


Download the FolderNavigation.js file from MSDN Code Gallery. You can deploy the script either in Layouts folder (in case of full trust solutions) or in Master Page gallery (in case of SharePoint Online or full trust). I would recommend to deploy in Master Page Gallery so that even if you move to cloud, it works without modification. If you deploy in Master page gallery, you don’t need to make any changes, but if you deploy in layouts folder, you need to make small changes in the script which is described in section ‘Deploy JS Link file in Layouts folder’.

Option 1: Deploy in Master Page Gallery (Suggested)
If you are dealing with SharePoint Online, you don’t have the option to deploy in Layouts folder. In that case you need to deploy it in Master page gallery. Note, deploying the script in other libraries (like site assets, site library) will not work, you need to deploy in master page gallery. To deploy in master page gallery manually, please follow the steps:
  1. Download the js file from MSDN Code Gallery.
  2. Navigate to Root web => site settings => Master Pages (under group ‘Web Designer Galleries’).
  3. From the ‘New Document’ ribbon try adding ’JavaScript Display Template’ and then upload the FolderNavigation.js file and set properties as shown below:
    Image 2: Upload JS file to Master Page Gallery
In the above image, we’ve specified the content type to ‘JavaScript Display Template’, ‘target control type’ to view to use the js file in list view. Also I’ve set target scope to ‘/’ which means all sites and subsites will be applied. If you have a site collection ‘/sites/HR’, then you need to use ‘/Sites/HR’ instead. You can also use List Template ID, if you need.

Option 2: Deploy JS Link file in Layouts Folder
If you are deploying the FolderNavigation.js file in Layouts folder, you need to make small changes in the downloaded script’s RegisterModuleInti method as shown below:
RegisterModuleInit('FolderNavigation.js', folderNavigation);
In this case the ‘RegisterModuleInit’ first parameter will be the path relative to Layouts folder. If you deploy your file in path ‘/_Layouts/folder1’, the then you need to modify code as shown below:
RegisterModuleInit('Folder1/FolderNavigation.js', folderNavigation);

If you are deploying in other subfolders in Layouts folder, you need to update the path accordingly. What I’ve found till now, you can only deploy in Layouts and Master page gallery. But if you find deploying in other folders works, please share.

Use The JS File in List View WebPart

Once you deploy the FolderNavigation.js file, you can start using it in list view webpart. Edit the list view web part properties and then under ‘Miscellaneous’ section put the file url for JS Link as shown below:
Image 3: JS Link for list view webpart

Few points to note for this JS Link:
  • if you have deployed the js file in Master Page Gallery, You can use ~site or ~SiteCollection token, which means current site or current site collection respectively.
  • If you have deployed in Layouts folder, you need to use corresponding path in the JS Link properties. For example if you are deploying the file in Layouts folder, then use ‘/_layouts/15/FolderNavigation.js’, if you are deploying in ‘Layouts/Folder1’ then, use ‘/_layouts/15/Folder1/FolderNavigation.js’.

How it works?

If you are interested how it works, you can carry on reading, either move to deployment section. Basically I’ve utilized the SharePoint 2013 Client Side Rendering (CSR) concept. If you are not familiar with this CSR, you can get the basic idea by Googling. Simply, CSR allows us to customize the rendering of SharePoint fields using JavaScript. I’ve developed a client side rendering JavaScript file which is shown below:

///Author: Sohel Rana
//Version 1.2
//Last Modified on 27-Oct-2013
//Version History:
//  1. Added
//  2. Fixed the bug 'Filtering by clicking on field title would result duplicate navigation link'
//  3. Fixed the bug 'breadcrumb title always lowercase'. Now breadcrumb title is as like the folder name in the library even with case (lower/upper)

//replace query string key with value
function replaceQueryStringAndGet(url, key, value) {
    var re = new RegExp("([?|&])" + key + "=.*?(&|$)", "i");
    separator = url.indexOf('?') !== -1 ? "&" : "?";
    if (url.match(re)) {
        return url.replace(re, '$1' + key + "=" + value + '$2');
    else {
        return url + separator + key + "=" + value;

function folderNavigation() {
    function onPostRender(renderCtx) {
        if (renderCtx.rootFolder) {
            var listUrl = decodeURIComponent(renderCtx.listUrlDir);
            var rootFolder = decodeURIComponent(renderCtx.rootFolder);
            if (renderCtx.rootFolder == '' || rootFolder.toLowerCase() == listUrl.toLowerCase())

            //get the folder path excluding list url. removing list url will give us path relative to current list url
            var folderPath = rootFolder.toLowerCase().indexOf(listUrl.toLowerCase()) == 0 ? rootFolder.substr(listUrl.length) : rootFolder;
            var pathArray = folderPath.split('/');
            var navigationItems = new Array();
            var currentFolderUrl = listUrl;

            var rootNavItem =
                    title: 'Root',
                    url: replaceQueryStringAndGet(document.location.href, 'RootFolder', listUrl)

            for (var index = 0; index < pathArray.length; index++) {
                if (pathArray[index] == '')
                var lastItem = index == pathArray.length - 1;
                currentFolderUrl += '/' + pathArray[index];
                var item =
                        title: pathArray[index],
                        url: lastItem ? '' : replaceQueryStringAndGet(document.location.href, 'RootFolder', encodeURIComponent(currentFolderUrl))
            RenderItems(renderCtx, navigationItems);

    //Add a div and then render navigation items inside span
    function RenderItems(renderCtx, navigationItems) {
        if (navigationItems.length == 0) return;
        var folderNavDivId = 'foldernav_' + renderCtx.wpq;
        var webpartDivId = 'WebPart' + renderCtx.wpq;

        //a div is added beneth the header to show folder navigation
        var folderNavDiv = document.getElementById(folderNavDivId);
        var webpartDiv = document.getElementById(webpartDivId);
            folderNavDiv =null;
        if (folderNavDiv == null) {
            var folderNavDiv = document.createElement('div');
            folderNavDiv.setAttribute('id', folderNavDivId)
            webpartDiv.parentNode.insertBefore(folderNavDiv, webpartDiv);
            folderNavDiv = document.getElementById(folderNavDivId);

        for (var index = 0; index < navigationItems.length; index++) {
            if (navigationItems[index].url == '') {
                var span = document.createElement('span');
                span.innerHTML = navigationItems[index].title;
            else {
                var span = document.createElement('span');
                var anchor = document.createElement('a');
                anchor.setAttribute('href', navigationItems[index].url);
                anchor.innerHTML = navigationItems[index].title;

            //add arrow (>) to separate navigation items, except the last one
            if (index != navigationItems.length - 1) {
                var span = document.createElement('span');
                span.innerHTML = '&nbsp;>&nbsp;';

    function _registerTemplate() {
        var viewContext = {};

        viewContext.Templates = {};
        viewContext.OnPostRender = onPostRender;
    //delay the execution of the script until clienttempltes.js gets loaded
    ExecuteOrDelayUntilScriptLoaded(_registerTemplate, 'clienttemplates.js');

//RegisterModuleInit ensure folderNavigation() function get executed when Minimum Download Strategy is enabled.
//if you deploy the FolderNavigation.js file in '_layouts' folder use 'FolderNavigation.js' as first paramter.
//if you deploy the FolderNavigation.js file in '_layouts/folder/subfolder' folder, use 'folder/subfolder/FolderNavigation.js as first parameter'
//if you are deploying in master page gallery, use '/_catalogs/masterpage/FolderNavigation.js' as first parameter
RegisterModuleInit('/_catalogs/masterpage/FolderNavigation.js', folderNavigation);

//this function get executed in case when Minimum Download Strategy not enabled.

Code Snippet 1: Folder Navigation JavaScript

Let me explain the code briefly.

  • The method ‘replaceQueryStringAndGet’ is used to replace query string parameter with new value. For example if you have url ‘’  and you would like to replace the query string ‘key’ with value ‘New Value’, you can use the method like
    replaceQueryStringAndGet("","key","New Value")
  • The function folderNavigation has three methods. Function ‘onPostRender’ is bound to rendering context’s OnPostRender event. The method first checks if the list view’s root folder is not null  and root folder url is not list url (which means user is browsing list’s/library’s root). Then the method split the render context’s folder path and creates navigation items as shown below:
    var item =
            title: title,
            url: lastItem ? '' : replaceQueryStringAndGet(document.location.href, 'RootFolder', encodeURIComponent(rootFolderUrl))
As shown above, in case of last item (which means current folder user browsing), the url is empty as we’ll show a text instead of link for current folder.
  • Function ‘RenderItems’ renders the items in the page. I think this is the place of customisation you might be interested. Having all navigation items passed to this function, you can render your navigation items in your own way. renderContext.wpq is unique webpart id in the page. As shown below with the wpq value of ‘WPQ2’ the webpart is rendered in a div with id ‘WebPartWPQ2’. 

    Image 4: How list view webpart is rendered

    In ‘RenderItems’ function I’ve added a div just before the webpart div ‘WebPartWPQ2’ to put the folder navigation as shown in the image 1.
  • In the method ‘_registerTemplate’, I’ve registered the template and bound the OnPostRender event.
  • The final piece is RegisterModuleInit. In some example you will find the function folderNavigation is executed immediately along with the declaration. However, there’s a problem with Client Side Rendering and Minimal Download Strategy (MDS) working together as described in here. To avoid this problem, we need to Register foldernavigation function with RegisterModuleInit to ensure the script get executed in case of MDS-enabled site. The last line ‘folderNavigation()’ will execute normally in case of MDS-disabled site.
I’ve upload the js file in MSDN code gallery. Please download it from here.


The JavaScript file is available in MSDN gallery for download.


The solution works for both SharePoint Server as well as SharePoint Online. Though I’ve shown manual process of deploying and updating the JS Link in webpart properties, you can develop powershell script to deploy the FolderNavigation. Few references might be useful: