SharePoint 101: installing Google Analytics

A more basic post, but hopefully helpful to someone out there. Also, a more in-depth response to my article on Microsoft’s “Get the Point” blog.

To install Google Analytics in your SharePoint 2010 environment, my approach is to use the Master Page. There are two basic steps here, so it shouldn’t take you more than a few minutes.

  • Step 1: Get tracking code
  • Step 2: Edit Master Page

Step 1: Get tracking code

It’s important when you are copying your tracking code from Google Analytics that you have set up your account correctly. Because SharePoint is often run on https, you’ll want to make sure it doesn’t make a non-secure call to Google Analytics. If you’ve set up your site in Google Analytics to use the correct protocol (http vs https), then the tracking code should reflect it. In general though, your code should look like this:


<script type="text/javascript">// <![CDATA[
var _gaq = _gaq || [];
 _gaq.push(['_setAccount', 'UA-XXXXXXX-X']);
 _gaq.push(['_trackPageview']);

(function() {
 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
 ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
 })();
// ]]></script>

Step 2: Edit Master page

  1. Open SharePoint Designer
  2. Go to Master Pages
  3. Right-click on your Master Page and click “Edit  File in Advanced Mode”
  4. Scroll all the way to the bottom (just above the closing ‘body’ tag)
  5. Paste the tracking code

Done!

Guest article on EUSP: itemstyle.xsl for designers

Recently had one of my articles garner a little bit of attention and it is now cross-posted on endusersharepoint.com for your viewing pleasure: Itemstyle.xsl in SharePoint 2010 – A guide for designers

Thanks EUSP!

Intro to branding SharePoint 2010 for designers

I’ve been in the SharePoint world for a couple of years now, and feel like I’m finally able to start seeing clearly what branding in SharePoint really entails. For those of you just getting started, prepare for a long journey. But no need to worry, branding in SharePoint isn’t too scary once you get into it.

I started out (and still do) hand-coding websites. I then progressed to CMS’s like Drupal and WordPress. I have since taken the plunge into SharePoint 2010 as well. If designing a website is like putting together a Lego castle, then designing a website in SharePoint is kind of like putting together a Lego castle where all the pieces are individually wrapped in little plastic bags, and are strangely shaped. It takes a long time to strip away all the “SharePoint-y” stuff to get down to your real design. But once you get there, it’s not so bad.

Not being a developer, SharePoint was a bit daunting at first. A lot of .aspx pages, as well as strange new programs like SharePoint Designer, InfoPath, and Visual Studio (although I don’t use this one). As you begin designing in SharePoint, you’ll want to consider your approach, and it will be slightly different than your typical approach to web design.

Bite-sized pieces

Don’t jump in and start opening every file in SharePoint Designer that you find…you’ll go crazy. Here is my three-step basic process to get started with branding in SharePoint. Move through each step slowly and see how it goes. Once you’re done, you’ll want to repeat the process (probably backwards) to create your own solution.

  1. Apply your own custom CSS
  2. Create new content types & page layouts
  3. Customize/create a new Master Page

Apply your own custom CSS

You’re a designer, so this is something you can be comfortable with as a first step. First, register your CSS file in the master page (all we will touch in the master page for now), and then create a new CSS file in “/Style Library/”. Using the web developer toolbar in Firefox, or Chrome’s built in developer tools, you should have what you need to get started customizing right away. You could do just this step, and be totally fine. However, if you keep digging the grave gets deeper.

Create new content types & page layouts

To keep things clean, I would suggest creating your own content type(s), and from there create unique page layouts for your content. With a page layout you can add your own html wrappers to your content (titles, body text, custom fields, etc.), which gives you that much more control of layout within a page. Also, you can add header styles in these documents to call CSS files and .js scripts without editing a Master Page (not best practice…but it’s possible).

[note] Don’t forget to enable any new page layouts in “Site Settings > Page Layouts and Site Templates” so your pages can use them.

Customize/create a new Master Page

This is the trickiest feat. I would suggest starting with something like Kyle Schaeffer’s HTML5 Master Page, or the Starter Master Pages on CodePlex (I believe by Randy Drisgill and others). My method? I printed out v4.master on giant A3 sheets, along with a couple of other master pages, and sat down at a table, analyzing line by line what I needed to pay attention to, what I was confused about, and what I could edit. So grab a couple of highlighters, print out a sample master page, and get familiar with your blueprint. You’ll learn soon enough what you can and can’t get rid of. A great tip I learned from Heather Waterman at a branding session in Las Vegas one year is to give yourself a bunch of blank space at the beginning of the document, put in your (working) html, and then slowly add in little pieces of the master page as needed. This way you don’t delete stuff you need, and you keep your html intact.

Explore

There is so much more you can do with SharePoint than just CSS and master pages. It gets really fun when you start working with jQuery and interacting with SharePoint services, for example. But that’s for another time. If you want to explore some more about branding in SharePoint, here are a few resources (some articles of mine, as well as other things you might find useful):

Sharepoint 2010 + SPServices + jQuery Mobile

Here we will setup a SharePoint 2010 page that utilizes both jQuery Mobile as well as the jQuery SPServices library. Note: This post was updated Feb 21 to reflect an issue I’ve documented here with IE8.

Create a new page

Create a new blank .aspx page in the “Site Pages” library (using SharePoint Designer 2010). I like to use a new .aspx page like this because I can create a document from scratch, I don’t have to deal with page layouts, master pages, etc. The same principals can be applied elsewhere, but this gives me a clean page to start from (which is way easier to debug).

Setup your html

Note: I’ve created my document using html5 standards (as does jQuery Mobile).

<!DOCTYPE html>
<html>
<head>
<meta name="WebPartPageExpansion" content="full" />
<title>SharePoint, SPServices, and jQuery Mobile!</title>
	<link rel="apple-touch-icon" href="/Style Library/Images/apple-touch-icon.png"/>
	<meta name="viewport" content="user-scalable=yes, width=device-width, initial-scale=1"> 
	<link rel="stylesheet" href="/Style Library/scripts/jquery.mobile-1.0.1/jquery.mobile-1.0.1.min.css" />
	<script src="/Style Library/scripts/jquery-1.6.4.min.js"></script>
	<script src="/Style Library/scripts/jquery.SPServices-0.7.0.min.js"></script>
<script type="text/javascript">
 //we'll put the SPServices functions here
 //note the placement of this script tag BEFORE the jQuery Mobile javascript link
</script>
	<script src="/Style Library/scripts/jquery.mobile-1.0.1/jquery.mobile-1.0.1.min.js"></script>

<!--[if lt IE 9]>
<script src="/Style Library/scripts/html5.js"></script>
<![endif]-->

</head>
<body>
<!--- we'll put the jQuery Mobile and HTML here --->
</body>
</html>

Create jQuery Mobile layout

Now let’s setup our html within the body tag. We’ll use the standard setup you can find in the jQuery Mobile documentation.

<section id="page1" data-role="page">
 <header data-role="header" data-position="fixed">
  <h1>First Page</h1>
 </header>
  <div data-role="content">
   Here's your first name: <span class="first-name" style="font-weight:bold;"></span><br/>
   <a href="#page2">Click here</a> to see your last name
  </div>
</section>

Here’s our first pagelet. It has an ID of “page1″, and a title of “First page”. If you have everything setup right so far, you should see an image like this:

Now let’s setup page 2. You’ll notice above that we’ve used a link tag with a href=”#page2″. jQuery Mobile takes this and navigates us to “page” 2, even though it is simply another section on the same aspx page. Here’s what you’ll have, and the image follows:

<section id="page2" data-role="page">
 <header data-role="header" data-position="fixed">
  <h1>Second Page</h1>
 </header>
  <div data-role="content">
   Here's your last name: <span class="last-name" style="font-weight:bold;"></span><br/>
   <a href="#page1">Go back</a> to see your first name
  </div>
</section>

Create functions

Now that we’ve created our pages, it’s time to create the functions. We’re going to create two functions. One will call the first name of the user, and one will call the last name. Once it gets the first/last name, it appends the value of that variable to the empty ‘span’ tags we created in the step above. This is a basic example, but you’ll get the point at least.

So the first thing we need to do is create the functions on document ready. But note that we won’t CALL the functions just yet.

First function (to get first name of the logged in user):

function getFirstName() {
  firstname = $().SPServices.SPGetCurrentUser({fieldName: "FirstName"})
  $(".first-name").append(firstname);
}	

Second function (to get last name of the logged in user):

function getLastName() {
  lastname = $().SPServices.SPGetCurrentUser({fieldName: "LastName"})
  $(".last-name").append(lastname);
}

Call functions on page change

Right now these two functions are just sitting in the script tag, but we want to call them. You can do one of two things:

  1. call the functions right away
  2. call whenever the new pagelet loads

Because of the functions I am calling in one of my other projects, I’ve decided to call the function each time each pagelet loads. That means that even though jQuery Mobile loads the new pagelet without reloading the url, my data will still load in asynchronously. So when we click on “click here to see your last name”, it will then call the function when that pagelet comes into view.

The other way is fine as well, it just means that while you are using your new web app, the data only loads when the document is ready. This means if data changes while you are navigating, you won’t see the change until you refresh the page.

Note: If you call the functions each time the page is loaded, your script must remain above the jquery mobile js reference (see step 2). This because you need to tweak the DOM before jQuery Mobile applies its classes and functionality to the page.

So onto the code! We’re going to use the jQuery function “on” and pass the event “pagecreate”. Like I mentioned above, this means the function will only run when the page is created (every time).

$("section#page1").live("pagecreate", function(event){
  getFirstName();
});
$("section#page2").live("pagecreate", function(event){
  getLastName();
});

Now you should see the following when you load each page:

Full Code

And for your copying and pasting pleasure, here’s the full code!

<!DOCTYPE html>
<html>
<head>
<meta name="WebPartPageExpansion" content="full" />
<title>SharePoint, SPServices, and jQuery Mobile!</title>
	<link rel="apple-touch-icon" href="/Style Library/Images/apple-touch-icon.jpg"/>
	<meta name="viewport" content="user-scalable=yes, width=device-width, initial-scale=1"> 
	<link rel="stylesheet" href="/Style Library/scripts/jquery.mobile-1.0.1/jquery.mobile-1.0.1.min.css" />
	<script src="/Style Library/scripts/jquery-1.6.4.min.js"></script>
	<script src="/Style Library/scripts/jquery.SPServices-0.7.0.min.js"></script>

<!--[if lt IE 9]>
<script src="/Style Library/scripts/html5.js"></script>
<![endif]-->

	<script type="text/javascript">
		$(document).ready(function(){
			
function getFirstName() {
	firstname = $().SPServices.SPGetCurrentUser({fieldName: "FirstName"})
	$(".first-name").append(firstname);
}		
function getLastName() {
	lastname = $().SPServices.SPGetCurrentUser({fieldName: "LastName"})
	$(".last-name").append(lastname);
}
			
$("section#page1").live("pagecreate", function(event){
  getFirstName();
});
$("section#page2").live("pagecreate", function(event){
  getLastName();
});		})
	</script>
	<script src="/Style Library/scripts/jquery.mobile-1.0.1/jquery.mobile-1.0.1.min.js"></script>
</head>
<body>

<section id="page1" data-role="page">
 <header data-role="header" data-position="fixed">
  <h1>First Page</h1>
 </header>
  <div data-role="content">
   Here's your first name: <span class="first-name" style="font-weight:bold;"></span><br/>
   <a href="#page2">Click here</a> to see your last name
  </div>
</section>

<section id="page2" data-role="page">
 <header data-role="header" data-position="fixed">
  <h1>Second Page</h1>
 </header>
  <div data-role="content">
   Here's your last name: <span class="last-name" style="font-weight:bold;"></span><br/>
   <a href="#page1">Go back</a> to see your first name
  </div>
</section>

</body>

</html>

Enjoy!

Ben

jQuery and SharePoint 2010: the Basics

SharePoint out-of-the-box is functional, but fairly lacking when it comes to really wanting to extract and beautify your data. This is where jQuery comes in. It’s light, easy to implement, and actually hooks up with a bunch of SharePoint services when you have the right plugins. Consider this a basic intro to what you can do in jQuery and SharePoint. It’s really the tip of the iceberg, so keep exploring!

Setup jQuery for SharePoint

First things first, let’s make sure we’re properly setup. If you are using SharePoint behind a secure server (as part of an intranet possibly), then you’ll probably want to load up a local copy of the jQuery script instead of grabbing it from jquery.com each time the page loads. So grab the latest build from jquery.com and dump it in “Style Library/scripts/jquery.js”.

Next, go to your master page and put the following script (depending on where your file is) anywhere within the HEAD section:

 <script type="text/javascript" src="/Style Library/scripts/jquery.js"></script>

And that’s it! Now every time a page loads, you’re pulling in all of jQuery’s power. Minified, the file is only about 31kb, so (considering everything else SharePoint is loading) this isn’t that much of a burden. But you can also just load the jQuery script in page layouts, or even within individual pages.

Now that you’ve got jQuery loaded, it might be in your best interest to create another .js file that holds all of your custom scripts. You can choose to do scripts on a per page or page layout basis as well, but this keeps things more organized. So create a “myscripts.js” file in “Style Library/scripts” (the same folder we put jQuery.js in). And don’t forget to reference it in your master page, right under the jquery code. So now the above code is amended to read:

 <script type="text/javascript" src="/Style Library/scripts/jquery.js"></script>
 <script type="text/javascript" src="/Style Library/scripts/myscripts.js"></script>

Now that we’ve got everything loaded, what can we do?

What can you do with jQuery and SharePoint?

Here are just a few things:

Markup your body content and make it interactive

I use this for something like an FAQ section. We’ll put every question in an H4 tag with a class of “question” and every answer in a span with a class of “answer” directly after the h4. That’s all we have to do to our HTML source in the page. Then in our custom scripts file (above) we add the following jQuery code:

$(document).ready(function(){ 
 $("span.answer").slideUp(); // hides all of the answers
 $("h4.question").click(function(){ // when you click an h4
   $(this).next("span.answer").slideToggle('fast') //the answer slides down
 })
});

Keep in mind you may want to add some CSS that make the h4 seem more like a link (cursor:pointer, etc.) so people know they should click.

Make an “instant” search/filter box


Check out this post about how to create this. You can create a filter, and then append it to any list across your site.

Create a slideshow of content from a picture library


I’ve written a separate post with precise instructions about how to do this, but here’s the general idea:

  1. Create a picture library
  2. Make a new page
  3. Put a CQWP in the page, and wrap it in some divs with specific classes
  4. Use the tinycarousel plugin to convert that Content Query WebPart into a slideshow/carousel
  5. Style with CSS

Create tabs (not the jQuery UI kind)

Check out this post on creating tabs using jQuery, but without using the jQuery UI. It’s a bit easier with the UI plugin, but again, the idea is:

  1. Create the tabs in HTML
  2. Create each panel in HTML
  3. Add the jQuery
  4. Style it with CSS

Use SPServices to really hook into SharePoint with jQuery

I’ve started writing what is turning into a small series on using jQuery with SPServices. Some of the things you can do:
Rollup items from multiple lists
Rollup from multiple lists and put the results in a new list
Rollup articles across a site collection

Rollup articles across a site collection (using jQuery) in SharePoint 2010

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>

Learning Sharepoint 2010 Branding

If you’re looking for a great resource to begin learning how to brand and design in Sharepoint 2010, check out Professional Sharepoint 2010 Branding and User Interface Design. It’s a great read, and if you purchase through my link, it helps pay for my hosting!

Or you can purchase the Kindle Version