Welcome to the second post in this series about REST in SharePoint 2013. Please read the first post before you go on to this post Get started with REST in SharePoint 2013 – Part I

In this post I will show you how create a web part with help of REST web service that will display a list of all sub sites immediately below the current site, similar to what you can find under ‘Site Contents’. We’ll also need to have this permission trimmed.

subsites

Before you start scripting and build the HTML and CSS for this, you’ll first need to construct the RESTful HTTP / oData request in order to retrieve the entities, in this case all sub sites of some site. Assume you have a number of sub sites under a site named Projects. Change the domain name and try the following basic query in your browser.

https://contoso.sharepoint.com/projects/_api/web/webs/?$select=title

Once you get the results back in your browser in pure XML and you have construct the query properly with the filters you want, it’s time to create the script that will return the result in JSON format and will create the markup with the styling.

Let’s start

You can use notepad, SharePoint Designer or Visual Studio or the tool of your choice. For example you can just add the following script, the CSS and the jQuery references in one single text file to a folder in your SharePoint environment and use a content editor web part to link to the text file.

Here’s the script that will create a list of all sub sites. You can download the script with the CSS and jQuery references from here.

<div id="listResult"></div>
<script type="text/javascript">
// If the web part will live in the root web or a subsite
if (_spPageContextInfo.webServerRelativeUrl === '/') {
var webUrl = '';
}    
else{
var webUrl = _spPageContextInfo.webServerRelativeUrl;
}
// start ajax
$.ajax({
url: webUrl + "/_api/web/webs/?$select=title,ServerRelativeUrl,Created,effectivebasepermissions&$filter=(effectivebasepermissions/high%20gt%2032)&$orderby=Created desc",

type: "GET",
headers: {"Accept": "application/json;odata=verbose"},
cache:false,
// start success                  
success: function(data){
//console.log(data);
var items = [];
items.push("<ul id='listContainer'>");
items.push("<div id='listHeader'>" + 'Subsites ' + "</div>");     
// if content exist
var dataResult = data.d.results;
if (dataResult.length == 0) {
items.push("<div id='listNoRecords'>" + 'No subsites were found' + "</div>");
}    
else{
// start data.d.results
$(data.d.results).each(function(){
var CreatedDate = moment(this.Created).startOf('hour').fromNow()
items.push('<li id="' + 'listContent' + '">' + 
'<span id="' + 'listContentInner' + '">' + 
'<img src="/_layouts/15/images/SharePointFoundation16.png" />' + ' <a href="' + this.ServerRelativeUrl + '">' +  this.Title + '</a>' +  
'</span>' + 
'<span id="' + 'listContentInnerTime' + '">' + 
' - ' + CreatedDate + 
'</span>' + 
'</li>');			    		
});
// end data.d.results		
}    
// end if content exist
items.push("</ul>");
$("#listResult").html(items.join(''));
}
// end success  
});
// end ajax
</script>
<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.6.0/moment.min.js"></script>

A couple of things

Filter and sorting

You can filter the oData query by conditions or sort the result, for example:

  • $filter=ID eq 1 (only the object with ID eq to 1)
  • $top=5 (limit to 5 items)
  • $orderby=Created desc (sort by descending order)

There’s a lot of oData operators that are supported in SharePoint’s REST service like numeric comparsions, string comparsions and Date/TIme functions. Read more about this at MSDN.

Add the results to the DOM

All the data in the array are stored in a variable called Items. The trick I used in the script for appending the data to the DOM is to use jQuery’s Push() method, in this way you’ll have good control of the HTML you create.

_spPageContextInfo

In this example I added a condition that will add a slash to the beginning of the URI if it’s not a top site, otherwise I don’t want this trailing slash there. The _spPageContextInfo will simply get the site paths after the domain name.

if (_spPageContextInfo.webServerRelativeUrl === '/') {
var webUrl = '';
}    
else{
var webUrl = _spPageContextInfo.webServerRelativeUrl;
}
url: webUrl + "/_api/web/webs/?$select=title,ServerRelativeUrl,Created,effectivebasepermissions&$filter=(effectivebasepermissions/high%20gt%2032)&$orderby=Created desc",

Date parsing

The REST API in SharePoint returns the date in ISO8601 which means that you’ll get the date and time back in a format like this: 2014-06-30T22:56:00Z. To format date and time in JS is tricky. To avoid this I’ve used a great JS plugin called Moment.js this one will help you and take care of the parsing. MomentJS will also give you the option to display the result in a clean way like 2014-06-30 or for example a format like ‘1 month ago’.

Security trimming

The result from a REST query are not security trimmed so if you want to display only the sites for which the users has access to, you need to secure trim the REST URI with a filter using the EffectiveBasePermissions with a following parameter like this

filter=(effectivebasepermissions/high%20gt%2032)

There’s a permission in SharePoint to allow web service called “Use Remote Interfaces”. All users should have this permission to be able to read results from a REST call.

If you have users in the out of the box group ‘visitors’ which have the permission level = Read, you’ll need to add ‘Use Remote Interfaces’ to this permission level. You can find the page with this URL: http://YourSite/_layouts/15/editrole.aspx?role=Read
URI

Do also note that the ‘Use Remote Interfaces’ can be disabled and enabled on the Web Application level in central admin.

Do always test your REST calls for users with different permission levels.

Stay tuned for the next post in this series!

</christian>

Advertisements