The situation: you have a great blog article you would like to rollup to a page on your site, but it is in a different site collection. What do you do? Content Query Webparts won’t do it! Well, you could create a custom webpart. You could pay a consultant and some developers to create one for you. You could find something prebuilt.
Or you could insert a few lines of jQuery and call it a day!
We’re looking to create something like this (the link would be dynamically rolled up from across a site collection):
Latest Blog Article: Rollup articles across a site collection (using jQuery) in SharePoint 2010
Skip ahead:
Download/link to SPServices
The Code
Final Result
Step 1: Download/link to SPServices
(This assumes you have already loaded jQuery itself…do that first!). SPServices is a jQuery library created by Marc D Anderson that helps you hook into SharePoints services. It does a freaking lot of stuff, but for this article we’re going to use it for rolling up some content from across a site collection. So download it from codeplex and let’s get started!
We’re going to do everything in the page using SharePoint Designer. You could load this script in your master page, or page layouts, or wherever you want. But for now, we’re going to do a one-page example. So copy this script onto your page:
<script type="text/javascript" src="/Style%20Library/scripts/jquery.SPServices-0.7.0.min.js"></script>
Step 2: the Code
First, let’s setup our placeholder for this article’s title. We will set up a span (or p, div, whatever) with and ID so we can use jQuery to find it and append the dynamically created link.
<span id="sitecollectionlink">Latest Blog Article:</span>
Next, we’ll start writing our code. I’ll break it down and then paste everything at the end. I’ve created this solution by trial and error, but there were a few discussions and examples by much smarter people on the codeplex forums that helped me with a few of the hard bits.
First let’s create a new script and call a new jQuery function on $(document).ready:
<script type="text/javascript">
$(document).ready(function() {
//code will go here
});
</script>
Let’s get into it! Our call to SPServices comes next. We’ll set the operation to “GetListItems”, set our webURL to where our blog is residing (in a separate site collection), and we pass it the list “name”. For default SharePoint blogs the list name is “Posts.” Next, we call in the fields using CAML. You’ll need two for this example, the Title field and the EncodedAbsUrl field. And finally, I’ve limited the results to just 1 because I want only one blog post showing up on my home page. Default I believe is 30 or so…
$().SPServices({
operation: "GetListItems",
async: false,
webURL: "/YOUR-SITE/CHANGETHIS",
listName: "Posts",
CAMLViewFields: "<ViewFields><FieldRef Name='EncodedAbsUrl' /><FieldRef Name='Title' /></ViewFields>",
CAMLRowLimit:1,
// we're not finished...more coming!
});
Next we call a function that runs when everything is complete. (Be sure to read the documentation on the codeplex for an explanation of why the code should be SPFilterNode instead of find). Ok, the code below first sets a variable called “url”. We set this from the EncodedAbsUrl variable. Don’t forget to include ows_ before the variables when you call them here. Next we have an if statement that tests whether or not the returned item is a document. This is not very relevant for this tutorial, but it’s good to see what happens. Because this is not a document, it’s a list item, the code inside the if statement will run. SharePoint URLs are stored really horribly, so this takes out all the junk and formats it nicely. It cuts off everything after the last forward slash and replaces it with “/Post.aspx?ID=” (this is the default viewing page for a SharePoint post). Then it brings in the ID to append to the URL. Finally, we set a variable called “link”, using the newly formatted URL as the href tag and putting our Title as the anchor text. And to wrap it all up we locate the span we created earlier using jQuery and append the new link we’ve created. The link will be put in dynamically after the page has loaded!
completefunc: function (xData, Status) {
$(xData.responseXML).SPFilterNode("z:row").each(function() {
var url = $(this).attr("ows_EncodedAbsUrl") + "";
if(($(this).attr("ows_EncodedAbsUrl") + "").match(/000$/))
{
url = url.substring(0, url.lastIndexOf("/", url.length));
url = url + "/Post.aspx?ID=" + $(this).attr("ows_ID");
}
var link = "<a href='" + url + "'>" + $(this).attr("ows_Title") + "</a>";
$("#sitecollectionlink").append(link);
});
}
So hopefully this tutorial was fairly straightforward. If you got lost, don’t worry, leave a comment and I’ll help you out. And for your ease, the full code is below. Copy and paste to your heart’s content!
Final Result
Copy and paste this into your page and you should be good to go. Remember to change the path to your javascript and the webUrl to your list.
<script type="text/javascript" src="/Style%20Library/scripts/jquery.SPServices-0.7.0.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$().SPServices({
operation: "GetListItems",
async: false,
webURL: "/YOUR-SITE/CHANGETHIS",
listName: "Posts",
CAMLViewFields: "<ViewFields><FieldRef Name='EncodedAbsUrl' /><FieldRef Name='Title' /></ViewFields>",
CAMLRowLimit:1,
completefunc: function (xData, Status) {
$(xData.responseXML).SPFilterNode("z:row").each(function() {
var url = $(this).attr("ows_EncodedAbsUrl") + "";
if(($(this).attr("ows_EncodedAbsUrl") + "").match(/000$/))
{
url = url.substring(0, url.lastIndexOf("/", url.length));
url = url + "/Post.aspx?ID=" + $(this).attr("ows_ID");
}
var link = "<a href='" + url + "'>" + $(this).attr("ows_Title") + "</a>";
$("#sitecollectionlink").append(link);
});
}
});
});
</script>
<span id="sitecollectionlink">Latest Blog Article:</span>
I am trying to use this piece of code to roll up contents from various lists in different site collections into one activity feed (list) on the main landing page. For proof of concept, I tried using 1 list from a site collection and use its title in the landing page using your code. I am fairly new to sharepoint and I am using shrepoint 2010 office 365.. Questions for you,
1) Where exactly should the webUrl be pointing?
2)listName = Name of the list I created?
3) ‘EncodedAbsUrl’ , what will be the value for this in a announcement list?
Hi Taran,
1) The webURL should be a link to the parent site (or site collection) of your list
2) Yes, the name of the list you created should be in listName. The plugin will look in the webURL for the listName
3) I’ve included the EncodedAbsUrl field only so the title that rolls up is turned into a link that takes you to the list entry for that announcement.
Thanks for the questions! Hope this helps. Let me know if you need more help.
Yes I do :)
Thanks for your quick replies and this does work for me, once I corrected the webURL. I guess, I have 2 more questions..
1) This works great when I have to pull data from a single list / library but do you have a solution, if you have to pull data from multiple lists? Do i have to write a function for each of them?
2) Can I feed this data to a sharepoint list and display them instead of a div/span or any html element?
I appreciate, all your help..
1) Yes, definitely possible, no need to write a function for each (assuming one or two things I’ll explain in a bit). It’s quite a big chunk of code, and I’m in Asia, so when I get back to my PC tomorrow I’ll paste it.
2) I’m not sure I understand this second question. Are you asking if, once you roll items up from several lists, if you can dump that whole thing into another SharePoint list?
I am sorry, I guess I could have been more clear on that.. but yes that was my question.. Can I dump rolled up items from several lists into another sharepoint list?
Hi Taran,
Ok, in response to your first question I’ve actually decided to just write a blog post about it. See if that helps. It’ll show you how to query multiple items from multiple lists.
Regarding your 2nd question…I’ll have to get back to you. I know you can add and update items in a list using SharePoint, but I’ll let you know if I discover how to take rolled up items and put them in a list. If you beat me to it, let me know, I’d love to know!
And for the next trick…
Here’s a blog post I just wrote on putting those rolled-up items into a new list. Hope it helps!
Ben,
Thanks for your responses. I was away for a couple days and came back and tried your code. With a few modifications and playing around, I am able to get closer to my requirements. Although, I noticed, in the z:row of getListItems, there are only a few things we can get like title, modified, etc.
My need is to get some more information like Modified By, File Name, Site Name etc.. Is there any method with SPServices, that will do the trick?
This is great learning curve for me and you are being very helpful, thanks!!
Yep, there’s definitely a way. You must do two things: 1) call the right fields using CAML, and 2) display them within the z:row bit.
1) Within your SPServices function, you can specify which fields the query picks up by using the CAMLViewFields section. The FieldRef Name=”" part is where you will put the name of your column (‘Editor’ is usually the field name of ‘Modified By’) You’ll just need to look at the settings of your list to find the real name of each of your columns.
2) Within the z:row part, you can call those fields by the following jQuery code:
$(this).attr(“Modified”);
I’ll post again tomorrow with some more real examples hopefully.
Thanks Ben, this is wonderful !! My questions don’t end but I am sure, your blog will be very helpful to tons of other people.. How can you grep a site name from a list? For instance, I have a list in site A and I want to display that as a column in site B, can I do that? Modifying data from EncodedAbsUrl would not be easy..
Never Mind, I parsed the URL to get it
Yeah, I think there’s an SPServices call to “get list name from URL,” is that what you used?
No, I did something like this..
var siteUrl= $(this).attr(“ows_EncodedAbsUrl”);
var siteUrlRegex = /https:\/\/[^\/]+\/([^\/]+)\/.*/;
var siteName = siteUrlRegex.exec(siteUrl)[1];
This works for me.. but I have a question, in order to make your solution work I will have to name the lists/library in a specific manner to find a pattern in the Title, to only grab data from those lists. This may not fly for me.. so I decided to look for more meta data like BaseType, now that brings a whole lot of junk data.. are you aware of any other way to just get data from user created lists/ libraries?
Yeah, if you use a BaseType of 0 (zero) I believe you should get all custom lists/libraries.
Thanks Ben but I think that is Type zero id for generic list. However, have you used a resource file in sharepoint cloud version before? If so, do you know where to place the file? Any example will help..
sorry for the typos.. :)
Sorry…I don’t have much experience working with SP in the cloud. Wouldn’t know where to start.