<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>SPMatt</title>
	<atom:link href="http://spmatt.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://spmatt.wordpress.com</link>
	<description>Discussing all things SharePoint from Perth, Western Australia</description>
	<lastBuildDate>Sun, 19 Feb 2012 08:02:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='spmatt.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>SPMatt</title>
		<link>http://spmatt.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://spmatt.wordpress.com/osd.xml" title="SPMatt" />
	<atom:link rel='hub' href='http://spmatt.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Using the Content Query Web Part and jQuery to create a staff desk locator</title>
		<link>http://spmatt.wordpress.com/2012/02/18/using-the-content-query-web-part-and-jquery-to-create-a-staff-desk-locator/</link>
		<comments>http://spmatt.wordpress.com/2012/02/18/using-the-content-query-web-part-and-jquery-to-create-a-staff-desk-locator/#comments</comments>
		<pubDate>Fri, 17 Feb 2012 17:25:59 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Content Editor Web Part]]></category>
		<category><![CDATA[Content Query Web Part]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[MapBox]]></category>
		<category><![CDATA[SharePoint lists]]></category>
		<category><![CDATA[Videos]]></category>
		<category><![CDATA[XSL]]></category>

		<guid isPermaLink="false">http://spmatt.wordpress.com/?p=353</guid>
		<description><![CDATA[I recently took it upon myself to provide an alternative to the staff desk locator that was due to go to production in the near future. The back-story is that a requirement existed to locate staff on a floor map to assist with the move to a new office complex. The original concept was created [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=353&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I recently took it upon myself to provide an alternative to the staff desk locator that was due to go to production in the near future. The back-story is that a requirement existed to locate staff on a floor map to assist with the move to a new office complex. The original concept was created by another developer, but with multiple requirement changes and multiple developers tweaking the original solution, the end result was far from perfect. It only worked completely in IE7 standards browser mode and some of the functionality performed in a less than ideal fashion &#8211; think scroll bars to navigate around a zoomed in map amongst other imperfections.</p>
<p>Now the solution I present here is also far from perfect, I have no illusions about that. I debated whether to post about it at all until I had a chance to optimse and refine it seeing that what exists here is essentially a protoype, however I believe it is in a complete enough state to provide some benefit or interest to people out there. If anyone can propose some better ways of achieving some of the functionality demonstrated here I&#8217;d be more than interested in hearing it. The first half of the post will explain the journey, so if you&#8217;re not interested in what drove the implementation decisions along the way, feel free to skip down to the solution.</p>
<p><strong>The Journey</strong></p>
<p>The concept I was going for was something similar to Google Maps; your standard zoom, move, mouse-wheel and drag functionality. The most attractive option I could find was a paid solution called MapBox which can be seen in their various <a href="http://tiles.mapbox.com/" target="_blank">featured map demos</a>. I didn&#8217;t think a paid solution would be an option and besides, I wanted to see if I could create something similar myself. I found a jQuery plugin also called MapBox documented at <a href="http://wayfarerweb.com/jquery/plugins/mapbox/" target="_blank">Mapbox: Zoomable jQuery Map Plugin</a> which definitely appeared to get me half way there. The only remaining challenge was to plot the points on the map and get it driven via SharePoint.</p>
<p>Plotting the points definitely proved challenging. I went through a few iterations as I lead myself down some wrong paths &#8211; the joys of experimentation. I went so far as to get everything adjusting correctly from a movement point of view (thinking I was better off starting easy and leaving the complicated functionality for later) only to have it breaking during zoom. It wasn&#8217;t until I further investigated the zoom requirements and changed the way in which I was approaching the challenge that I realised the work I had done to adjust for movement was redundant and was handled by the plugin. Lovely.</p>
<p>I eventually got the locations remaining in place during zooming however this exposed its own issues; the pins representing each location didn&#8217;t adjust in size as the map did, resulting in a very strange looking experience. It is here where my solution is least elegant &#8211; I essentially created multiple CSS classes and multiple sized images and dynamically changed the class of the elements as I zoomed in and out (using the width of the parent div to differentiate). I couldn&#8217;t simply scale the image as I was using background images and divs rather than image elements (for reasons based on issues with the previous solution and brief experimentation in this one). This exposed even more gotchyas &#8211; it appears different browsers round decimal values in different ways (there were variations around rounding, floor or ceiling). I also noticed that while on most occassions the plugin would zoom to fixed width sizes, occassionally it would result in completely unexpected values which I needed a safety net CSS definition for. I love Internet Explorer. The CSS is hence a pretty ugly beast, but for the most part it works.</p>
<p>The next step was adding some hover over functionality to display the staff members information. This was relatively simple and just leveraged the onMouseOver event and some jQuery for each plotted element. The search functionality was a little more complex. I had witnessed the functionality I desired during my research, present on the <a href="http://www.rocknrollmetromap.com/" target="_blank">Rock &#8216;n&#8217; Roll Metro Map</a>, which I dug deeper into and discovered it was being achieved via the animate function of the jQuery UI plugin. A couple of equations and experimentation later to determine how I could establish my scroll-to points and it was all humming along nicely.</p>
<p>The final challenge was getting it all into SharePoint. This functionality was to sit on the intranet which had been created as a codeless solution, therefore rather than rendering what I needed via the API in a web part I decided to stick with the theme and leverage the Content Query Web Part (CQWP), drawing out of a custom list. The previous solution had done the same so it wasn&#8217;t too difficult with a few tweaks to achieve what I desired. A couple of the gotchyas encountered included ensuring the CommonViewFields were set in the CQWP (exporting and importing the web part was used to achieve this) and rediscovering that for a column to exist to filter on in the web part it needed to be a site column, not just a list column. One last little hurdle that needed to be jumped included how the parts sat on the page with the master page being used &#8211; and this differed between browsers (Did I mention how much I love IE?). Seeing this probably had a lot to do with the custom master page being used I&#8217;ll leave the specifics out in the solution below, however just know that it is something that may need to be considered.</p>
<p><strong>The Solution</strong></p>
<p>Part 1: The list to hold the data</p>
<p>This was a custom list with some custom columns. Note that the IsAResource column is a site column. The -1000 X and Y values reflect a staff member that does not exist in the building.</p>
<p><a href="http://spmatt.files.wordpress.com/2012/02/list1.png" target="_blank"><img class="alignnone size-full wp-image-361" title="list" src="http://spmatt.files.wordpress.com/2012/02/list1.png?w=630&#038;h=114" alt="" width="630" height="114" /></a></p>
<p>Part 2: Header.xsl</p>
<p>The templates in Header.xsl map to the Group Style settings selected in the Content Query Web Parts. They render once to open and close the items which are rendered in between. The below templates were defined.</p>
<p><pre class="brush: xml;">
  &lt;xsl:template name=&quot;DeskfinderSelectName&quot; match=&quot;*[@GroupStyle='DeskfinderSelectName']&quot; mode=&quot;header&quot;&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;document.write('&lt;![CDATA[&lt;div id=&quot;SearchByName&quot;&gt;&lt;span class=&quot;SearchLabel&quot;&gt;Search by Name:&lt;/span&gt;&lt;select onchange=&quot;FindUser(this.value);&quot;&gt;&lt;option value=&quot;&quot;&gt;Please select an option...&lt;/option&gt;]]&gt;')&lt;/script&gt;
  &lt;/xsl:template&gt;
  &lt;xsl:template name=&quot;DeskfinderSelectNameClose&quot; match=&quot;*[@GroupStyle='DeskfinderSelectName']&quot; mode=&quot;footer&quot;&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;document.write('&lt;![CDATA[&lt;/select&gt;&lt;/div&gt;]]&gt;')&lt;/script&gt;
  &lt;/xsl:template&gt;
  &lt;xsl:template name=&quot;DeskfinderSelectResource&quot; match=&quot;*[@GroupStyle='DeskfinderSelectResource']&quot; mode=&quot;header&quot;&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;document.write('&lt;![CDATA[&lt;div id=&quot;SearchByResource&quot;&gt;&lt;span class=&quot;SearchLabel&quot;&gt;Search by Resource:&lt;/span&gt;&lt;select onchange=&quot;FindUser(this.value);&quot;&gt;&lt;option value=&quot;&quot;&gt;Please select an option...&lt;/option&gt;]]&gt;')&lt;/script&gt;
  &lt;/xsl:template&gt;
  &lt;xsl:template name=&quot;DeskfinderSelectResourceClose&quot; match=&quot;*[@GroupStyle='DeskfinderSelectResource']&quot; mode=&quot;footer&quot;&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;document.write('&lt;![CDATA[&lt;/select&gt;&lt;/div&gt;]]&gt;')&lt;/script&gt;
  &lt;/xsl:template&gt;
  &lt;xsl:template name=&quot;DeskfinderPin&quot; match=&quot;*[@GroupStyle='DeskfinderPin']&quot; mode=&quot;header&quot;&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;document.write('&lt;![CDATA[&lt;div class=&quot;StaffLocations&quot;&gt;]]&gt;')&lt;/script&gt;
  &lt;/xsl:template&gt;
</pre></p>
<p>The most important part to note here is that the DeskfinderPin doesn&#8217;t have an associated footer. This was a bit of a gotchya &#8211; the browsers closed off the div anyway but if I included the footer, the</p>
<p><pre class="brush: xml;">
&lt;script type=&quot;text/javascript&quot;&gt;document.write('&lt;![CDATA[&lt;/div&gt;]]&gt;')&lt;/script&gt;
</pre></p>
<p>node was appearing within the div which caused issues when I went to extract the HTML via jQuery and pump it into other locations. It worked fine without the footer so it was removed.</p>
<p>Part 3: ItemStyle.xsl</p>
<p>The templates in ItemStyle.xsl map to the Item Style settings selected in the Content Query Web Parts. They&#8217;re rendered for each item in the query. The below templates were defined.</p>
<p><pre class="brush: xml;">
  &lt;xsl:template name=&quot;DeskfinderSelectOption&quot; match=&quot;Row[@Style='DeskfinderSelectOption']&quot; mode=&quot;itemstyle&quot;&gt;
    &lt;xsl:variable name=&quot;DisplayTitle&quot;&gt;
      &lt;xsl:call-template name=&quot;OuterTemplate.GetTitle&quot;&gt;
        &lt;xsl:with-param name=&quot;Title&quot; select=&quot;@Title&quot;/&gt;
        &lt;xsl:with-param name=&quot;UrlColumnName&quot; select=&quot;'LinkUrl'&quot;/&gt;
      &lt;/xsl:call-template&gt;
    &lt;/xsl:variable&gt;
    &lt;option value=&quot;{@ID}&quot;&gt;
      &lt;xsl:value-of select=&quot;$DisplayTitle&quot;/&gt;
    &lt;/option&gt;
  &lt;/xsl:template&gt;
  &lt;xsl:template name=&quot;DeskfinderPin&quot; match=&quot;Row[@Style='DeskfinderPin']&quot; mode=&quot;itemstyle&quot;&gt;
    &lt;xsl:variable name=&quot;DisplayTitle&quot;&gt;
      &lt;xsl:call-template name=&quot;OuterTemplate.GetTitle&quot;&gt;
        &lt;xsl:with-param name=&quot;Title&quot; select=&quot;@Title&quot;/&gt;
        &lt;xsl:with-param name=&quot;UrlColumnName&quot; select=&quot;'LinkUrl'&quot;/&gt;
      &lt;/xsl:call-template&gt;
    &lt;/xsl:variable&gt;
    &lt;xsl:choose&gt;
      &lt;xsl:when test=&quot;starts-with(@Location,'L2')&quot;&gt;
		&lt;div class=&quot;pin2&quot; style=&quot;left:{@X}px; top:{@Y}px;&quot; onMouseOver=&quot;DisplayDetails(this);&quot; data-id=&quot;{@ID}&quot; data-xpos=&quot;{@X}&quot; data-ypos=&quot;{@Y}&quot; data-name=&quot;{$DisplayTitle}&quot; data-phone=&quot;{@Phone}&quot; data-email=&quot;{@Email}&quot;&gt;&lt;/div&gt;
      &lt;/xsl:when&gt;
      &lt;xsl:otherwise&gt;
        &lt;div class=&quot;pin3&quot; style=&quot;left:{@X}px; top:{@Y}px;&quot; onMouseOver=&quot;DisplayDetails(this);&quot; data-id=&quot;{@ID}&quot; data-xpos=&quot;{@X}&quot; data-ypos=&quot;{@Y}&quot; data-name=&quot;{$DisplayTitle}&quot; data-phone=&quot;{@Phone}&quot; data-email=&quot;{@Email}&quot;&gt;&lt;/div&gt;
      &lt;/xsl:otherwise&gt;
    &lt;/xsl:choose&gt;
  &lt;/xsl:template&gt;
</pre></p>
<p>It is important to note that all of the custom columns referenced in the template (X, Y, Email, Phone) need to appear in the CommonViewFields element of the Content Query Web Part to be recognised. This can be done by exporting the web part, manually editing the .webpart file to add those columns and importing it back onto the page.</p>
<p>Part 4: The resources</p>
<p>CSS &#8211; the CSS used was extended from that used for the MapBox demo with some slight tweaks to those definitions. A little more was added to style the drop down menus and staff information. The majority of CSS was to style the pins mapping to the locations of staff members. As mentioned before, this was a very bloated solution and far too much to include in this post. I&#8217;ll try and summarise.</p>
<p>There were essentially 4 groups of styles &#8211; level 2 pins, level 3 pins, level 2 &#8216;located&#8217; pins and level 3 &#8216;located&#8217; pins. These were seperated into whether they appeared in the firstLayer, secondLayer, thirdLayer or fourthLayer. They were further seperated into sizes mapping to the width of the parent div (the reason for 2 sizes 1 pixel apart is due to the rounding issue I mentioned earlier). Here are a few randomly selected examples:</p>
<p><pre class="brush: css;">
#firstLayer .pin2
{
	position: absolute;
	width: 10px;
	height: 9px;
	background: url(../PublishingImages/pin2-size709.gif);
}

#secondLayer .pin2.found.size974, #secondLayer .pin2.found.size975
{
	width: 16px;
	height: 16px;
	background: url(../PublishingImages/found2-size975.gif);
}

#fourthLayer .pin3 {
	position: absolute;
	width: 30px;
	height: 27px;
	background: url(../PublishingImages/pin3-size2126.gif);
}

#fourthLayer .pin3.size1505, #fourthLayer .pin3.size1506 {
	width: 21px;
	height: 19px;
	background: url(../PublishingImages/pin3-size1506.gif);
}
</pre></p>
<p>You get the idea. Perhaps look into an alternative solution!</p>
<p>Images &#8211; The images included the 4 different sized floor map images, the map control image and 100 different pin images to match the CSS styles.</p>
<p>JavaScript &#8211; The javascript leveraged that provided with the MapBox demo with the following adjustments.</p>
<p>Functionality to populate the staff information:</p>
<p><pre class="brush: jscript;">
function DisplayDetails(person)
{
	$(&quot;#staffName&quot;).text($(person).attr(&quot;data-name&quot;));
	$(&quot;#staffPhone&quot;).text($(person).attr(&quot;data-phone&quot;));
	$(&quot;#staffEmail&quot;).html('&lt;a href=&quot;mailto:' + $(person).attr(&quot;data-email&quot;) + '&quot;&gt;' + $(person).attr(&quot;data-email&quot;) + '&lt;/a&gt;');
}
</pre></p>
<p>Functionality to find a given user or resource:</p>
<p><pre class="brush: jscript;">
function FindUser(id)
{
	var limitX = 0, limitY = 0, mapWidth = $(&quot;.mapwrapper&quot;).width(), mapHeight = $(&quot;.mapwrapper&quot;).height(),
	nodeWidth = $(&quot;.current-map-layer&quot;).width(), nodeHeight = $(&quot;.current-map-layer&quot;).height();

	if(mapWidth &lt; nodeWidth) limitX = mapWidth - nodeWidth;
	if(mapHeight &lt; nodeHeight) limitY = mapHeight - nodeHeight;

	var element = $(&quot;.current-map-layer div[data-id='&quot; + id + &quot;']&quot;);
	var left = (parseInt($(element).css(&quot;left&quot;)) * -1) + (parseInt($(&quot;.mapwrapper&quot;).css(&quot;width&quot;)) / 2);
	var top = (parseInt($(element).css(&quot;top&quot;)) * -1) + (parseInt($(&quot;.mapwrapper&quot;).css(&quot;height&quot;)) / 2);

	left = (left &gt; 0) ? 0 : left;
	left = (left &lt; limitX) ? limitX : left;
	top = (top &gt; 0) ? 0 : top;
	top = (top &lt; limitY) ? limitY : top;

	var width = parseInt($(&quot;.current-map-layer&quot;).css(&quot;width&quot;));
	if ($(&quot;div[data-id='&quot; + id + &quot;']&quot;).attr(&quot;class&quot;).indexOf(&quot;pin2&quot;) == -1)
		$(&quot;div[data-id='&quot; + id + &quot;']&quot;).attr(&quot;class&quot;, &quot;pin3 found size&quot; + width);
	else
		$(&quot;div[data-id='&quot; + id + &quot;']&quot;).attr(&quot;class&quot;, &quot;pin2 found size&quot; + width);

	$(&quot;.current-map-layer&quot;).animate({top: top,left: left}, {easing: &quot;easeOutQuart&quot;});
	DisplayDetails(element);
}
</pre></p>
<p>The important thing to note here is that extra code was required to ensure the map wasn&#8217;t moved &#8216;out of viewport&#8217;. Thankfully, the MapBox JavaScript already included that logic for its drag functionality so I just leveraged that.</p>
<p>Document Ready functionality:</p>
<p><pre class="brush: jscript;">
$(document).ready(function() {
	$(&quot;#firstLayer,.mapcontent&quot;).html($(&quot;.StaffLocations&quot;).html());

	$(&quot;#viewport&quot;).mapbox({
		mousewheel: true,
		layerSplit: 8//smoother transition for mousewheel
	});
	$(&quot;.map-control a&quot;).click(function() {//control panel
		var viewport = $(&quot;#viewport&quot;);
		//this.className is same as method to be called
		if(this.className == &quot;zoom&quot; || this.className == &quot;back&quot;) {
			viewport.mapbox(this.className, 2);//step twice
		}
		else {
			viewport.mapbox(this.className);
		}
		return false;
	});
})
</pre></p>
<p>The first line is the most important &#8211; this is where the HTML is taken from the hidden div rendered by our Content Query Web Part and injected into the necessary locations. The rest of the code is the same that existed for the MapBox demo.</p>
<p>Custom changes to the _zoom function (insert above return movement; line)</p>
<p><pre class="brush: jscript;">
/* Custom changes */
var xChange = (totalWidth == undefined) ? 1 : totalWidth / $(&quot;#firstLayer&quot;).width();
var yChange = (totalHeight == undefined) ? 1 : totalHeight / $(&quot;#firstLayer&quot;).height();

$(&quot;.pin2,.pin3&quot;).each(function(index, value) {
	$(this).css(&quot;left&quot;, ($(this).attr(&quot;data-xpos&quot;) * xChange));
	$(this).css(&quot;top&quot;, ($(this).attr(&quot;data-ypos&quot;) * yChange));

	var width = parseInt($(&quot;.current-map-layer&quot;).css(&quot;width&quot;));
	if ($(this).attr(&quot;class&quot;).indexOf(&quot;pin2&quot;) == -1)
	{
		if ($(this).attr(&quot;class&quot;).indexOf(&quot;found&quot;) == -1)
			$(this).attr(&quot;class&quot;, &quot;pin3 size&quot; + width);
		else
			$(this).attr(&quot;class&quot;, &quot;pin3 found size&quot; + width);
	}
	else
	{
		if ($(this).attr(&quot;class&quot;).indexOf(&quot;found&quot;) == -1)
			$(this).attr(&quot;class&quot;, &quot;pin2 size&quot; + width);
		else
			$(this).attr(&quot;class&quot;, &quot;pin2 found size&quot; + width);
	}
});
/* End Custom changes */
</pre></p>
<p>Part 5: Referencing the resources</p>
<p>This was a chromeless Content Editor Web Part referencing the required resources:</p>
<p><pre class="brush: xml;">
&lt;link href=&quot;../Documents/master.css&quot; type=&quot;text/css&quot; rel=&quot;stylesheet&quot;&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../Documents/mousewheel.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../Documents/mapbox.js&quot;&gt;&lt;/script&gt;
</pre></p>
<p>Take note the version of jQuery referenced &#8211; it&#8217;s not the latest, but was required for MapBox to function correctly.</p>
<p>Part 6: The search box</p>
<p>This was a chromeless Content Query Web Part pointing to the list in Part 1. It was set to show items of type &#8216;Custom List&#8217; and filtered where &#8216;IsAResource is equal to 0&#8242;. The Presentation was grouped by &lt;Site&gt; (to ensure the group element was rendered) and sorted by &#8216;Title ascending&#8217;. The &#8216;Limit the number of items to display&#8217; was turned off. The Group Style was set to &#8216;DeskfinderSelectName&#8217; and Item Style set to &#8216;DeskfinderSelectOption&#8217;.</p>
<p>To include a Search by Resource box as well as a Search by Name box, the steps above can be followed, however the filter value should be 1 and the Group Style should be set to &#8216;DeskfinderSelectResource&#8217;.</p>
<p><a href="http://spmatt.files.wordpress.com/2012/02/searchby.png" target="_blank"><img class="alignnone size-full wp-image-356" title="searchby" src="http://spmatt.files.wordpress.com/2012/02/searchby.png?w=630" alt=""   /></a></p>
<p>Part 7: The map, associated controls and staff information</p>
<p>This was a chromeless Content Editor Web Part which essentially rendered the HTML which existed in the MapBox demo with a few minor tweaks.</p>
<p><pre class="brush: xml;">
&lt;div class=&quot;mapwrapper&quot;&gt;
	&lt;div id=&quot;viewport&quot; style=&quot;overflow: hidden; position: relative;&quot;&gt;
		&lt;div id=&quot;firstLayer&quot; class=&quot;current-map-layer&quot; style=&quot;background: url('Images/FloorImage1.png') no-repeat scroll 0% 0% transparent; width: 709px; height: 631px; position: absolute; display: block; left: 0px; top: 0px;&quot;&gt;
		&lt;/div&gt;
		&lt;div id=&quot;secondLayer&quot; style=&quot;height: 947px; width: 1063px; position: absolute; display: none;&quot;&gt;
			&lt;img style=&quot;width: 100%; position: absolute; left: 0pt; top: 0pt;&quot; src=&quot;Images/FloorImage.png&quot; alt=&quot;&quot;&gt;
			&lt;div style=&quot;position: absolute; left: 0pt; top: 0pt; background: none repeat scroll 0% 0% white; opacity: 0;&quot; class=&quot;map-layer-mask&quot;&gt;&lt;/div&gt;
			&lt;div style=&quot;position: absolute; top: 0pt; left: 0pt;&quot; class=&quot;mapcontent&quot;&gt;
			&lt;/div&gt;
		&lt;/div&gt;
		&lt;div id=&quot;thirdLayer&quot; style=&quot;height: 1262px; width: 1417px; position: absolute; display: none;&quot;&gt;
			&lt;img style=&quot;width: 100%; position: absolute; left: 0pt; top: 0pt;&quot; src=&quot;Images/FloorImage.png&quot; alt=&quot;&quot;&gt;
			&lt;div style=&quot;position: absolute; left: 0pt; top: 0pt; background: none repeat scroll 0% 0% white; opacity: 0;&quot; class=&quot;map-layer-mask&quot;&gt;&lt;/div&gt;
			&lt;div style=&quot;position: absolute; top: 0pt; left: 0pt;&quot; class=&quot;mapcontent&quot;&gt;
			&lt;/div&gt;
		&lt;/div&gt;
		&lt;div id=&quot;fourthLayer&quot; style=&quot;height: 1893px; width: 2126px; position: absolute; display: none;&quot;&gt;
			&lt;img style=&quot;width: 100%; position: absolute; left: 0pt; top: 0pt;&quot; src=&quot;Images/FloorImage.png&quot; alt=&quot;&quot;&gt;
			&lt;div style=&quot;position: absolute; left: 0pt; top: 0pt; background: none repeat scroll 0% 0% white; opacity: 0;&quot; class=&quot;map-layer-mask&quot;&gt;&lt;/div&gt;
			&lt;div style=&quot;position: absolute; top: 0pt; left: 0pt;&quot; class=&quot;mapcontent&quot;&gt;
			&lt;/div&gt;
		&lt;/div&gt;
	&lt;/div&gt;
	&lt;div class=&quot;map-control&quot;&gt;
		&lt;a href=&quot;#left&quot; class=&quot;left&quot;&gt;Left&lt;/a&gt;
		&lt;a href=&quot;#right&quot; class=&quot;right&quot;&gt;Right&lt;/a&gt;
		&lt;a href=&quot;#up&quot; class=&quot;up&quot;&gt;Up&lt;/a&gt;
		&lt;a href=&quot;#down&quot; class=&quot;down&quot;&gt;Down&lt;/a&gt;
		&lt;a href=&quot;#zoom&quot; class=&quot;zoom&quot;&gt;Zoom&lt;/a&gt;
		&lt;a href=&quot;#zoom_out&quot; class=&quot;back&quot;&gt;Back&lt;/a&gt;
	&lt;/div&gt;
	&lt;div class=&quot;staff-information&quot;&gt;
		&lt;div&gt;&lt;span class=&quot;staff-info-label&quot;&gt;Name: &lt;/span&gt;&lt;span id=&quot;staffName&quot;&gt;&lt;/span&gt;&lt;/div&gt;
		&lt;div&gt;&lt;span class=&quot;staff-info-label&quot;&gt;Phone: &lt;/span&gt;&lt;span id=&quot;staffPhone&quot;&gt;&lt;/span&gt;&lt;/div&gt;
		&lt;div&gt;&lt;span class=&quot;staff-info-label&quot;&gt;Email: &lt;/span&gt;&lt;span id=&quot;staffEmail&quot;&gt;&lt;/span&gt;&lt;/div&gt;
	&lt;/div&gt;
&lt;/div&gt;
</pre></p>
<p>Note that the images and sizes were adjusted respectively and each layer div was given an id so I could reference them via both jQuery and CSS. The staff-information div was also included to present the staff information.</p>
<p>Part 8: The staff locations</p>
<p>This was a chromeless Content Query Web Part pointing to the list in Part 1. It was set to show items of type &#8216;Custom List&#8217;, grouped by &lt;Site&gt; and the &#8216;Limit the number of items to display&#8217; was turned off. The Group Style was set to &#8216;DeskfinderPin&#8217; and Item Style set to &#8216;DeskfinderPin&#8217;.</p>
<p>Note that the contents rendered here were within a div hidden by the CSS &#8211; it&#8217;s main purpose was to render the data once, then jQuery injected it into the locations required.</p>
<p><strong>The End Result</strong></p>
<p>An image doesn&#8217;t really do it justice, but for the purposes of completing the article, the end result looks something like that depicted below.</p>
<p><a href="http://spmatt.files.wordpress.com/2012/02/endresult2.png"><img class="alignnone size-full wp-image-367" title="endresult" src="http://spmatt.files.wordpress.com/2012/02/endresult2.png?w=630&#038;h=450" alt="" width="630" height="450" /></a></p>
<p>Either that or you can watch a video below on how the functionality works.</p>
<span style="text-align:center; display: block;"><a href="http://spmatt.wordpress.com/2012/02/18/using-the-content-query-web-part-and-jquery-to-create-a-staff-desk-locator/"><img src="http://img.youtube.com/vi/d9oW0c_3D78/2.jpg" alt="" /></a></span>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spmatt.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spmatt.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spmatt.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spmatt.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/spmatt.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/spmatt.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/spmatt.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/spmatt.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spmatt.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spmatt.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spmatt.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spmatt.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spmatt.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spmatt.wordpress.com/353/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=353&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://spmatt.wordpress.com/2012/02/18/using-the-content-query-web-part-and-jquery-to-create-a-staff-desk-locator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0d26e27d7507158fb5a229f002b3c314?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">menezesm</media:title>
		</media:content>

		<media:content url="http://spmatt.files.wordpress.com/2012/02/list1.png" medium="image">
			<media:title type="html">list</media:title>
		</media:content>

		<media:content url="http://spmatt.files.wordpress.com/2012/02/searchby.png" medium="image">
			<media:title type="html">searchby</media:title>
		</media:content>

		<media:content url="http://spmatt.files.wordpress.com/2012/02/endresult2.png" medium="image">
			<media:title type="html">endresult</media:title>
		</media:content>
	</item>
		<item>
		<title>Custom Error Pages in SharePoint</title>
		<link>http://spmatt.wordpress.com/2012/02/06/custom-error-pages-in-sharepoint/</link>
		<comments>http://spmatt.wordpress.com/2012/02/06/custom-error-pages-in-sharepoint/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 14:09:16 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Error Handling]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[SharePoint 2007]]></category>
		<category><![CDATA[IIS7]]></category>
		<category><![CDATA[Exception handling]]></category>
		<category><![CDATA[Error page]]></category>
		<category><![CDATA[Custom Error Page]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[Page Not Found]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[HTTP Module]]></category>
		<category><![CDATA[Control Adapter]]></category>
		<category><![CDATA[Master Page]]></category>

		<guid isPermaLink="false">http://spmatt.wordpress.com/?p=341</guid>
		<description><![CDATA[As I alluded to in my post Exception Handling in SharePoint, providing custom error pages is an integral step in an overall exception handling strategy. This is particularly important for public facing internet sites to portray a consistent brand for the site in any situation, however is also relevant for intra or extranet portals to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=341&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>As I alluded to in my post <a title="Exception Handling in SharePoint" href="http://spmatt.wordpress.com/2012/02/01/exception-handling-in-sharepoint/" target="_blank">Exception Handling in SharePoint</a>, providing custom error pages is an integral step in an overall exception handling strategy. This is particularly important for public facing internet sites to portray a consistent brand for the site in any situation, however is also relevant for intra or extranet portals to provide a more user-friendly experience and to reduce confusion in the event of an error. In similar fashion to my post on <a title="Error Logging in SharePoint" href="http://spmatt.wordpress.com/2012/02/06/error-logging-in-sharepoint/" target="_blank">Error Logging in SharePoint</a>, the information already available on this topic is extensive so the need for me to blog the specifics is negligible. This post will however join the link between my 2 previous posts mentioned above by outlining the best resources available in this area for both SharePoint 2007 and 2010.</p>
<p>In the ASP.NET world this topic would barely rate a mention. Handling this matter is essentially as simple as ensuring the &lt;customErrors&gt; mode=&#8221;" attribute is set to &#8220;On&#8221; and the defaultRedirect=&#8221;" attribute is set to a valid error page. We can&#8217;t use this method in SharePoint however as SharePoint has its own error handling infrastructure which overrides this functionality.</p>
<p>What we do have are different ways in which we can achieve this functionality in both versions of the product. When we talk of error pages in a SharePoint context we can group them into two categories for the purpose of identifying ways in which they can be addressed; 404 Page Not Found error pages and any others (which can include but are not limited to 401 Access Denied errors, 500 HTTP Status errors and the like).</p>
<p><strong>404 Page Not Found</strong></p>
<p>Microsoft has a knowledge base article <a href="http://support.microsoft.com/kb/941329" target="_blank">How to point to a custom 404 error Web page in SharePoint</a> which covers both versions of SharePoint. One thing to note here however is that it&#8217;s not necessary to create a console application to carry out the command in SharePoint 2007 &#8211; you can also use a powershell command to achieve the same thing noted in Ian Morrish&#8217;s post <a href="http://www.wssdemo.com/Blog/archive/2007/12/22/using-powershell-to-set-a-custom-sharepoint-error-page.aspx" target="_blank">Using PowerShell to set a custom SharePoint Error Page</a>.</p>
<p>Another thing to note is that this method requires the specified file to be valid HTML larger than 512 bytes in size. The size limitation is to ensure friendly HTTP error messages are not triggered in the client. I&#8217;ve also seen minorly-invalid HTML rendering as text in the browser so this is another thing to look out for. One more gotchya was identified by Andreas Glaser in <a href="http://andreasglaser.net/post/2009/03/15/SharePoint-and-custom-404-Page-Not-Found-and-UTF-8-issue-with-Firefox.aspx" target="_blank">SharePoint and custom 404 Page Not Found and UTF-8 issue with Firefox</a> which is worth consideration.</p>
<p>One downside to the method presented above is that you are limited to static HTML pages deployed to the _layouts/1033 directory (or which ever LCID is appropriate for your site). This results in branding elements needing to be implemented in the static HTML and ensures maintenance of the page is more complicated than it should be. The main advice here is to implement a redirect on that error page to a standard SharePoint page along the lines identified by Jingmei Li in <a href="http://blogs.msdn.com/b/jingmeili/archive/2007/04/08/how-to-create-your-own-custom-404-error-page-and-handle-redirect-in-sharepoint-2007-moss.aspx" target="_blank">How to create your own custom 404 error page and handle redirect in SharePoint 2007 (MOSS)?</a>.</p>
<p>There is another line of thought however, predominantly outlined by Waldek Mastykarz in his posts <a href="http://blog.mastykarz.nl/accessible-404-pagenotfound-in-microsoft-office-sharepoint-server-2007/" target="_blank">Accessible 404 (PageNotFound) in Microsoft Office SharePoint Server 2007</a> and <a href="http://blog.mastykarz.nl/sharepoint-2010-page-not-found-404/" target="_blank">SharePoint 2010 &#8216;Page not found (404)&#8217; page the way it should be</a>. This advocates using an HTTP Module to redirect the user to a page managed in SharePoint. If you&#8217;re going to go down this path focus on the second article and pay attention to Andrew Greaves&#8217; comment.</p>
<p>While I like Waldek&#8217;s approach and appreciate its thoroughness in its flexibility for working in all scenarios and its technical correctness, for most purposes using the other method would suffice (particularly in controlled internal environments).</p>
<p><strong>Other Error Pages</strong></p>
<p>While the handling of 404 errors is quite similar in both SharePoint 2007 and 2010, the same cannot be said for other errors. SharePoint 2010 excels in this area providing an easy to use method of assigning these custom error pages at the web application level. Todd Carter provides a post titled <a href="http://todd-carter.com/post/2010/04/07/An-Expected-Error-Has-Occurred.aspx" target="_blank">An Expected Error Has Occurred</a> which is well worth a read and while the code snippets are identical, Ram Prasad Meenavalli&#8217;s post <a href="http://www.spdeveloper.co.in/articles/pages/custom-error-pages-for-sharepoint2010-sites.aspx" target="_blank">Mapping Custom Error Pages for SharePoint 2010 Site</a> is a good extension to it. Mike&#8217;s post <a href="http://sharepointlearningcurve.blogspot.com.au/2010/06/sharepoint-2010-custom-error-messages.html" target="_blank">SharePoint 2010 Custom Error Messages for Public Facing Deployments</a> is a quality post particularly in terms of 401 authentication errors and is worth a look as well.</p>
<p>Implementing custom error pages for SharePoint 2007 however is not so simple. There seems to be 3 camps of thought; firstly there is the HTTP Module method similar to that used with the 404&#8242;s outlined above. While its a little difficult to read and follow, this method is documented in Ketaanh Shah&#8217;s post <a href="http://blogs.msdn.com/b/ketaanhs/archive/2010/03/13/moss-sharepoint-2007-custom-error-page-and-access-denied-page.aspx" target="_blank">MOSS / Sharepoint 2007 Custom Error Page and Access denied Page</a>. Another option is using a control adapter as per Aapo Talvensaari&#8217;s post <a href="http://www.sharepointblues.com/2010/02/12/custom-error-page-adapter/" target="_blank">Custom Error Page Adapter</a> although i&#8217;d be a little wary implementing the functionality in this manner. My favourite option is Jeremy Jameson&#8217;s <a href="http://blogs.msdn.com/b/jjameson/archive/2010/03/20/error-handling-in-moss-2007-applications.aspx" target="_blank">Error Handling in MOSS 2007 Applications</a> which advocates hooking into the Error event from a custom master page &#8211; nice and clean, however it&#8217;s only really appropriate for errors that occur once the page has been accessed &#8211; i&#8217;m guessing it wouldn&#8217;t be suitable to handle errors such as a 401 authentication error.</p>
<p>In the interests of completeness there was one other form of configuring custom error pages I came across on Heath Anderson&#8217;s <a href="http://blog.incworx.com/blog/sharepoint-tips-and-tricks/implementing-sharepoint-2010-custom-error-pages-v3" target="_blank">Implementing SharePoint 2010 Custom Error Pages</a>. It is relevant to IIS7 and claims to work in SharePoint 2010 (whether it would work on an WSS instance installed on IIS7 i&#8217;m not sure). It definitely looks like a reasonably nice and clean option to consider, however it requires modifications to the web.config file even after configuring via the IIS UI and thus would not be the perfect option in my opinion.</p>
<p>So as you can see there are a bunch of ways in which you can implement custom error pages for your SharePoint site no matter which version of the product you are using. All methods vary in terms of their difficulty, suitability and correctness however the main takeaway is to ensure that you do use one of the methods and ensure that your users have the most user-friendly experience if they counter an error on your site.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spmatt.wordpress.com/341/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spmatt.wordpress.com/341/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spmatt.wordpress.com/341/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spmatt.wordpress.com/341/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/spmatt.wordpress.com/341/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/spmatt.wordpress.com/341/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/spmatt.wordpress.com/341/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/spmatt.wordpress.com/341/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spmatt.wordpress.com/341/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spmatt.wordpress.com/341/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spmatt.wordpress.com/341/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spmatt.wordpress.com/341/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spmatt.wordpress.com/341/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spmatt.wordpress.com/341/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=341&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://spmatt.wordpress.com/2012/02/06/custom-error-pages-in-sharepoint/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0d26e27d7507158fb5a229f002b3c314?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">menezesm</media:title>
		</media:content>
	</item>
		<item>
		<title>Error Logging in SharePoint</title>
		<link>http://spmatt.wordpress.com/2012/02/06/error-logging-in-sharepoint/</link>
		<comments>http://spmatt.wordpress.com/2012/02/06/error-logging-in-sharepoint/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 11:28:16 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Best practice]]></category>
		<category><![CDATA[Error Handling]]></category>
		<category><![CDATA[Codeplex]]></category>
		<category><![CDATA[CRM]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Email]]></category>
		<category><![CDATA[Enterprise Library]]></category>
		<category><![CDATA[Event Log]]></category>
		<category><![CDATA[Exception handling]]></category>
		<category><![CDATA[log4net]]></category>
		<category><![CDATA[PortalLog.LogString]]></category>
		<category><![CDATA[Sandboxed]]></category>
		<category><![CDATA[SharePoint 2007]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[SharePoint 365]]></category>
		<category><![CDATA[SharePoint Guidance Library]]></category>
		<category><![CDATA[SharePoint lists]]></category>
		<category><![CDATA[SharePoint ULS]]></category>
		<category><![CDATA[SPDiagnosticsService]]></category>
		<category><![CDATA[SPUtility.SendEmail]]></category>

		<guid isPermaLink="false">http://spmatt.wordpress.com/?p=330</guid>
		<description><![CDATA[FRUB938D3AJG As identified in my post Exception Handling in SharePoint it is important to determine the most appropriate form of logging for your situation and use it. My original intention for this post was to create more of a how-to for each possibility but in my research discovered that the number of quality resources on [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=330&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><span style="color:#ffffff;font-size:6px;">FRUB938D3AJG</span><br />
As identified in my post <a title="Exception Handling in SharePoint" href="http://spmatt.wordpress.com/2012/02/01/exception-handling-in-sharepoint/" target="_blank">Exception Handling in SharePoint</a> it is important to determine the most appropriate form of logging for your situation and use it. My original intention for this post was to create more of a how-to for each possibility but in my research discovered that the number of quality resources on this topic is extensive. This being the case, the focus for this post will instead discuss the different options available, point out some of the best resources I found on the subject if appropriate and summarise what I think is the best overall option to use in most instances.</p>
<p>The forms of logging I identified and will discuss below include logging to the SharePoint ULS, to the Event Log, via email, a database, CRM or a SharePoint list.</p>
<p><strong>SharePoint ULS</strong></p>
<p>Logging to the SharePoint ULS is arguably the most logical option when it comes to logging exceptions in your custom code. It is most appropriate for developers or support staff if they have access to the files and are able to monitor them consistently. Ideally, the ULS should be monitored regardless to ensure the ongoing health of the site but under some scenarios the files may not be made available and hence logging here would go unnoticed &#8211; in this situation an alternative logging option should be considered.</p>
<p>The difficulty with logging to the ULS surrounds the different options available depending on what version of SharePoint you&#8217;re using. SharePoint 2010 makes this task a breeze with its <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spdiagnosticsservice.aspx" target="_blank">SPDiagnosticsService</a> functionality which is available in both the free (SPF) and licenced (SPS) versions of the product. The best articles I found on this topic were Tobias Zimmergren&#8217;s article on <a href="http://www.zimmergren.net/technical/sp-2010-developing-for-performance-part-4-logging" target="_blank">SP 2010: Developing for performance Part 4 – Logging</a> and Waldek Mastykarz&#8217;s extension of this in <a href="http://blog.mastykarz.nl/logging-uls-sharepoint-2010/" target="_blank">Logging to ULS in SharePoint 2010</a>.</p>
<p>The task is more difficult in SharePoint 2007. MOSS at least provides some functionality to write to the logs via Microsoft.Office.Server.Diagnostics.PortalLog.LogString (briefly documented in Clayton James&#8217; post <a href="http://claytonj.wordpress.com/2007/10/29/log-errors-to-sharepoint-log-file/" target="_blank">Log errors to SharePoint Log file</a>) but that is not available in WSS. There are some examples listed including Eli Robillard&#8217;s <a href="http://weblogs.asp.net/erobillard/archive/2008/07/31/sharepoint-trace-logs-and-the-unified-logging-service-uls.aspx" target="_blank">SharePoint Trace Logs and the Unified Logging Service (ULS)</a> however a number of links in that article are broken now. Gunnar Peipman&#8217;s <a href="http://weblogs.asp.net/gunnarpeipman/archive/2009/02/25/sharepoint-writing-messages-to-uls-unified-logging-system.aspx" target="_blank">SharePoint: Writing messages to ULS (Unified Logging System)</a> is another quality post however a reasonably complicated solution. There is also a Codeplex <a href="http://splogginglibrary.codeplex.com/" target="_blank">SharePoint Logging Library</a> by Ayman El-Hattab that may be able to be harnessed. As you&#8217;re probably appreciating now, logging to the ULS in WSS was not made easy.</p>
<p>There is however one saving grace for any version of SharePoint when it comes to logging to the ULS and that is the<br />
patterns &amp; practices <a href="http://spg.codeplex.com/" target="_blank">SharePoint Guidance Library</a> which i&#8217;ll discuss in more detail later.</p>
<p>The other possible qualm about logging to the SharePoint ULS is the difficulty in reading them. This is made easier in SharePoint 2010 by Microsoft&#8217;s <a href="http://archive.msdn.microsoft.com/ULSViewer/" target="_blank">ULS Viewer</a> or Stefan Gordon&#8217;s <a href="http://ulsviewer.codeplex.com/" target="_blank">SharePoint ULS Log Viewer</a> on Codeplex. Tools also exist for SharePoint 2007 including Florin Muntean&#8217;s <a href="http://sptraceview.codeplex.com/" target="_blank">SPTraceView</a> and Stuart Starrs&#8217; <a href="http://wssmosslogfilereader.codeplex.com/" target="_blank">WSS / MOSS Log File Reader</a> &#8211; both on Codeplex.</p>
<p><strong>Event Logs</strong></p>
<p>The other logical place to log exceptions is the Event Log. It is most suitable for system administrators or developers and support staff who have access to the server (hopefully this isn&#8217;t the case in production environments!). Much like the ULS it is reliant on the logs being monitored on a consistent basis and also on the system administrators reporting any issues back to the development or support teams.</p>
<p>Again SharePoint 2010 steps up to the plate with it&#8217;s SPDiagnosticsService class, also documented in Tobias&#8217; post outlined previously. SharePoint 2007 has to rely on core functionality in the System.Diagnostics namespace called EventLog.WriteEntry briefly documented in SharePoint King&#8217;s <a href="http://sharepointking.blogspot.com.au/2009/01/event-log-access-denied-sharepoint-net.html" target="_blank">Event Log Access Denied : Sharepoint /.NET</a>. As that article points out (to a degree), you need to ensure that access to write to the Event Log is granted to the relevant accounts.</p>
<p>One thing to point out here is, like the ULS logs above, the patterns &amp; practices SharePoint Guidance Library provides the ability to write to the Event Logs as well.</p>
<p><strong>Email</strong></p>
<p>Logging exceptions via email is an interesting one. In my opinion, email should only be used hand in hand with another logging option primarily for the purposes of notification. It is mostly required if the primary log store isn&#8217;t checked on a regular basis. There are 2 options available here; either use the in-built SharePoint emailing capability of SPUtility.SendEmail or using .NETs SmtpClient class &#8211; both documented in Mohd Sukri At&#8217;s post <a href="http://sharepointmalaya.blogspot.com.au/2011/04/send-email-in-sharepoint-via-net.html" target="_blank">Send Email in SharePoint via .NET SmtpClient Class and SharePoint SPUtility Class</a>.</p>
<p><strong>Database</strong></p>
<p>I&#8217;m not a huge advocate of using a database logging mechanism in a SharePoint context however it may be appropriate if there is a need to aggregate exceptions from multiple (and non-SharePoint) applications across an organisation. If database logging is desired then a library should be used such as <a href="http://logging.apache.org/log4net/" target="_blank">log4net</a> or the <a href="http://msdn.microsoft.com/en-us/library/ff648951.aspx" target="_blank">Enterprise Library Application Block</a>. There is a good article on <a href="http://imason.com/imason_Blogs/b/suleman_ibrahim/archive/2009/05/25/configuring-enterprise-library-4-0-for-exception-handling-and-logging.aspx" target="_blank">Configuring Enterprise Library 4.0 for Exception handling and Logging</a> by Suleman Ibrahim and some potential issues in Cory Roth&#8217;s <a href="http://www.dotnetmafia.com/blogs/dotnettipoftheday/archive/2007/09/05/how-to-get-enterprise-library-working-with-sharepoint.aspx" target="_blank">How to get Enterprise Library working with SharePoint</a> if you choose to go down this path. While on the topic of the Enterprise Library it may be worth pointing out that it is also possible to use it to log to the ULS logs demonstrated in Madhur Ahuja&#8217;s post <a href="http://www.codeproject.com/Articles/23530/Implementation-of-Logging-and-Instrumentation-Appl" target="_blank">Implementation of Logging and Instrumentation Application Blocks in MOSS 2007</a>.</p>
<p><strong>CRM</strong></p>
<p>My opinions on logging to CRM are similar to that of a database. The most appropriate reason for this however would be in a tightly integrated SharePoint and CRM application where interaction mostly takes place on the CRM side. I&#8217;ve actually been involved in projects like this where logging exceptions to CRM was deemed more appropriate than SharePoint as it would aggregate issues from both systems and be more closely monitored. At the risk of exposing my lack of CRM knowledge and in lieu of providing a link to an example, the premise would be to have a log entity in CRM and have a library code-side which creates a dynamic entity of that type, populates the relevant fields, creates a TargetCreateDynamic object binding the dynamic entity and a request binding the target, then executing the request via the CrmService. Sounds easy, is relatively easy, but will leave this to the CRM experts.</p>
<p><strong>SharePoint list</strong></p>
<p>I find it interesting that I have yet to see an implementation of exception logging to a SharePoint list. It&#8217;s a highly visible and accessible location to monitor issues within a SharePoint site. Another plus to logging to a SharePoint list is that it is sandbox-friendly and hence a viable option for SharePoint 365. Timmy Gilissen identifies this in his post <a href="http://www.moss2007.be/blogs/timmy/archive/2011/12/26/sharepoint-365-logging.aspx" target="_blank">SharePoint 365 logging</a> and the example is not restricted to just sandboxed solutions (note that if you&#8217;re going to take the code from that page you may also want to read Rob Garrett&#8217;s post <a href="http://blog.robgarrett.com/2009/02/25/efficient-way-to-add-a-new-item-to-a-sharepoint-list/" target="_blank">Efficient way to add a new item to a SharePoint list</a>).</p>
<p>On the topic of sandboxed solutions it is something worth pointing out in terms of the other logging mechanisms. It essentially makes them far more difficult to implement, for instance logging to the ULS or Event Logs in a sandbox requires a full-trust proxy due to the Microsoft.SharePoint.Administration namespace not being available in a sandboxed environment. The patterns &amp; practices SharePoint Guidance Library however includes a full trust proxy which enables the use of it&#8217;s SharePoint Logger within the sandbox.</p>
<p><strong>The patterns &amp; practices SharePoint Guidance Library</strong></p>
<p>I&#8217;ve been a little coy throughout this post regarding the patterns &amp; practices <a href="http://spg.codeplex.com/" target="_blank">SharePoint Guidance Library</a> solely for the reason that I think it&#8217;s worthy of it&#8217;s own section in this post. The library is amazing on a number of fronts and this is no different when it comes to Logging. In fact, it is my most recommended option for logging exceptions assuming logging to the ULS and/or the Event Logs is suitable for your circumstances. I highly recommend you visit the page and read what the library offers both from a SharePoint 2007 and 2010 perspective. Another post worth reading in regards to the library is Alex Angas&#8217; <a href="http://www.alexangas.com/blog/2011/09/intro-to-sharepoint-2010-patterns-practices-logging/" target="_blank">Intro to SharePoint 2010 patterns &amp; practices – Logging</a>.</p>
<p>As you can see there are a number of options when it comes to logging exceptions in SharePoint and depending on your circumstances, different ones may be the most suitable. The important part is that you use some form of exception logging and do it in a best practice manner.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spmatt.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spmatt.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spmatt.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spmatt.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/spmatt.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/spmatt.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/spmatt.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/spmatt.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spmatt.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spmatt.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spmatt.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spmatt.wordpress.com/330/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spmatt.wordpress.com/330/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spmatt.wordpress.com/330/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=330&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://spmatt.wordpress.com/2012/02/06/error-logging-in-sharepoint/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0d26e27d7507158fb5a229f002b3c314?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">menezesm</media:title>
		</media:content>
	</item>
		<item>
		<title>Exception Handling in SharePoint</title>
		<link>http://spmatt.wordpress.com/2012/02/01/exception-handling-in-sharepoint/</link>
		<comments>http://spmatt.wordpress.com/2012/02/01/exception-handling-in-sharepoint/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 13:40:36 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Best practice]]></category>
		<category><![CDATA[Error Handling]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Enterprise Library]]></category>
		<category><![CDATA[Error page]]></category>
		<category><![CDATA[Exception handling]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[MSDN]]></category>
		<category><![CDATA[SharePoint 2007]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[SharePoint Guidance Library]]></category>

		<guid isPermaLink="false">http://spmatt.wordpress.com/?p=324</guid>
		<description><![CDATA[I feel like i&#8217;m going to be opening a can of worms with this one. I&#8217;ve given it a fair bit of thought over time and for this post specifically. I&#8217;ve read a lot of guidance around the topic. For the most part, best practice exception handling is reasonably well covered in the ASP.NET space [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=324&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I feel like i&#8217;m going to be opening a can of worms with this one. I&#8217;ve given it a fair bit of thought over time and for this post specifically. I&#8217;ve read a lot of guidance around the topic. For the most part, best practice exception handling is reasonably well covered in the ASP.NET space but starts to become a bit murky when you delve into the SharePoint sphere. Some of my own personal preferences clash slightly with other advice that exists and like anything to do with SharePoint, often circumstances may dictate the path you need to take.</p>
<p>As such, I was slightly hesitant to write this post. The reason I have is because exception handling seems to be one of the most poorly implemented (or at least forgotten/ignored) tasks in SharePoint development. It&#8217;s also an important task when you factor in user experience, performance and ability to monitor your deployed applications. I&#8217;ve seen some shockers; from potential exception-throwing lines of code going unmanaged in web parts which could  bring down the entire page, to swallowed exceptions that you&#8217;ll never even know are there. I&#8217;ve seen catch (Exception ex) blocks scattered everywhere and try-catch blocks used to control execution flow or used in place of pre-exception checks.</p>
<p>There is a lot of good information out there. MSDN has version-specific editions regarding <a href="http://msdn.microsoft.com/en-us/library/5b2yeyab%28v=vs.85%29.aspx" target="_blank">Handling and Throwing Exceptions</a>. There are some good articles written for .NET in general including Scott Mitchell&#8217;s <a href="http://www.4guysfromrolla.com/articles/081209-1.aspx" target="_blank">Exception Handling Advice for ASP.NET Web Applications</a>, Daniel Turini&#8217;s <a href="http://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET" target="_blank">Exception Handling Best Practices in .NET</a> and Russell Allen&#8217;s <a href="http://russellallen.info/post/2011/03/11/C-net-Exception-Handling-Best-Practice-As-Easy-as-1-2-3.aspx" target="_blank">C# .net Exception Handling Best Practice &#8211; As Easy as 1, 2, 3?</a>.</p>
<p>The general consensus tends to boil down to a few rules. Generally, the base exception classes (Exception, ApplicationException) shouldn&#8217;t be caught or thrown. Exceptions should only be handled if you can add value to how they&#8217;re processed, otherwise they should be allowed to bubble up the chain. Finally, exceptions should be reported so corrective action can be taken if nececssary &#8211; preferably using an existing framework such as the <a href="http://msdn.microsoft.com/en-us/library/ff649140.aspx" target="_blank">Exception Management Application Block</a>.</p>
<p>The question is how these rules and surrounding information can be tweaked to be suitable for SharePoint projects. I&#8217;ll structure my comments around this by identifying some general rules and outlining where they&#8217;re applicable in a SharePoint context.</p>
<p><strong>1. Never, ever swallow an exception.</strong></p>
<p>Pretty obvious, but the following is a definite no-no.</p>
<p><pre class="brush: csharp;">
try
{
    // code
}
catch { }
</pre></p>
<p>At the very least the error should be reported using error logging functionality, if not handled sufficiently. I have seen an instance whereby the exception was expected and superfluous to report &#8211; I wish I could find it now or even remember why to explain &#8211; but if this unlikely case ever occurs it should be properly documented in the code.</p>
<p><strong>2. If you&#8217;re going to throw an exception, use throw;</strong></p>
<p>A common piece of code I see goes something along the lines of:</p>
<p><pre class="brush: csharp;">
try
{
    // code
}
catch (Exception ex)
{
    throw ex;
}
</pre></p>
<p>This is actually quite bad practice. The reasons why were highlighted in some of the links I mentioned earlier, but essentially by doing this you clear the stack trace which is very useful when debugging the exception down the track. You&#8217;re better off using the following:</p>
<p><pre class="brush: csharp;">
try
{
    // code
}
catch
{
    throw;
}
</pre></p>
<p><strong>3. Wherever possible handle the specific exception.</strong></p>
<p>The most common form of exception handling I see is something along the lines of:</p>
<p><pre class="brush: csharp;">
try
{
    // code
}
catch (Exception ex)
{
    // handle exception
}
</pre></p>
<p>The problem is this goes against the general philosophy behind exception handling. Lee Dumond&#8217;s post <a href="http://leedumond.com/blog/friends-dont-let-friends-catch-exception/" target="_blank">Friends Don&#8217;t Let Friends catch (Exception)</a> explains this nicely.</p>
<p>If you know the object model, or at least know where to go to find the information, you&#8217;ll be able to find out which exception/s you should be handling. Take the <a href="http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spweb.getlist.aspx" target="_blank">GetList function in SPWeb</a>. That page identifies clearly the exceptions that may be thrown so you should handle them appropriately.</p>
<p><pre class="brush: csharp;">
try
{
    spList = spWeb.GetList(&quot;/Path/List&quot;);
}
catch (FileNotFoundException ex)
{
    // handle exception
}
catch (ArgumentException ex)
{
    // handle exception
}
</pre></p>
<p>An important point to note is that your catch blocks must go in order of most specific to least specific.</p>
<p><strong>4. If you can check for a condition before it throws an exception, do so.</strong></p>
<p>A common block of code you may see is something along the lines of:</p>
<p><pre class="brush: csharp;">
try
{
    myString = listItem[&quot;MyField&quot;].ToString();
}
catch (Exception ex)
{
    // handle exception
}
</pre></p>
<p>Sure, if MyField was never populated in the list item it would throw an exception when you attempt to convert it to a string, but why not check to see if it was populated in the first place?</p>
<p><pre class="brush: csharp;">
if (String.IsNullOrEmpty(listItem[&quot;MyField&quot;]))
{
    myString = listItem[&quot;MyField&quot;].ToString();
}
</pre></p>
<p><strong>5. You got to know when to hold &#8216;em, know when to fold &#8216;em.</strong></p>
<p>Ok I may have stretched the poetic licence a bit there. What i&#8217;m talking about somewhat contradicts the rule regarding letting exceptions bubble up the chain to be handled at the application level. Consider you have a web part on a page, relatively non-critical to the page or application as a whole, a weather web part for instance. Do you really want the whole page to error out because it generated an exception? I wouldn&#8217;t begrudge you a global catch (Exception) in that instance.</p>
<p>On the flip side, imagine an event receiver that is processing a list item that is currently being added. The processing is necessary to complete the step of adding the list item, but the exception is caught, reported and held. The list item will exist, but the process did not complete, and depending on the level of reporting the user may never have a clue.</p>
<p>The point is you really need to use your best judgement when it comes to error handling in SharePoint. It&#8217;s hard to state a catch-all rule that can be applied across the board, often it will depend on context.</p>
<p><strong>6. Determine the most appropriate form of logging and use it.</strong></p>
<p>I would have preferred to state how errors should be logged in a SharePoint application much more definitively than this. The most important takeaway is to ensure that the errors are logged. The 2 most logical locations to log the errors would be the ULS or Event Log, however this may not always be appropriate. If these locations aren&#8217;t regularly monitored or accessible by the people who need to know about the errors, then it is essentially no better than swallowing the errors in the first place. Email, CRM, a database or even a SharePoint list are other potential locations that could be more accessible. Logging to a file on the file system makes little sense seeing if that is an accessible option you could just use the ULS. I write on this topic in more detail and explain my preference for logging to the ULS/Event Log using the SharePoint Guidance Library in my post <a title="Error Logging in SharePoint" href="http://spmatt.wordpress.com/2012/02/06/error-logging-in-sharepoint/" target="_blank">Error Logging in SharePoint</a>.</p>
<p><strong>7. Use a custom error page.</strong></p>
<p>Nothing looks worse on a public facing internet site or even an intranet application than when you get the &#8216;yellow screen of death&#8217;. Wherever possible you should display a user friendly message rather than an ugly generic error page. I explain the options available around this topic in my post <a title="Custom Error Pages in SharePoint" href="http://spmatt.wordpress.com/2012/02/06/custom-error-pages-in-sharepoint/" target="_blank">Custom Error Pages in SharePoint</a>.</p>
<p>That about covers it. Just thinking about this post made my head spin around in circles so it&#8217;s no wonder why a vast number of developers take the shortcut route and use global try-catch blocks with generic Exceptions. Hopefully this post sheds some light however on why doing so is a bad idea and that there are better options available to be leveraged. If anyone wishes to comment on the topic I&#8217;d be very interested in hearing opposing views and ideas &#8211; I&#8217;d still consider myself learning the best practice approach to exception handling at this point.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spmatt.wordpress.com/324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spmatt.wordpress.com/324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spmatt.wordpress.com/324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spmatt.wordpress.com/324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/spmatt.wordpress.com/324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/spmatt.wordpress.com/324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/spmatt.wordpress.com/324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/spmatt.wordpress.com/324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spmatt.wordpress.com/324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spmatt.wordpress.com/324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spmatt.wordpress.com/324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spmatt.wordpress.com/324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spmatt.wordpress.com/324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spmatt.wordpress.com/324/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=324&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://spmatt.wordpress.com/2012/02/01/exception-handling-in-sharepoint/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0d26e27d7507158fb5a229f002b3c314?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">menezesm</media:title>
		</media:content>
	</item>
		<item>
		<title>Content Security in SharePoint</title>
		<link>http://spmatt.wordpress.com/2012/01/24/security-for-sharepoint/</link>
		<comments>http://spmatt.wordpress.com/2012/01/24/security-for-sharepoint/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 13:04:47 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Best practice]]></category>
		<category><![CDATA[AD]]></category>
		<category><![CDATA[Permissions]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Security Groups]]></category>
		<category><![CDATA[SharePoint 2007]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[SharePoint Groups]]></category>
		<category><![CDATA[TechNet]]></category>

		<guid isPermaLink="false">http://spmatt.wordpress.com/?p=320</guid>
		<description><![CDATA[Security is a polarising topic in the SharePoint community. It seems that everyone has a slight variation to what would be considered a best practice approach to implementing security across a site. There are so many conditions that determine which approach would be the best to use that it&#8217;s difficult to outline a best practice [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=320&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Security is a polarising topic in the SharePoint community. It seems that everyone has a slight variation to what would be considered a best practice approach to implementing security across a site. There are so many conditions that determine which approach would be the best to use that it&#8217;s difficult to outline a best practice approach in the first place. This article, while filed under the Best Practices category, should only be considered my personal best practice approach to implementing a security model across a SharePoint 2007 or 2010 site.</p>
<p>If you have the time, there is a tonne of background reading to get through on the subject. Technet includes pages dedicated to both versions of SharePoint including <a href="http://technet.microsoft.com/en-us/library/cc263215(office.12).aspx" target="_blank">Security and protection for Office SharePoint Server 2007 </a> and <a href="http://technet.microsoft.com/en-us/library/cc263215.aspx" target="_blank">Security and protection for SharePoint Server 2010</a>. In this article i&#8217;m focussing on securing site content which is more specifically targeted in the <a href="http://technet.microsoft.com/en-us/library/cc262619(office.12).aspx" target="_blank">Downloadable book: Security for Office SharePoint Server 2007</a> and <a href="http://technet.microsoft.com/en-us/library/cc262939.aspx" target="_blank">Security planning for sites and content (SharePoint Server 2010)</a>.</p>
<p>I&#8217;ve always favoured a simplistic approach to site security. I used to advocate maintaining security groups in active directory, assigning those security groups to SharePoint groups and then assigning the relevant permissions to those groups across the site where necessary. The premise behind this methodology was to have one source of truth (AD) which was often maintained more religiously when staff joined or left the organisation. It was to allow a &#8216;set and forget&#8217; approach to security within SharePoint &#8211; the security across the site would ideally never change, only the staff members assigned to the security groups. In reality, this approach is far too idealistic.</p>
<p>I&#8217;ve since realised that a lot of the time the security methodology will be largely influenced by the context of the organisation. Security groups may make a lot of sense throughout the organisation, but they may not map ideally to the SharePoint site. Some organisations may not and will not assign email addresses to security groups which renders them a tad ineffectual when it comes to workflow notifications. Some will refuse to create SharePoint-specific security groups in AD altogether. AD maintenance may be carried out solely by an over-worked IT department at a low priority, so getting a particular user added to a group may take longer than necessary. Or you may want to display the members of a given site using the Site Users web part and notice you end up with the security group listed rather than the individuals (there is a way around this in SP2010 however, check out Robi Voncina&#8217;s <a href="http://sp2010adgroupmembers.codeplex.com/" target="_blank">Display members of AD group in SharePoint 2010</a>  solution on CodePlex). You get the idea &#8211; there&#8217;s not necessarily a one size fits all approach that will work in every scenario.</p>
<p>There are however a few golden rules which can be followed with a few potential caveats to implement a solid security methodology across a site.</p>
<p><strong>1. Plan your security</strong></p>
<p>One of the biggest issues with security in SharePoint is it seems to be done ad-hoc initially and grows wildly once the site is live. Security is granted on an as-needed basis with little fore-thought which generally results in a sprawling mess which is hard to track and maintain. Initially the security implementation should be well thought out and planned &#8211; identify the levels of access required, the users which will need those levels of access and identify the logical groupings of those users. When security needs to be modified, assess how the change fits in to the initial model and implement the most logical option to affect the change.</p>
<p><strong>2. Document your security</strong></p>
<p>This is particularly important in terms of tracking the customisations to security &#8211; preferably everything should be documented. It allows you to have an over-arching view of what is in place &#8211; determine what users have access to which portions of the site &#8211; something which is otherwise difficult to ascertain. At the very least where ever inheritance has been broken should be clearly identified, especially at more granular levels such as list or item level security (which preferably should be avoided).</p>
<p><strong>3. Inherit permissions where ever possible</strong></p>
<p>Aside from making the job far easier for point 2, it really keeps the security structure a lot more clear and clean to identify which users have certain levels of access across the site. Breaking inheritance at the sub-site level is not too much of a concern but at the list and item level should be avoided if possible. SharePoint helps out in this regard seeing inheriting permissions is the default.</p>
<p><strong>4. Always use SharePoint groups when applying security across a site</strong></p>
<p>You may not be able to only use AD security groups as identified above, but you should always use the SharePoint groups. Permissions should only be assigned to these groups rather than individuals &#8211; you are able to add both AD users and security groups to the SharePoint groups. It keeps everything a bit neater and consistent across the site rather than having some SharePoint groups, some security groups and some individuals. It&#8217;s worth preventing group-sprawl if possible &#8211; maintaining as few logically seperated groups as possible will ensure ease of maintenance.</p>
<p><strong>5. Use AD security groups where appropriate</strong></p>
<p>I still prefer using security groups to keep the SharePoint security structure clean and concise &#8211; but only when it makes sense to do so. Leverage the Domain Users group to provide global read access across a site for instance.</p>
<p><strong>6. Use the principle of least-privilege</strong></p>
<p>This is just good practice in all forms of IT. No user should ever have access to functionality that they don&#8217;t need. I&#8217;ve seen plenty of implementations which give site ownership to a wide range of users so they can edit a particular page of a sub-site, then wonder where a certain list item disappeared to.</p>
<p>The goal for any security implementation should be simplicity, understandability, maintenance efficiency and most importantly effectiveness in securing the content. The best way to get there is to plan and document the approach, for the time invested in the beginning will save a lot of headaches moving forward.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spmatt.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spmatt.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spmatt.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spmatt.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/spmatt.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/spmatt.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/spmatt.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/spmatt.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spmatt.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spmatt.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spmatt.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spmatt.wordpress.com/320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spmatt.wordpress.com/320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spmatt.wordpress.com/320/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=320&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://spmatt.wordpress.com/2012/01/24/security-for-sharepoint/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0d26e27d7507158fb5a229f002b3c314?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">menezesm</media:title>
		</media:content>
	</item>
		<item>
		<title>301 vs 302 Redirects in SharePoint</title>
		<link>http://spmatt.wordpress.com/2012/01/18/301-vs-302-redirects-in-sharepoint/</link>
		<comments>http://spmatt.wordpress.com/2012/01/18/301-vs-302-redirects-in-sharepoint/#comments</comments>
		<pubDate>Wed, 18 Jan 2012 14:51:14 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[SEO]]></category>
		<category><![CDATA[.NET 4.0]]></category>
		<category><![CDATA[301 redirect]]></category>
		<category><![CDATA[302 redirect]]></category>
		<category><![CDATA[HttpModule]]></category>
		<category><![CDATA[IIS6]]></category>
		<category><![CDATA[IIS7]]></category>
		<category><![CDATA[Redirect Page layout]]></category>
		<category><![CDATA[SharePoint 2007]]></category>
		<category><![CDATA[SharePoint 2010]]></category>

		<guid isPermaLink="false">http://spmatt.wordpress.com/?p=318</guid>
		<description><![CDATA[Recently I was faced with the request to implement some permanent 301 redirects for a publically facing SharePoint website. It was more of an investigative request rather than a call for action and as yet there has been no resolution, so rather than presenting a solution to the issue, this post will serve more as [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=318&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Recently I was faced with the request to implement some permanent 301 redirects for a publically facing SharePoint website. It was more of an investigative request rather than a call for action and as yet there has been no resolution, so rather than presenting a solution to the issue, this post will serve more as a discussion around it.</p>
<p>Rather than focus the article on the differences between a 301 and 302 redirect I&#8217;d rather point you in the direction of some existing resources that explain the details better than I could myself. The article <a href="http://www.stepforth.com/blog/2008/redirects-permanent-301-vs-temporary-302/" target="_blank">Redirects: Permanent 301 vs. Temporary 302</a> does a good job in doing so.</p>
<p>The main concern around the 301 vs 302 redirect in SharePoint is 2-fold. Predominantly, there is a lot of information floating around the net in regards to the SEO implications of the 2 redirect techniques. To cut a long story short, 301 redirects are generally preferred from an SEO standpoint to 302 redirects. The problem being, SharePoint uses 302 redirects for its &#8216;Redirect Page&#8217; layout. You can get a more in depth explanation of this in Jeff Cate&#8217;s post <a href="http://sharepointsolutions.blogspot.com/2009/10/moss-for-internet-and-301-redirects.html" target="_blank">MOSS for Internet and 301 Redirects</a>.</p>
<p>Those wanting to implement 301 redirects rather than the default 302 redirects are left with 2 main options. Firstly, IIS can be used to re-write the URLS (which serves as a 301 redirect). This can be done natively via an <a href="http://learn.iis.net/page.aspx/460/using-the-url-rewrite-module/" target="_blank">add-on in IIS7</a> and with a <a href="http://www.micronovae.com/ModRewrite/ModRewrite.html" target="_blank">3rd party add-on in IIS6</a>. Secondly, the option exists to write a custom HttpModule to perform the 301 redirect as per Waldek Mastykarz&#8217;s post on <a href="http://blog.mastykarz.nl/sharepoint-2007-redirect-solved-using-301-instead-of-302-redirects/" target="_blank">Using 301 instead of 302 redirects</a>. Waldek&#8217;s post is focussing more on another MOSS 302 redirect phenomenon rather than the Redirect Page layout but the concepts are still applicable.</p>
<p>I have a bit of an issue with both solutions. I should be attracted to the custom code option being a developer by trade, but from a complexity and maintainability point of view it doesn&#8217;t really appeal to me. It may be possible to architect a solution whereby the redirects are maintained in a SharePoint list improving the functions extensibility, and that&#8217;s probably the angle I would have looked into had time allowed, but it still seems like a bit of an overkill considering the IIS solution existed. The problem with the IIS solution however is (aside from it not being native in IIS6 which was being used in my instance) that maintenance would need to be conducted on the server by IT rather than the site owners.</p>
<p>Jeff posed the question in his post &#8216;Will it be in SharePoint 2010?&#8217; &#8211; unfortunately, the answer is no. Waldek points out in a follow up post <a href="http://blog.mastykarz.nl/sharepoint-redirects-revisited-301-302/" target="_blank">Using 301 instead of 302 (without code!)</a> that they can be handled in IIS7 (required for SharePoint 2010) natively, which is true and how Jeremy Thake at NothingButSharePoint implemented their <a href="https://www.nothingbutsharepoint.com/sites/itpro/Articles/Pages/301Redirects.aspx" target="_blank">301 Redirects in IIS7.5</a>, but doesn&#8217;t solve the issue of giving access to site owners to perform the function. You really don&#8217;t want this administrative overhead placed on IT.</p>
<p>To be honest in my opinion we seem to be left with no ideal option. It would be nice (but still not ideal) if 301 redirects could be set and maintained via Central Administration (at least ensuring server access would not be necessary). It would be even better if they could be set and maintained in the Site Settings of the relevant site. Better still, an option on the redirect page to indicate whether it should be a 301 or 302 redirect would be perfect.</p>
<p>For now we&#8217;re left with the options presented. Having a personal interest in SEO myself it would be nice to see future versions of SharePoint tailored towards this goal in anyway possible, and making it easier to perform 301 redirects out of the box would be one way of getting there. Assuming SharePoint vNext is based on .NET 4.0 we should be a lot more likely to have this feature considering the <a href="http://www.dotnetmafia.com/blogs/dotnettipoftheday/archive/2009/08/28/301-redirects-in-net-4-0.aspx" target="_blank">301 Redirects in .NET 4.0</a>.</p>
<p>If it so happens that this piece of work is given the green light i&#8217;ll post a follow up on how the solution was achieved.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spmatt.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spmatt.wordpress.com/318/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spmatt.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spmatt.wordpress.com/318/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/spmatt.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/spmatt.wordpress.com/318/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/spmatt.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/spmatt.wordpress.com/318/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spmatt.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spmatt.wordpress.com/318/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spmatt.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spmatt.wordpress.com/318/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spmatt.wordpress.com/318/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spmatt.wordpress.com/318/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=318&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://spmatt.wordpress.com/2012/01/18/301-vs-302-redirects-in-sharepoint/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0d26e27d7507158fb5a229f002b3c314?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">menezesm</media:title>
		</media:content>
	</item>
		<item>
		<title>Application Settings in SharePoint</title>
		<link>http://spmatt.wordpress.com/2012/01/16/application-settings-in-sharepoint/</link>
		<comments>http://spmatt.wordpress.com/2012/01/16/application-settings-in-sharepoint/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 11:33:03 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Best practice]]></category>
		<category><![CDATA[Application settings]]></category>
		<category><![CDATA[Codeplex]]></category>
		<category><![CDATA[Hierarchical Object Store]]></category>
		<category><![CDATA[Property bags]]></category>
		<category><![CDATA[SharePoint 2007]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[SharePoint Guidance Library]]></category>
		<category><![CDATA[SharePoint lists]]></category>
		<category><![CDATA[SPPersistedObject]]></category>
		<category><![CDATA[SPWebConfigModification]]></category>
		<category><![CDATA[Variable configuration]]></category>
		<category><![CDATA[web.config]]></category>
		<category><![CDATA[WebPart properties]]></category>

		<guid isPermaLink="false">http://spmatt.wordpress.com/?p=310</guid>
		<description><![CDATA[One of the most commonly neglected features in SharePoint I find across a number of different projects is the manner in which application settings are managed. Far too often it is left to manually modifying the &#60;AppSettings&#62; section of the web.config file for the relevant web application. Perhaps this is due to legacy behaviour of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=310&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One of the most commonly neglected features in SharePoint I find across a number of different projects is the manner in which application settings are managed. Far too often it is left to manually modifying the &lt;AppSettings&gt; section of the web.config file for the relevant web application. Perhaps this is due to legacy behaviour of ASP.NET developers moving into the SharePoint sphere, perhaps its due to environments being small and the risks of manually modifying the file not being exposed. It may be due to organisational process or procedure, or (most likely) it may be because on face value it appears to be the most simple, quick and easy option to maintain some configuration values.</p>
<p>It&#8217;s ironic that in projects laced with features and solutions to deploy resources &#8216;the right way&#8217; that configuration is overlooked and remains a manual process. Aside from wanting to avoid any manual modification of files directly on the server by principle, dangers exist in terms of ensuring the web.config files are the same on all web front end servers. Maintaining application settings this way also requires access to the web.config file (and hence server) itself which wouldn&#8217;t be considered best practice, and the act of changing a variable in the web.config directly would cause the application pool to refresh and cause the site to load slowly on the next hit.</p>
<p>I write this post with a tinge of regret &#8211; I too have been guilty on multiple occassions of maintaining the status quo and leaving (and even adding to) configuration values maintained manually in a web.config file. So not only should this post serve as a source of information regarding the best practice methods to maintain application settings, but it should also serve as a motivator to myself and others to practice what I/we preach on all future greenfield projects.</p>
<p>Anyone who has studied for or taken the application development exam (<a title="How I passed 70-576" href="http://spmatt.wordpress.com/2011/12/08/how-i-passed-70-576/" target="_blank">70-576</a>) would have noticed that 4 main options consistently get presented for application configuration: web.config, lists, property bags and the hierarchical object store. I&#8217;ll discuss each option briefly and provide some situations where the method would be appropriate.</p>
<p><strong>Web.config</strong></p>
<p>Now it may seem like i&#8217;m beginning to contradict myself here &#8211; I previously mentioned that manually maintaining application settings in the web.config was a BAD idea. It is. The beauty of SharePoint though is that it provides a mechanism to maintain application settings in the web.config file automatically via the SPWebConfigModification class. If you&#8217;re wanting to store them in the web.config, then a feature should be created which on activation uses the SPWebConfigModification class to modify the web.config for you. This ensures that the same values are written to the web.config files on all front-end web servers and even ensures they&#8217;re consistent amongst new servers added to the farm.</p>
<p>You&#8217;re likely to want to use this option if you just can&#8217;t pull yourself away from the web.config for variable configuration. At least its a safer method. There are some valid reasons however &#8211; it&#8217;s reasonably simple to incorporate this functionality and then easy to program with seeing you&#8217;re probably used to it already. It ensures values are consistent across all front-end web servers and are available and consistent across the entire web application. It&#8217;s also fairly useful for &#8216;set and forget&#8217; the values &#8211; if you&#8217;re unlikely to need to change them in the future, then you won&#8217;t run into the application pool refresh issue I mentioned previously and will get the performance benefits of the cached settings.</p>
<p>Before running off and using this method however, be warned that the web is littered with issues and problems with using SPWebConfigModification. I&#8217;d probably want to avoid making any &#8216;unnecessary&#8217; changes to the web.config especially for the purposes of setting configuration values considering there are other options available.</p>
<p><strong>SharePoint lists</strong></p>
<p>It almost seems too easy and obvious. SharePoint provides us with these useful things called lists. Most of us would be familiar with or have used database-driven variable configuration mechanisms before. Lists, on face value, are reasonably similar to database tables. Why don&#8217;t we use lists for variable configuration? It&#8217;s not actually that silly a proposition and is in fact one of the more reasonable options. One of the beauties of using lists is that you get all that SharePoint listy goodness. Versioning, security and an out-of-the-box UI for example. You&#8217;re likely already familiar with list-based programming, so that isn&#8217;t too much of an inconvenience.</p>
<p>Using SharePoint lists is definitely one of the preferred methods. It&#8217;s probably easier to outline some of the reasons why you may not want to use it; a site with lax security restrictions would probably be wise to avoid this method &#8211; you wouldn&#8217;t want any user being able to modify or delete configuration items or the list itself. If you wanted the application settings to be available to multiple site collections/web applications then you&#8217;d potentially end up duplicating the list values across these sites.</p>
<p>There&#8217;s another huge advantage to choosing this method. An MVP named Chris O&#8217;Brien has written a <a href="http://spconfigstore.codeplex.com" target="_blank">Config store framework</a> available on Codeplex which makes the option even more attractive and erases some of the drawbacks from choosing it. I&#8217;d definitely recommend reading a bit about it in his post <a href="http://www.sharepointnutsandbolts.com/2009/01/better-config-store-for-sharepoint.html" target="_blank">A better Config Store for SharePoint sites</a>.</p>
<p><strong>Property bags</strong></p>
<p>This option is perhaps a little less obvious but similarly powerful. A number of SharePoint objects contain a Properties property which stores a collection of key/value pairs. These obviously lend themselves towards being used for storing application settings.</p>
<p>This option is possibly the best one to harness when scope is an important consideration for configuration. It lends itself to being able to maintain numerous variables with different values on a per-scope basis (per web, per web application and so forth).</p>
<p>Like the SharePoint list option, this also benefits from addons which improve the usability and effectiveness of the option. The SharePoint Guidance Library provides the <a href="http://msdn.microsoft.com/en-us/library/ff798488.aspx" target="_blank">Application Setting Manager</a> which is an API to read and write application settings. Codeplex also has the <a href="http://pbs2010.codeplex.com/" target="_blank">SharePoint Property Bag Settings</a> project which provides a GUI in Central Administration to manage the settings.</p>
<p><strong>Hierarchical Object Store</strong></p>
<p>This is a farm-scoped store similar to a property bag. It requires custom code to create and is far more complex than the other options, however has the benefit of being able to store more complex types if that&#8217;s neccessary. Generally for the purpose of variable configuration though, in my opinion i&#8217;d go for one of the other options.</p>
<p>You&#8217;d possibly choose this option if you were looking for a global storage option for values or required complex values to be stored. If the values are simple key/value pairs however a farm-scoped property bag would probably be easier to use and do the trick.</p>
<p><strong>WebPart properties</strong></p>
<p>I know I said before there were 4 main options, but I wanted to briefly cover this one too. In the event that your custom web parts require configuration values specific to the web part then it will often make sense to include custom properties editable in the web part itself &#8211; they are then able to be set by modifying the settings of the web part.</p>
<p>My initial concept for this post was to include an array of advantages, disadvantages and code samples on each option to more completely highlight where each could be used and how they&#8217;re used, however during my research for this post came across an MSDN article written by David Mann titled <a href="http://msdn.microsoft.com/en-us/library/ee855123%28v=office.12%29.aspx#odcwss3_ManageCustConfigOptions_ASP.NET" target="_blank">Managing Custom Configuration Options for a SharePoint Application</a> &#8211; it essentially covers in reasonable detail those points and I would strongly recommend reading.</p>
<p>Overall I&#8217;d have to say I prefer the SharePoint list method the best. I&#8217;m somewhat surprised, I remember thinking a while ago that using lists for application settings would be a bit primitive and that surely the other options which have been provided (obviously for the purpose of variable configuration?) like SPWebConfigModification, SPPersistedObject and the Properties collections would be the best practice method to use. I guess sometimes the easy option actually is the best, and it&#8217;s sandbox-friendly to boot.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spmatt.wordpress.com/310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spmatt.wordpress.com/310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spmatt.wordpress.com/310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spmatt.wordpress.com/310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/spmatt.wordpress.com/310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/spmatt.wordpress.com/310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/spmatt.wordpress.com/310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/spmatt.wordpress.com/310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spmatt.wordpress.com/310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spmatt.wordpress.com/310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spmatt.wordpress.com/310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spmatt.wordpress.com/310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spmatt.wordpress.com/310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spmatt.wordpress.com/310/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=310&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://spmatt.wordpress.com/2012/01/16/application-settings-in-sharepoint/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0d26e27d7507158fb5a229f002b3c314?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">menezesm</media:title>
		</media:content>
	</item>
		<item>
		<title>Referencing resources in SharePoint: File system or content database?</title>
		<link>http://spmatt.wordpress.com/2011/12/26/referencing-resources-in-sharepoint-file-system-or-content-database/</link>
		<comments>http://spmatt.wordpress.com/2011/12/26/referencing-resources-in-sharepoint-file-system-or-content-database/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 03:59:54 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Best practice]]></category>
		<category><![CDATA[Backups]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Sandboxed]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SharePoint 2007]]></category>
		<category><![CDATA[SharePoint 2010]]></category>
		<category><![CDATA[Versioning]]></category>

		<guid isPermaLink="false">http://spmatt.wordpress.com/?p=307</guid>
		<description><![CDATA[Recently I’ve gone through a particular project and modified the solution structure and philosophy behind deploying resources for use within a number of public facing SharePoint sites. It’s a concept I actually hadn’t given too much thought to in the past – previously the majority of projects I’ve worked on or created have simply deployed [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=307&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Recently I’ve gone through a particular project and modified the solution structure and philosophy behind deploying resources for use within a number of public facing SharePoint sites. It’s a concept I actually hadn’t given too much thought to in the past – previously the majority of projects I’ve worked on or created have simply deployed all resources to the /_layouts/ folder and that was that. There are varying reasons why you would choose one method over the other and a discussion on these will form the basis for this post.</p>
<p>First though a bit of background on what brought this topic to the fore. The project I was analysing was a shared solution used for a large number of public facing websites (5+) hosted on the MOSS platform. All resources (CSS, Images, JavaScript, Flash) were deployed to the 12 hive within a folder structure suitable for identifying the site the resources belonged to. There were some smarts in the code which determined where to reference the resources in question.</p>
<p>The problem was 3-fold. Firstly, some site owners wanted the ability to make changes to the CSS or images themselves and didn’t have access to the servers to do so. Secondly, even if the changes were to be made by the development team they still needed to be done within the weekly change window to deploy the new solution. Finally, because the solution was shared between a number of sites and contained code as well as resources, any minor changes made to an image or CSS file would need to go through a complete and rigorous UAT and regression testing phase before they could be deployed.</p>
<p>The solution was obvious; the resources needed to be stored in the content database, and there are a number of benefits gained from storing resources for SharePoint in there.</p>
<ol>
<li>Site owners can be given the ability to make modifications to the images and CSS files if desired. Assuming they don’t have access to the server itself, and they shouldn’t, getting the files into the content database is the best way to enable this.</li>
<li>Immediate access. Assuming you’re deploying your resources to the file system via a solution package (and there should be no other option), you’ll require the solution to be deployed and in many cases this needs to be scheduled during a deployment window.</li>
<li>Versioning. Storing these files within the content database will be able to leverage the in-built versioning capabilities of SharePoint assuming they’re enabled. This could be countered with the fact that source control could be considered a form of file versioning.</li>
<li>Backups. This in my opinion is somewhat of a minor benefit as any decent disaster recovery plan would incorporate multiple forms of backup which would include source control and the SharePoint server (assuming virtual environments), however having the files in the content database enables the resources to be backed up both via SharePoint mechanisms and via backups of the SQL database.</li>
<li>Isolation. By storing the files within the content database you’re ensuring that any changes made are far less likely to affect other sites hosted on the same server. Storing the files within separate sub-folders on the file system mitigates this to an extent, but it’s less safe.</li>
<li>Sandboxed solutions. While not relevant to my own situation in MOSS, deploying the resources to the content database enables the solution to be deployed as a sandboxed solution, opening the door to deploying in a hosted environment.</li>
</ol>
<p>So why would anyone want to deploy their resources to the file system in the first place? I’m going to start by being cynical – developer laziness. Frankly, with tools such as WSPBuilder in 2007 or the build-in developer tools in 2010 it’s simply easier to place your resources into a mapped folder in your solution rather than creating the feature and module to deploy the files to the content database. There are however legitimate reasons why you may want to go down this path.</p>
<ol>
<li>Global access. It is possible that some of the resources you are deploying need to be used across sites for the purpose of common branding. By deploying to the file system all sites will have access to the files without having to duplicate content into the individual content databases.</li>
<li>Restricting access. While the granular security in SharePoint allows you to lock down access quite significantly, there is the possibility that a user may have levels of access which would give them the ability to modify these resources when they shouldn’t. It would be a bad security scheme that enabled this, but keeping the files out of the content database and on the file system would ensure this never happened.</li>
<li>Performance. Out of the box you’d get better performance having the resources on the file system rather than the content database. You can get around this for the most part using the build-in caching mechanisms within SharePoint such as BLOB caching, however for MOSS at least there are known issues associated with this noted in Chris O’Brien’s post on <a href="http://www.sharepointnutsandbolts.com/2009/05/optimization-blob-caching-and-http-304s.html" target="_blank">Optimization, BLOB caching and HTTP 304s</a>.</li>
</ol>
<p>It’s a question that seems to polarise the SharePoint community and there are a bunch of blog posts, <a href="http://msdn.microsoft.com/en-us/library/dd221375.aspx#odcsp2007taDeploymentOptionsforBrandingFiles" target="_blank">MSDN articles</a> and <a href="http://sharepoint.stackexchange.com/questions/2219/css-files-in-layouts-or-document-library">discussions</a> on this very subject matter. My personal opinion now, which would appear to be backed by a number of credible posts I’ve since read, is that ideally resources for SharePoint should be stored in the content database whenever possible.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spmatt.wordpress.com/307/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spmatt.wordpress.com/307/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spmatt.wordpress.com/307/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spmatt.wordpress.com/307/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/spmatt.wordpress.com/307/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/spmatt.wordpress.com/307/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/spmatt.wordpress.com/307/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/spmatt.wordpress.com/307/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spmatt.wordpress.com/307/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spmatt.wordpress.com/307/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spmatt.wordpress.com/307/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spmatt.wordpress.com/307/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spmatt.wordpress.com/307/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spmatt.wordpress.com/307/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=307&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://spmatt.wordpress.com/2011/12/26/referencing-resources-in-sharepoint-file-system-or-content-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0d26e27d7507158fb5a229f002b3c314?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">menezesm</media:title>
		</media:content>
	</item>
		<item>
		<title>Applying the MVVM pattern to create SharePoint list-driven interactive tools using Knockout</title>
		<link>http://spmatt.wordpress.com/2011/12/17/applying-the-mvvm-pattern-to-create-sharepoint-list-driven-interactive-tools/</link>
		<comments>http://spmatt.wordpress.com/2011/12/17/applying-the-mvvm-pattern-to-create-sharepoint-list-driven-interactive-tools/#comments</comments>
		<pubDate>Sat, 17 Dec 2011 06:20:04 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[ASHX Handler]]></category>
		<category><![CDATA[jQuery.tmpl]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Knockout]]></category>
		<category><![CDATA[Model-View-View Model]]></category>
		<category><![CDATA[MVVM]]></category>
		<category><![CDATA[SharePoint 2007]]></category>

		<guid isPermaLink="false">http://spmatt.wordpress.com/?p=296</guid>
		<description><![CDATA[MVC, MVP, MVVM. They’re common acronyms that any developer worth their salt would have at least a vague understanding of what they mean and entail. I remember doing an MVC hands-on lab at Tech-Ed 2-3 years ago in ASP.NET for my own curiosity, see what all the fuss was about. Having been in the SharePoint [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=296&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>MVC, MVP, MVVM. They’re common acronyms that any developer worth their salt would have at least a vague understanding of what they mean and entail. I remember doing an MVC hands-on lab at Tech-Ed 2-3 years ago in ASP.NET for my own curiosity, see what all the fuss was about. Having been in the SharePoint realm for the past 3 and a half years though it’s something that I never thought would have had much application in my day to day job. Surely it was just left to the ASP.NET crowd, nothing to do with SharePoint. How wrong I was.</p>
<p>To be honest this article could go on forever with explanations and definitions, examples and possibilities. What I’ve since found when researching for this post however is that the information available on the net is actually pretty comprehensive. Unsure what the difference is between the various view-model design patterns? Take a look at Niraj Bhatt’s post on <a href="http://nirajrules.wordpress.com/2009/07/18/mvc-vs-mvp-vs-mvvm/" target="_blank">MVC vs. MVP vs. MVVM</a>. In fact somewhat to my surprise there are even a number of quality SharePoint related posts in regards to implementing MVVM. The majority of them relate to MVVM in Silverlight hosted in SharePoint – you can read up on a great article series by Andrew Connell regarding <a href="http://www.andrewconnell.com/blog/archive/2011/10/28/silverlight-mvvm-sharepoint-about-this-series.aspx" target="_blank">Silverlight, MVVM &amp; SharePoint</a>. There’s a quality post by Shailen Sukul regarding <a href="http://www.shailen.sukul.org/2011/06/applying-mvvm-principles-to-sharepoint.html" target="_blank">Applying MVVM Principles to SharePoint 2010 Development</a>. There’s even a post on <a href="http://blah.winsmarts.com/2011-5-using_mvvm_with_office365_and_sharepoint_2010_rest_api.aspx" target="_blank">Using MVVM with Office365 and SharePoint 2010 REST API</a> by Sahil Malik.</p>
<p>Sahil&#8217;s post is somewhat similar to my own. The reason being, we’ve both implemented the MVVM pattern using <a href="http://knockoutjs.com/" target="_blank">Knockout</a> – a library to ‘Simplify dynamic JavaScript UIs by applying the Model-View-View Model (MVVM) Pattern’. There is a difference however – where Sahil had the luxury of using the SharePoint 2010 REST APIs which go hand in hand perfectly for this purpose, my task was to implement it in MOSS 2007.</p>
<p>The tools created using this method are a part of the suite of tools that exist on the <a href="http://careercentre.dtwd.wa.gov.au/" target="_blank">Career Centre Portal</a> including the Resume Builder, Slider tools, Choices and Hands On, Career Possibility Generator, Card Sort tools and multiple forms throughout the site. A number of developers have played a large part in the creation of these tools and forms including Paul Maddox, Elliot Wood, Lay Hooi Tan and myself. Some are SharePoint list-driven and others are CRM-driven. For the purpose of this article I’ll focus on the <a href="http://careercentre.dtwd.wa.gov.au/occupations/Pages/CareerPossibilityGenerator.aspx" target="_blank">Career Possibility Generator</a>.</p>
<p>So how does Knockout work? It could really do with a post of its own. I’d suggest reading the <a href="http://knockoutjs.com/documentation/introduction.html" target="_blank">documentation</a> for a full explanation of how it works and its capabilities. Trying to keep it simple however, essentially you use data-binds to map UI elements to values stored in a data model. If you define the value as ‘observable’ you ensure that updates to the UI are reflected in the model and vice-versa. Knockout also harnesses the jQuery.tmpl template engine to render repeatable blocks of code.</p>
<p>It&#8217;s driven really well by using a JSON object as the underlying data model. This is why it ties in so nicely with the SharePoint 2010 REST services – you can quite easily pull back a JSON object instead of an Atom response via those services and use it within the Knockout framework. To get around this missing functionality an ASHX handler was created to return the JSON object for us. This is quite easy to do – the generic shell of the handler would look something like that shown below:</p>
<p><pre class="brush: csharp;">
public class MyHandler : IHttpHandler
{
    #region IHttpHandler Members

    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        List&lt;CloudListItem&gt; items = new List&lt;CloudListItem&gt;();
        // Retrieve items from SharePoint and populate into the generic list
        JavaScriptSerializer ser = new JavaScriptSerializer();
        string jsonObject = ser.Serialize(items);
        context.Response.Clear();
        context.Response.ContentType = &quot;application/json&quot;;
        context.Response.Write(jsonObject);
    }

    #endregion
}

public class CloudListItem
{
    // Various properties to return in the JSON object
}
</pre></p>
<p>The next step is to bind the returned JSON object to Knockout and in turn allow Knockout to bind the values to the UI using applyBindings.</p>
<p><pre class="brush: jscript;">
&lt;script id=&quot;Occupations_Cloud_Tmpl&quot; type=&quot;text/x-jquery-tmpl&quot;&gt;
    &lt;li class=&quot;cloud${Count}&quot;&gt;&lt;a target='_blank' href=&quot;${PageUrl}&quot;&gt;
      &lt;label data-bind=&quot;text:Title&quot;&gt;&lt;/label&gt;
    &lt;/a&gt;&lt;/li&gt;
&lt;/script&gt;

&lt;div id=&quot;tag-cloud&quot;&gt;
    &lt;ul id=&quot;occupations-cloud&quot;
        data-bind=&quot;template: {name: 'Occupations_Cloud_Tmpl', foreach: viewModel.Cloud}&quot;&gt;
    &lt;/ul&gt;
&lt;/div&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
    $.getJSON('/_controltemplates/ccosdportal/handlers
               /ListToJsonHandler.ashx?ListName=NormalisedKSA
               &amp;Web=occupations', function(data){
        //viewModel.Cloud = ko.mapping.fromJS(data);
        viewModel.Cloud = data;
        $.each(viewModel.Cloud, function(index, value) {
            value.Count = ko.observable(0);
        });
        ko.applyBindings(viewModel.Cloud);
    });
&lt;/script&gt;
</pre></p>
<p>Essentially what the above code will result in is an unordered list of Occupation profile links with a distinct class applied. I’ve left in the comment above to demonstrate one of the gotchyas I encountered using Knockout. By using ko.mapping.fromJS() you’re essentially ensuring that all properties within the JSON object are observable. This causes some memory issues if the object is too large and can result in the following warning in Internet Explorer browsers:</p>
<p><a href="http://spmatt.files.wordpress.com/2011/12/ie-knockout-issue.png"><img class="alignnone size-medium wp-image-298" title="IE-knockout-issue" src="http://spmatt.files.wordpress.com/2011/12/ie-knockout-issue.png?w=300&#038;h=141" alt="" width="300" height="141" /></a></p>
<p>The only thing left to explain here is how the ‘observable’ functionality works. The tool itself includes a number of checkboxes which users can select which in turn drives how the cloud looks on the screen. The checkboxes are mapped in SharePoint lists to various occupations and thus when a checkbox is selected that maps to a given occupation, the class applied to the relevant list item is modified to reflect that link. As you may have noticed, the only observable property in the object is the ‘Count’ which is used in the list item class=”cloud${Count}”. By incrementing the Count value in the model, the UI is updated to reflect the new value and hence changes the class of the list item, changing the way it displays on the screen.</p>
<p><pre class="brush: jscript;">
function AdjustCloud(checkbox) {
    var addValue = -1;
    if (checkbox.checked) addValue = 1;

    $.getJSON('/_controltemplates/ccosdportal/handlers
               /ListToJsonHandler.ashx?ListName=OccupationKSA
               &amp;Web=occupations&amp;KSAID=' + checkbox.value, function(data){
    if (data.length &gt; 0)
    {
        $.each(data, function(ind, dtwd) {
            var dtwdVal = dtwd.DTWDANZSCO;
            $.each(viewModel.Cloud, function(index, value) {
              var clouddtwdVal = value.DTWDANZSCO;
              if (clouddtwdVal == dtwdVal)
                if (((viewModel.Cloud[index].Count() + addValue) &gt;= 0) &amp;&amp;
                   ((viewModel.Cloud[index].Count() + addValue) &lt;= 9))
                       viewModel.Cloud[index].Count(viewModel.Cloud[index].Count() + addValue);
            });
        });

         HideItems();
    }
    });
}
</pre></p>
<p>A visual example of the tool can be seen below (click for the full-sized image).</p>
<p><a href="http://spmatt.files.wordpress.com/2011/12/career-possibility-generator.png" target="_blank"><img class="alignnone size-medium wp-image-301" title="career-possibility-generator" src="http://spmatt.files.wordpress.com/2011/12/career-possibility-generator.png?w=300&#038;h=165" alt="" width="300" height="165" /></a></p>
<p>If you take the time to look at the <a href="http://careercentre.dtwd.wa.gov.au/occupations/Pages/CareerPossibilityGenerator.aspx" target="_blank">Career Possibility Generator</a> and all the tools throughout the <a href="http://careercentre.dtwd.wa.gov.au" target="_blank">Career Centre Portal</a> you’ll get an appreciation of how powerful it is to leverage the MVVM pattern via Knockout to create highly interactive applications within SharePoint.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spmatt.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spmatt.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spmatt.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spmatt.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/spmatt.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/spmatt.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/spmatt.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/spmatt.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spmatt.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spmatt.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spmatt.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spmatt.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spmatt.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spmatt.wordpress.com/296/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=296&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://spmatt.wordpress.com/2011/12/17/applying-the-mvvm-pattern-to-create-sharepoint-list-driven-interactive-tools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0d26e27d7507158fb5a229f002b3c314?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">menezesm</media:title>
		</media:content>

		<media:content url="http://spmatt.files.wordpress.com/2011/12/ie-knockout-issue.png?w=300" medium="image">
			<media:title type="html">IE-knockout-issue</media:title>
		</media:content>

		<media:content url="http://spmatt.files.wordpress.com/2011/12/career-possibility-generator.png?w=300" medium="image">
			<media:title type="html">career-possibility-generator</media:title>
		</media:content>
	</item>
		<item>
		<title>Integrating WordPress into SharePoint</title>
		<link>http://spmatt.wordpress.com/2011/12/13/integrating-wordpress-into-sharepoint/</link>
		<comments>http://spmatt.wordpress.com/2011/12/13/integrating-wordpress-into-sharepoint/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 15:29:59 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[metaWeblog]]></category>
		<category><![CDATA[web.config]]></category>
		<category><![CDATA[Wordpress API]]></category>
		<category><![CDATA[XML-RPC]]></category>

		<guid isPermaLink="false">http://spmatt.wordpress.com/?p=289</guid>
		<description><![CDATA[The title here may be slightly misleading. The majority of this post will be applicable to any .NET application integrating with WordPress &#8211; however my experiences were derived from creating the WordPress functionality within the Career Centre portal. The requirements were for an extract of the latest post to appear on the front page and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=289&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The title here may be slightly misleading. The majority of this post will be applicable to any .NET application integrating with WordPress &#8211; however my experiences were derived from creating the WordPress functionality within the <a href="http://careercentre.dtwd.wa.gov.au/" target="_blank">Career Centre</a> portal. The requirements were for an extract of the latest post to appear on the front page and for any relevant categories to be presented on the Career Connect page. The featured article functionality was initially intended to come from WordPress but ended up being list-driven as there was no obvious way to mark the WordPress blog as a feature (In hindsight I may have created a &#8216;Feature&#8217; category in WordPress and use the API to bring it back that way, but as it stands it&#8217;s relatively static).</p>
<p><a href="http://spmatt.files.wordpress.com/2011/12/latest-blog.png"><img class="alignnone size-medium wp-image-290" title="latest-blog" src="http://spmatt.files.wordpress.com/2011/12/latest-blog.png?w=210&#038;h=300" alt="" width="210" height="300" /></a><a href="http://spmatt.files.wordpress.com/2011/12/blog-categories.png"><img class="alignnone size-medium wp-image-291" title="blog-categories" src="http://spmatt.files.wordpress.com/2011/12/blog-categories.png?w=276&#038;h=300" alt="" width="276" height="300" /></a></p>
<p>This actually turned out a little more challenging than I was expecting. There appeared to be a lot of information in regards to WordPress APIs as it related to plugin development, but the information I was searching for wasn&#8217;t as obvious to find. I eventually found out that WordPress supports both the Atom Publishing Protocol (AtomPub) and XML-RPC for client development and that currently WordPress provides more features and capabilities via XML-RPC than AtomPub. XML-RPC seemed the way to go.</p>
<p>This snippet of information actually made life a lot easier. Turns out that the information WordPress provides on this subject is actually pretty useful. Firstly there&#8217;s the <a href="http://codex.wordpress.org/XML-RPC_Support" target="_blank">XML-RPC Support</a> page which identified that 3 APIs were supported; Blogger, metaWeblog and Movable Type. There&#8217;s also an extension to the Movable Type API specific for WordPress (conveniently called the WordPress API) that should be used as a first resort if possible. That API is pretty well documented too on the <a href="http://codex.wordpress.org/XML-RPC_wp" target="_blank">XML-RPC wp</a> page.</p>
<p>It seemed pretty promising &#8211; getCategories? Perfect. There didn&#8217;t seem to be an obvious way to get the latest blog post though from this API so the search continued. Reading through the alternate API&#8217;s metaWeblog seemed the easiest to use and appeared to have the functionality I needed. Unfortunately I found it to be pretty poorly documented &#8211; it seemed that no one wanted to make this task easy! I did stumble across one page; Eric&#8217;s <a href="http://mindsharestrategy.com/2010/wp-xmlrpc-metaweblog/" target="_blank">WordPress XML-RPC – MetaWeblog API</a>. Without this page I think I would have had a much harder time getting everything to work &#8211; getRecentPosts? Perfect.</p>
<p>The only thing left to do was to code it up in .NET. Turns out there&#8217;s an excellent library for this purpose by Charles Cook called <a href="http://www.xml-rpc.net/" target="_blank">XML-RPC.NET</a>. The download includes the DLL you&#8217;ll need to reference (CookComputing.XmlRpcV2.dll) and a bunch of examples to get you started.</p>
<p>Time to pull out a few code snippets. Firstly you need to create an interface with the functions you intend to call:</p>
<p><pre class="brush: csharp;">
public interface IStateName : IXmlRpcProxy
{
    [XmlRpcMethod(&quot;wp.getUsersBlogs&quot;)]
    Blog[] GetUsersBlogs(string username, string password);

    [XmlRpcMethod(&quot;metaWeblog.getRecentPosts&quot;)]
    BlogEntry[] GetPosts(int blog_id, string username, string password, int numberOfPosts);

    [XmlRpcMethod(&quot;wp.getCategories&quot;)]
    Category[] GetCategories(int blog_id, string username, string password);
}
</pre></p>
<p>The arrays are public structures with the properties you&#8217;re wanting to pull back &#8211; note that casing is important for the properties &#8211; make sure it matches the documentation exactly. Next is the code to retrieve the most recent post, and then all the blog categories:</p>
<p><pre class="brush: csharp;">
IStateName proxy = XmlRpcProxyGen.Create&lt;IStateName&gt;();
proxy.Url = XMLRPCUrl;

BlogEntry[] blogEntries = null;
BlogEntry blogEntry = new BlogEntry();
Blog[] blogs = proxy.GetUsersBlogs(Username, Password);
if (blogs.Length &gt; 0)
{
    Blog blog = blogs.FirstOrDefault(s =&gt; s.blogName == BlogName);

    if (blog.blogid != null)
    {
        blogEntries = proxy.GetPosts(int.Parse(blog.blogid), Username, Password, 1);
        blogEntry = blogEntries[0];
    }
}
</pre><br />
<pre class="brush: csharp;">
IStateName proxy = XmlRpcProxyGen.Create&lt;IStateName&gt;();
proxy.Url = XMLRPCUrl;

Category[] categories = null;
Blog[] blogs = proxy.GetUsersBlogs(Username, Password);
if (blogs.Length &gt; 0)
{
    Blog blog = blogs.FirstOrDefault(s =&gt; s.blogName == BlogName);

    if (blog.blogid != null)
    {
        categories = proxy.GetCategories(int.Parse(blog.blogid), Username, Password);
    }
}
</pre></p>
<p>The XMLRPCUrl is your wordpress address /xmlrpc.php (ie http://spmatt.wordpress.com/xmlrpc.php), the BlogName is the name of your blog (ie SPMatt) and your Username and Password is pretty self explanatory &#8211; use the account you use to author/administer your blog (I believe some of the actions you&#8217;re able to perform are dependant on the credentials of the account you use &#8211; using the administrator account is obviously the bad practice / guaranteed success way of getting it working).</p>
<p>That&#8217;s pretty much it. There&#8217;s one last potential gotchya and that&#8217;s to do with organisational proxies on your SharePoint servers. If the server requires a proxy to access the internet then there&#8217;s a fair chance you&#8217;re going to end up getting an error page like this (click to expand):</p>
<p><a href="http://spmatt.files.wordpress.com/2011/12/proxy-error.png" target="_blank"><img class="alignnone size-medium wp-image-292" title="proxy-error" src="http://spmatt.files.wordpress.com/2011/12/proxy-error.png?w=300&#038;h=132" alt="" width="300" height="132" /></a></p>
<p>What&#8217;s required is to find the proxy line in your web.config and change it to the following:</p>
<p><pre class="brush: csharp;">
&lt;system.net&gt;
  &lt;defaultProxy&gt;
    &lt;proxy proxyaddress=&quot;http://your-proxy-address:port&quot; bypassonlocal=&quot;true&quot; /&gt;
  &lt;/defaultProxy&gt;
&lt;/system.net&gt;
</pre></p>
<p>And that should be it! You&#8217;re good to go. Pretty basic integration I know, but for most public facing sites this is all you&#8217;ll ever need. Dig in to the APIs and see the true power you can get interacting with WordPress through the APIs (anyone feeling like authoring blogs in SharePoint and publishing them to WordPress and vice-versa?).</p>
<p>One last point I should mention &#8211; I&#8217;ve yet to link in this blog to a man who seems to be a bit of a guru in this stuff &#8211; at least it seems that way from the research I did. His name is Joseph Scott and you can view a slidedeck of a presentation on the <a href="http://www.slideshare.net/josephscott/wordpress-apis" target="_blank">WordPress APIs here</a>. If you&#8217;re scouring the net for decent advice I&#8217;d suggest looking out for his name would be a good start.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/spmatt.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/spmatt.wordpress.com/289/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/spmatt.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/spmatt.wordpress.com/289/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/spmatt.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/spmatt.wordpress.com/289/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/spmatt.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/spmatt.wordpress.com/289/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/spmatt.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/spmatt.wordpress.com/289/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/spmatt.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/spmatt.wordpress.com/289/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/spmatt.wordpress.com/289/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/spmatt.wordpress.com/289/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=spmatt.wordpress.com&amp;blog=30268948&amp;post=289&amp;subd=spmatt&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://spmatt.wordpress.com/2011/12/13/integrating-wordpress-into-sharepoint/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0d26e27d7507158fb5a229f002b3c314?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">menezesm</media:title>
		</media:content>

		<media:content url="http://spmatt.files.wordpress.com/2011/12/latest-blog.png?w=210" medium="image">
			<media:title type="html">latest-blog</media:title>
		</media:content>

		<media:content url="http://spmatt.files.wordpress.com/2011/12/blog-categories.png?w=276" medium="image">
			<media:title type="html">blog-categories</media:title>
		</media:content>

		<media:content url="http://spmatt.files.wordpress.com/2011/12/proxy-error.png?w=300" medium="image">
			<media:title type="html">proxy-error</media:title>
		</media:content>
	</item>
	</channel>
</rss>
