<?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/"
	>

<channel>
	<title>CleverWorkarounds &#187; Features</title>
	<atom:link href="http://www.cleverworkarounds.com/category/sharepoint/application-development/features/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cleverworkarounds.com</link>
	<description>After much frustration, it seems DEFAULT is the way to go...</description>
	<lastBuildDate>Mon, 07 Jun 2010 10:20:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>SharePoint development/deployment governance&#8230;</title>
		<link>http://www.cleverworkarounds.com/2008/05/28/sharepoint-developmentdeployment-governance/</link>
		<comments>http://www.cleverworkarounds.com/2008/05/28/sharepoint-developmentdeployment-governance/#comments</comments>
		<pubDate>Tue, 27 May 2008 16:01:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[Governance]]></category>
		<category><![CDATA[STSDEV]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Troubleshooting]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2008/05/28/sharepoint-developmentdeployment-governance/</guid>
		<description><![CDATA[My home-town compatriot Jeremy Thake has hit onto a governance topic that I think will turn into a very popular series once he is done with it (in committing to writing it, he will be a busy boy indeed for a while I suspect ). He has written a post on current methods and common [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p><script type="text/javascript"><!--
google_ad_client = "pub-6551570212921028";
google_ad_width = 468;
google_ad_height = 60;
google_ad_format = "468x60_as";
google_ad_type = "text_image";
google_ad_channel = "";
google_ui_features = "rc:6";
//-->
</script>
<script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<p>My home-town compatriot <a href="http://wss.made4the.net" target="_blank">Jeremy Thake</a> has hit onto a governance topic that I think will turn into a very popular series once he is done with it (in committing to writing it, he will be a busy boy indeed for a while I suspect <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ). </p>
<p>He has written a <a href="http://wss.made4the.net/archive/2008/05/26/solution-development-in-sharepoint-2007.aspx" target="_blank">post</a> on current methods and common issues of deployment of SharePoint customisations from dev to staging to prod, with particular reference to the current pain associated with iterative development and deployment.</p>
<p>The state of play in this area out in SharePoint land is not the best, due to a wide variety of factors and Jeremy sums it up very well. </p>
<p>Certainly, there are some extremely annoying architectural quirks. Back when I did the branding series I encountered some, but Jeremy has hit some nastier ones than what I found. </p>
<p>Anyway, t<a href="http://wss.made4the.net/archive/2008/05/26/solution-development-in-sharepoint-2007.aspx?id=674" target="_blank">ake a look at his post</a> &#8211; its a good read.</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-6551570212921028";
google_ad_width = 468;
google_ad_height = 60;
google_ad_format = "468x60_as";
google_ad_type = "text_image";
google_ad_channel = "";
google_ui_features = "rc:6";
//-->
</script>
<script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2008/05/28/sharepoint-developmentdeployment-governance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why do SharePoint Projects Fail &#8211; Part 6</title>
		<link>http://www.cleverworkarounds.com/2008/05/12/why-do-sharepoint-projects-fail-part-6/</link>
		<comments>http://www.cleverworkarounds.com/2008/05/12/why-do-sharepoint-projects-fail-part-6/#comments</comments>
		<pubDate>Sun, 11 May 2008 14:16:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[Governance]]></category>
		<category><![CDATA[Project Management]]></category>
		<category><![CDATA[SDK]]></category>
		<category><![CDATA[STSDEV]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Web Parts]]></category>
		<category><![CDATA[Wicked Problems]]></category>
		<category><![CDATA[planning]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2008/05/12/why-do-sharepoint-projects-fail-part-6/</guid>
		<description><![CDATA[Hi again and welcome to part 6 of my series on the factors of why SharePoint projects fail. Joel Oleson&#8217;s write-up a while back gave me 5 minutes of fame, but like any contestant on Big Brother, I&#8217;ve had my time in the limelight, been voted out of the house (as in Joel&#8217;s front page) [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p><!--adsense--></p>
<p>Hi again and welcome to part 6 of my series on the factors of why SharePoint projects fail. Joel Oleson&#8217;s <a href="http://www.sharepointjoel.com/archive/2008/05/07/insights-why-sharepoint-projects-fail.aspx" target="_blank">write-up</a> a while back gave me 5 minutes of fame, but like any contestant on Big Brother, I&#8217;ve had my time in the limelight, been voted out of the house (as in Joel&#8217;s <a href="http://www.sharepointjoel.com/default.aspx" target="_blank">front page</a>) and I&#8217;m back to being an ordinary citizen again.</p>
<p>If you have followed events thus far, I covered off some <a href="http://www.cleverworkarounds.com/2008/04/11/why-do-sharepoint-projects-fail-part-1/" target="_blank">wicked problem theory</a>, before delving into the <a href="http://www.cleverworkarounds.com/2008/04/19/why-do-sharepoint-projects-fail-part-3/" target="_blank">bigger ticket</a> items that contribute to SharePoint project failure. In the <a href="http://www.cleverworkarounds.com/2008/04/27/why-do-sharepoint-projects-fail-part-5/" target="_blank">last post</a>, we pointed our virtual microscope at the infrastructure aspects that can cause a SharePoint problem to go off the rails.</p>
<p>Now we turn our magnifying glass onto application development issues and therefore application developers. Ah, what fun you can have with application developer stereotyping, eh! A strange breed indeed they are. As a group they have had a significant contribution to the bitter and twisted individual that I am today.</p>
<p>The CleverWorkarounds tequila shot rating is back!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a> <a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a> for a project manager in denial <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2009/09/image_thumb.png" width="30" height="43" /></a><a href="http://images.google.com/imgres?imgurl=http://louisa123.files.wordpress.com/2007/10/redbull.jpg&amp;imgrefurl=http://louisa123.wordpress.com/2007/10/17/a-time-for-stress/&amp;h=480&amp;w=480&amp;sz=27&amp;hl=en&amp;start=6&amp;sig2=yadZAfpAiOwduFHe_8v0Bw&amp;tbnid=jcP1Z-h8tmYnvM:&amp;tbnh=129&amp;tbnw=129&amp;ei=SNwDSIrBKJiuiAHitLXbCg&amp;prev=/images%3Fq%3Dredbull%26imgsz%3Dsmall%257Cmedium%257Clarge%257Cxlarge%26gbv%3D2%26ndsp%3D18%26hl%3Den%26safe%3Doff%26sa%3DN"><img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" src="http://tbn0.google.com/images?q=tbn:jcP1Z-h8tmYnvM:http://louisa123.files.wordpress.com/2007/10/redbull.jpg" width="129" height="129" /></a>for the rest of us!</p>
</p>
<p><span id="more-752"></span></p>
<h2>Leave us sensitive developers alone already!</h2>
<p>Oh please.. I could make insultingly broad, sweeping generalisations about developers to make people laugh, but you guys hate each-other more than you do the rest of us! So any insult that I come up with will be water off a duck&#8217;s back and you will no doubt have a good come-back insult loaded up and ready to shoot me down <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Case in point? Go and read <a href="http://diveintomark.org/archives/2004/08/16/specs" target="_blank">this hilarious post</a> by Mark Pilgrim &#8211; an oldie but a real goodie. Warning: there is profanity there. I&#8217;d dearly like to repeat it here because it&#8217;s pure gold, but I wear a suit now and I am supposed to sound all &quot;impressive and wise&quot;. Got to keep up appearances <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Mark&#8217;s post is mandatory reading for anyone following this series. Stop now and read! (It&#8217;s cool &#8211; I&#8217;ll wait for you).</p>
<p>** cue elevator music **</p>
<p>All done? Excellent. Let&#8217;s move on!</p>
<p>Mark is the sort of developer who would be worth his weight in gold. What is great about the above post is that it is actually an excellent example of the social complexity of projects and why it is so incredibly challenging to get a project team (stakeholders and user reference group included) to see a <strong>common version of the truth</strong>. Although Mark nails his fellow developers to the wall here, an equally witty project manager, information worker or senior executive could write the same sort of post for their discipline area.</p>
<p>In common with what I said during the infrastructure oriented post, a lot of application development issues are simply a manifestation of wicked problems that have not been recognised earlier. Although everything I have outlined in posts 1-4 is where you will find your root causes, in an organisation with a low maturity level the project team likely has been largely oblivious to the warning signs up until this point. Suddenly once we are cutting code, problems start to become apparent and it&#8217;s all those damn developers fault of course!</p>
<p>So once again, for the rest of this post we have to do a suspension of belief. In <a href="http://www.cleverworkarounds.com/2008/04/27/why-do-sharepoint-projects-fail-part-5/" target="_blank">part 5</a> we went to Homer Simpson&#8217;s land of chocolate. So for this post, how about we can all pretend that we live in a world where teenyboppers do not exist and therefore people&#8217;s minds haven&#8217;t turned to jelly from being bombarded by crap music &#8211; so let&#8217;s blame Britney Spears for 99% of project failures.</p>
<h2>In the world without Britney Spears</h2>
<p>In this world, the stakeholders all agree with each-other. They have a tacit and deep understanding of the organisation&#8217;s vision, strategy and exactly how that strategy is to be executed. Therefore, they have clearly and unambiguously articulated this vision to the project team. This information in turn has been understood at all levels by the project team and after much investigation, soul searching and deep analysis, the entire team agrees completely that SharePoint is the perfect fit.</p>
<p>After reading all of the insightful information in the CleverworkArounds&#8217; &quot;<a href="http://www.cleverworkarounds.com/2007/11/17/learn-to-talk-to-your-cfo-in-their-language-part-1/">Learn to speak to your CFO</a>&quot; series <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> , a project management plan has been put together and agreed upon and signed off by all stakeholders. Scope, constraints and assumptions are reasonable and clear. A work breakdown structure has been developed and signed off with well developed budget and accurate, confident estimates.</p>
<p>What could possibly go wrong? <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h2>Thinking your developers are developers</h2>
<p>Jeremy Thake wrote about &quot;<a href="http://wss.made4the.net/Lists/Posts/Post.aspx?ID=669" target="_blank">organisational responsibility</a>&quot; recently, and my new &quot;homie&quot; Joel made his <a href="http://www.sharepointjoel.com/archive/2008/05/07/insights-why-sharepoint-projects-fail.aspx" target="_blank">feelings known</a> when he wrote about the folly of &quot;<strong>Thinking your developers are administrators</strong>&quot;. This needs to be analysed further however. I prefer to use the title &quot;Thinking your developers are developers&quot;. The world is rife with what one would term &quot;bad programming&quot;. The term is something of a misnomer though. I work with a great free WCM system called Joomla, and it has a devoted community of developers writing add-on modules for a dizzying array of options. Most are very well written, but some of these modules I have hacked away at the source and quite frankly they are pretty bad (and coming from a part time developer like me, that&#8217;s saying something).</p>
<h2>Wishing your developers are admins?</h2>
<p>That term &quot;bad programming&quot; is misleading and potentially unfair, because bad programming can contain tight, readable code that would satisfy industry standard conventions. In actual fact I&#8217;m not really all that fussed about the source code unless it&#8217;s *monumentally* stupid. Instead it is all about the <strong>thought process that went into the development</strong>. Here is a real world example from my past of what I mean.</p>
<p><em>A system developed by a former employer of mine relied extensively on DNS aliases, that our customers had to add into their DNS. So when our application looked for its </em><em>&quot;server&quot;, it queried DNS for that alias. I suggested that this was not a good idea, and we would be much better served via a registry setting that could override this, centrally controlled via group policy in Active Directory. The suggestion was met with general disinterest until s</em><em>ome time later, we had an install at a site with several physical locations.There would be a server at each location, but the customer&#8217;s Active Directory set-up was a single DNS namespace. Thus we could only add a DNS alias for 1 server, yet we had several sites where servers resided. The system couldn&#8217;t handle the fact that a DNS can spread over multiple sites.</em></p>
<p><em>One quickly convened meeting later and suddenly the penny dropped on the logic of my suggestion. (But it took a real world emergency for that to happen). The next problem was the developers immediately chose the wrong location for registry key. Microsoft have a <a href="http://support.microsoft.com/?id=323639" target="_blank">guide</a> that tells you *where* in the registry to place your modification and they didn&#8217;t know there were recommendations and didn&#8217;t think to check for such a recommendation. Fortunately I caught that one in time and got it sorted.</em></p>
<p>That example highlights that &quot;bad programming&quot; was actually more like lack of awareness of important external considerations. I named the title of this section, &quot;Wishing your developers are admins&quot;, more for the example that I cited than a statement of fact. Certainly, infrastructure administrators are very crap coders, (despite what they think of their efforts). But they do have a greater affinity for integration oriented governance issues than their pure development counterparts because of the nature of their role.</p>
<p>Sniggering infrastructure people who are feeling superior now should stop and take note. Experience has shown me time and time again that greater awareness about governance and integration rarely translates to actually running their environment to the ideals they espouse however <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  .</p>
<p><em>Read my <a href="http://www.cleverworkarounds.com/2008/02/17/selling-moss-a-choose-your-own-adventure-story/" target="_blank">Choose Your Own Adventure</a> post for a more offbeat and sarcastic take on that issue.</em></p>
<h2>Planting wicked seeds..</h2>
<p>In <a href="http://www.cleverworkarounds.com/2008/04/27/why-do-sharepoint-projects-fail-part-5/" target="_blank">part 5</a>, I had a section entitled &quot;Infrastructure and Product Skills&quot;, and I suggested that a lack of product awareness and skills among infrastructure designers did not always manifest themselves into pain and suffering until later down the track. In the application development discipline, this is even <strong>more</strong> of a problem, and the remainder of this post focuses pretty much on this area, since if things do go down this road, it is simply going to end up being one of the root causes of the <strong>next, even more wicked problem </strong>to try and solve.</p>
<p>The impact of a bad design decision today can in particular have far reaching consequences into the future. Microsoft have this problem at a level that would blow your mind if you have been around long enough know your history (and your security <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . Remember than in 1973, what Rittel said of wicked problems: &quot;<strong>There is no immediate and no ultimate test of a solution to a wicked problem</strong>&quot;, and by that he meant any solution, post implementation will generate &quot;waves of consequences&quot; that may yield utterly undesirable repercussions which outweigh the intended advantages.</p>
<p>The thoroughly depressing thing about that statement is the implication that a wicked problem can arise from the unexpected aftermath of a perfectly innocent &quot;non wicked&quot; problem!</p>
<p>So let&#8217;s see where SharePoint and the systems it relies upon makes life hard for developers and can blow out projects.</p>
<h2>The obvious way is usually the dumb way</h2>
<p>I am going to start by showing you some C# code. Non programmers, don&#8217;t be scared, it&#8217;s not too bad and in honour of Ms Spears I have kept the theme going. It is opening a SharePoint list programmatically, looking for anything with a title of &quot;Oops I did it again&quot; and if it matches that term, informs you that you must &quot;Wash your mouth out!&quot;.</p>
</p>
<pre class="csharpcode"><span class="kwrd">foreach</span> (SPListItem item <span class="kwrd">in</span> list.Items)


{

<span class="kwrd">if</span> (item.Title == <span class="str">&quot;Oops I did it again&quot;</span>) {

console.Writeline(<span class="str">&quot;Wash your mouth out!&quot;</span>);

}

}

</pre>
<p>
<style type="text/css">
.csharpcode, .csharpcode pre</style>
</p>
<p>{</p>
<p>font-size: small;</p>
<p>color: black;</p>
<p>font-family: consolas, &#8220;Courier New&#8221;, courier, monospace;</p>
<p>background-color: #ffffff;</p>
<p>/*white-space: pre;*/</p>
<p>}</p>
<p>.csharpcode pre { margin: 0em; }</p>
<p>.csharpcode .rem { color: #008000; }</p>
<p>.csharpcode .kwrd { color: #0000ff; }</p>
<p>.csharpcode .str { color: #006080; }</p>
<p>.csharpcode .op { color: #0000c0; }</p>
<p>.csharpcode .preproc { color: #cc6633; }</p>
<p>.csharpcode .asp { background-color: #ffff00; }</p>
<p>.csharpcode .html { color: #800000; }</p>
<p>.csharpcode .attr { color: #ff0000; }</p>
<p>.csharpcode .alt</p>
<p>{</p>
<p>background-color: #f4f4f4;</p>
<p>width: 100%;</p>
<p>margin: 0em;</p>
<p>}</p>
<p>.csharpcode .lnum { color: #606060; }</p>
</p>
<p>Easy enough &#8211; aren&#8217;t lists sooo easy to work with! Let&#8217;s just say you used this sort of logic in a web part that displays only list items that have &quot;Oops&quot; in the title. A few minutes later, you have coded and tested the web part, and it works a treat. Into the change control it goes, and into production it finds itself.</p>
<p>Fast forward 4 weeks and now the list has 400 items in it. Now a refresh of the page containing your web part is taking 10 seconds and getting worse. Naturally &#8216;the network&#8217; must be the problem, right? Of course it&#8217;s not. In this example every list item is being enumerated and a comparison is made. This is <a href="http://technet.microsoft.com/en-us/library/cc262813.aspx" target="_blank">well documented</a> as the most <strong>inefficient </strong>way to query a list.</p>
<p><em>Putting on my old Cisco hat for a second, I am going to repeat an oft said mantra that people who know me will have heard many times over the years and what all self respecting Cisco nerds know. <strong>It&#8217;s not the %$^%$ network alright! It&#8217;s never been the network, it&#8217;s your $%%$ code!</strong></em></p>
<p>You think the example above is made up? It&#8217;s not! On one SharePoint project where I was the information architect, a developer from a well respected Australian integrator did <strong>exactly</strong> what I described above, and proceeded to blame the infrastructure, the architecture, the network &#8211; basically anything that wasn&#8217;t their component. Of course, their development environment only had 10 items in the list and thus it seemed fine to them!</p>
<p>If you go back to my real-world example of the DNS/Registry issue, it was a design decision that was probably given half a thought at best, only to turn out to be a major constraint down the track. My SharePoint specific example above shows that for an inexperienced developer, even a &quot;hello-world&quot; style example is potentially a landmine just waiting for you to innocently step on. The issue is that, to the uninitiated, the SharePoint ecosystem has even more virtual land mines to avoid than being Lindsay Lohan&#8217;s publicist.</p>
<p>Simply put, if you do not have a broad depth of knowledge that can only come from time, pain and experience, you are inevitably going to get blown up time and time again. What&#8217;s that old saying? There are old SharePoint developers, and there are bold SharePoint developers, but there are never any old-bold SharePoint developers <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><em>If I listed all of the examples that I could think of, this post would get out of hand, so instead, Jeremy Thake sent me his </em><a href="http://www.diigo.com/user/Jthake/sharepoint%20performance" target="_blank"><em>diigo link</em></a><em> that aggregates blog posts tagged with &quot;SharePoint and performance&quot;. That should give you some idea of what developers are getting themselves into.</em></p>
<h2>Junk DNA</h2>
<p>John Kominetz <a href="http://kominetz.com/2007/11/20/the-elephant-and-the-blind-men/" target="_blank">wrote</a> a great blog post that is highly relevent to this discussion. It has nothing to do with SharePoint in the slightest, yet if you substituted the word &quot;Documentum&quot; with &quot;SharePoint&quot; we would all be nodding our heads in collective agreement. It examines Documentum, a product that was already a mature player in the ECM space way before SharePoint had even made it to a little red box on a Redmond whiteboard.</p>
<p>Kominetz looks at Documentum&#8217;s heritage and describes it in terms akin to a living organism. He makes the observation that its &quot;genome&quot; has evolved over many years and carries with it plenty of <a href="http://en.wikipedia.org/wiki/Junk_DNA">junk DNA</a> and &quot;evolutionary dead ends&quot;. This is completely unavoidable, despite what any idealistic whinger about &quot;bloatware&quot; would like to believe. Another Joel (are all Joel&#8217;s in this world clever?), has a blog that is mandatory reading for anyone who is prone to making idealistic statements about security, bloat or complexity. I urge you to read his &quot;<a href="http://www.joelonsoftware.com/items/2008/03/17.html" target="_blank">Martian Headsets</a>&quot;, &quot;<a href="http://www.joelonsoftware.com/items/2008/05/01.html" target="_blank">Architecture Astronaut</a>&quot; (where he picks on Groove <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ), as well as his &quot;<a href="http://www.joelonsoftware.com/articles/fog0000000069.html" target="_blank">Things you should never do</a>&quot; posts. Joel is a wise man, indeed.</p>
<p>Quick history lesson for the uninitiated. SharePoint actually started as SharePoint Team Services (STS) and actually used the <strong>file system </strong>as the content store. (<em>And I predict they will eventually go back to it too but that&#8217;s <a href="http://www.cleverworkarounds.com/2008/03/25/sharepoint-external-storage-api-crushing-my-dream/" target="_blank">another story</a></em>). Next Microsoft trotted out SharePoint Portal Server (SPS) where some bright spark thought that the Exchange &quot;web storage system&quot; (information store) would make a lovely document repository (probably because of the replication potential). Over the next couple of years there must have been a big ugly turf war between the Exchange storage team and the SQL team because, lo&#8217; and behold, with SharePoint Portal Server 2003, SQL Server was now the document store. In this major architectural change, we actually <strong>lost</strong> some functionality. In addition to this, the 2003 version leveraged the recently released&#160; .NET Framework, and provided a richer object model and platform for SharePoint to sit on (although then it was not a completely cohesive fit).</p>
<p>Roll on 2007 and we have a slew of new technologies and features, too many to name. And just to make it more interesting, Microsoft decided to change terminology (again) as ASP.NET was leveraged much more heavily. Thus, &quot;webs&quot; and &quot;areas&quot; are gone. But their evolutionary signature remains. Whether it&#8217;s the SDK, the choose-your-own-adventure Technet documentation, blogs or even the STSADM command, it is very easy to spend a lot of time going down the completely wrong path in the quest for a solution to a problem because you get mired in junk DNA. Worse still, you get there, realise you solved the problem the &#8216;old&#8217; way, say &quot;stuff it&quot; and deliver it as-is.</p>
<p><em>Web Parts are a great case in point. There are actually two types of web parts in the object model. The one that was introduced with SharePoint 2003 and the one that comes with ASP.NET 2.0 (which SharePoint 2007 uses). When I was writing my </em><a href="http://www.cleverworkarounds.com/freebies/" target="_blank"><em>hide control web part</em></a><em>, almost all the technet examples as well as blogs on the subject did not make it clear which type of web part and the distinction between them. It turned out of course I was using the right web part class, but following the wrong online documentation. A couple of XML irregularities had be scratching my head for hours.</em></p>
<h2>Infrastructure, security and governance awareness (again)</h2>
<p>I sort of covered this at a high level in the &quot;Wishing your developers are admins&quot; section and it&#8217;s been said before on many blogs that SharePoint blurs the lines between developer and administrator. Both sides have to shift ground (as do project managers and stakeholders too). Administrators really need to gain more development competencies and visa versa. I won&#8217;t spend too much time reinforcing what has already been said, but always remember this: Despite all the advances in Windows 200x, IIS, SQL Server, fancy multi-layered security, richer object model via ASP.NET Version x and the like, every developer has it in his/her power to render even a tightly managed SharePoint farm a train wreck. A lack of a simple null-check can render a site un-viewable. Choosing the wrong way to execute a query on content can chew excessive amounts of CPU and memory, an ill-thought design decision can cause a good idea to be lost in the frustration of the user experience. When it all comes down to it, it is the end user acceptance, adoption and evangelism that determines whether a project has been a success or failure.</p>
<p>But it goes beyond performance. What about security considerations? As developers, do you stop and ask yourself whether your chosen course of action has implications on security? What is your definition of security anyway? (Because it is just as much about smart, re-usable design as it is about using passwords with non alphanumeric characters in them &#8211; google &quot;<a href="http://www.google.com.au/search?hl=en&amp;q=the+CIA+triad&amp;meta=" target="_blank">the CIA triad</a>&quot;).</p>
<p>A major problem area I have seen that has manifested itself in project management time frames is the difference between the development and production environments. SharePoint development environments tend to have a short shelf-life due to the amount of crap you have to install, remove, reinstall, etc. Therefore, they are best served via a single Windows 2003 Virtual Machine with Office 2007, Visual Studio 2005, SharePoint Designer, Reporting Services, SQL Server and all of the other associated paraphernalia. Give each developer their own so they don&#8217;t kill each-other <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Without question, it is exceedingly likely that the developer is an administrator of their VM, and those that have a low security acumen tend to hit problems when they migrate their solution to the test or production environment. SharePoint has that many service accounts, application pools, web applications, site permissions, GAC DLL&#8217;s, .Net Trust levels, web.configs, etc that it is very easy for something to break into the transition to production.</p>
<p>Remember, everything works when you run it all as the administrator! You will not get much sympathy from your bitter and twisted infrastructure architect if you complain about it.</p>
<p><em>Project managers and stakeholders need to also be held to account here, as developers routinely cut corners when faced with unrealistic deadlines based on poor assumptions. But don&#8217;t worry developers, I&#8217;ll nail their asses in part 7!</em></p>
<h2>Solutions and Features</h2>
<p>The next two topics have caused me real-world pain. I had an argument with a developer a while back who felt extremely inconvenienced by my audacity to mandate that their web parts, DLL&#8217;s and web.config modifications be packaged up as a solution that activates the functionality via a feature.</p>
<p>But to be fair to the developer, if they have a low governance acumen, their point of view is completely understandable. SharePoint application development governance takes time to learn and is often not accounted for in project planning phases. Tools like STSDEV have gone a long way to improving the situation, but at the end of the day, developers who hate all the additional governance overhead associated with SharePoint are buck-passing risk to a place where it is ill afforded.</p>
<h2>Branding&#8230;</h2>
<p>Don&#8217;t get me started! <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  (I&#8217;m drinking a scotch as I write this so please forgive the vitriol <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  )</p>
<p>I&#8217;ll come back to branding in part 7 of this series, because to be fair, the developers are beholden to stakeholders who obsess over the location of a pixel. In many SharePoint <a href="http://www.cleverworkarounds.com/2007/11/14/sharepoint-branding-the-governance-of-it-all-part-7/" target="_blank">scenarios</a> (not all) this is mis-focused because their success criteria is not how good it looks, but how much the organisation has gained in <a href="http://www.cleverworkarounds.com/2007/11/17/learn-to-talk-to-your-cfo-in-their-language-part-1/" target="_blank">bottom line</a>.</p>
<p>But from a developer&#8217;s perspective, this is another area where I see <strong>serious</strong> abuse. My entire branding series came from the experience of having to clean up after a &quot;consultant&quot; who decided he did not have to research into the techniques to customise SharePoint in a sustainable, governable way. He completely butchered the _layouts files with no backup or consideration to the implications of future service packs or updates and ignored built in features like the site collection style library. Instead he reinvented his own solution. As I mentioned in the previous section, I asked him to package his work up into a solution for ease of deployment and rollback and I was met with resistance and tension.</p>
<p><em>The whole concept of &#8216;CleverWorkarounds&#8217;, comes from the pragmatic acceptance that hacks are a part of life. You can&#8217;t avoid them, and sometimes you are forced to resort to them. But there is a huge difference between a workaround and a &#8216;clever workaround&#8217;. Most of the various hacks and workarounds that I describe in the more technically focused articles of this blog (like the </em><a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/" target="_blank"><em>JavaScript</em></a><em> stuff) always come from the philosophical perspective of leaving a environment where the next administrator or developer doesn&#8217;t curse your name for eternity. </em></p>
<h2>Miscellaneous considerations&#8230;</h2>
<p>Jeez, branding got me riled up &#8211; I guess the scars are still fresh on that one! <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/05/image1.png"><img style="border-right-width: 0px; margin: 0px 20px 0px 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/05/image-thumb1.png" width="125" height="177" /></a></p>
<p><em>No-one can know everything. Everyone has governance deficiencies in one way or another. I remember in 2003, a shattered project manager came into my office. A client meeting had gone very badly, blown up in his face in fact. He came to me and his classic line to me was &quot;All I did was tell them to modify their Active Directory schema!&quot;. If you know Active Directory, you would know what sort of landmine he just stepped on. It&#8217;s like telling Mr T. that his &quot;bling&quot; really brings out his feminine side!</em></p>
<p>Thus, the branding hacks manifest themselves in other areas too. Pretty much any time you delve into the guts of the 12 Hive (tech guys and devs know what I&#8217;m referring to here), you have to be very mindful of governance, security and re-use. Ask yourself this question</p>
<p>Does the change I am making have <strong>any</strong> chance of being undone or unduly affected by a future patch or service pack?</p>
<p>Is the answer is yes, <strong>then stop and get some advice! </strong></p>
<p>Developers in general get frustrated with their project managers. The PM&#8217;s nag, don&#8217;t have a deep enough understanding of the intricacies and nuances of application development and set unreasonable deadlines based on what you see as incomplete requirements and assumptions. However, as I have said in the <a href="http://www.cleverworkarounds.com/2008/04/15/why-do-sharepoint-projects-fail-part-2/" target="_blank">second</a> post, their world is just as frustrating as yours. Shared understanding this is the key to dealing with it.</p>
<p>So, if your project manager gets upset because their deadlines stretch because you feel some more research is required to determine the best course of action, tell them to read this series from start to finish (whenever it finishes). Chances are they will be squirming with embarrassment way before they have even gotten to this post.</p>
<p>At the end of the day, it is in both your collective interest to keep the stakeholders happy and ensure that the project is successful.</p>
<h2>Conclusion</h2>
<p>This post covered a lot of material, and I appreciate you sticking with me. Judging from the reaction from Joel&#8217;s endorsement of the series, it also seems to have tapped into a common vein of frustration felt by many IT professionals all around the world.</p>
<p>The next post will round off the &quot;people&quot; aspects with an examination of the stakeholder and project sponsor and senior management perspective. Like the developer and infrastructure post, the key is to recognise that their perspective of the world is just as valid as yours, and just as much as you see them misinformed and contributing to a wicked problem scenario, you need to accept the fact that you do not have the full picture either.</p>
<p>Having said that, they get paid way more than we do and therefore that makes them fair game for some serious nailing to the wall <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Roll on part 7!</p>
<p><!--adsense--></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2008/05/12/why-do-sharepoint-projects-fail-part-6/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>&quot;Guru of governance?&quot;</title>
		<link>http://www.cleverworkarounds.com/2008/04/04/guru-of-governance/</link>
		<comments>http://www.cleverworkarounds.com/2008/04/04/guru-of-governance/#comments</comments>
		<pubDate>Thu, 03 Apr 2008 14:44:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[Governance]]></category>
		<category><![CDATA[SDK]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SharePoint]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2008/04/04/guru-of-governance/</guid>
		<description><![CDATA[My old mate from employers yonder, Mike Stringfellow is one of those developers who always liked to take a step back and think through the bigger picture implications of various design/coding decisions. It&#8217;s just a pity that at that particular company we worked at, he was in the minority. (Not helped by some unbelievably poor [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p><!--adsense--></p>
<p>My old mate from employers yonder, <a href="http://www.sharepointblogs.com/mossms/about.aspx" target="_blank">Mike Stringfellow</a> is one of those developers who always liked to take a step back and think through the bigger picture implications of various design/coding decisions. It&#8217;s just a pity that at that particular company we worked at, he was in the minority. (Not helped by some unbelievably poor executive level management wacky views of reality).</p>
<p>So I became one of those bitter and twisted anal infrastructure guys who always seemed to default to &quot;No&quot;, when asked a question. (Usually &quot;no&quot; was the right answer nonetheless). I was told by another colleague that some of the (web) developers were scared of me&#8230; but Mike at least understood why <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>He recently <a href="http://www.sharepointblogs.com/mossms/archive/2008/03/18/making-a-feature-of-spwebconfigmodifications.aspx" target="_blank">blogged the idea</a> of using features to modify web.config file of a web application. After all, the SharePoint SDK offers the WebConfigModifications property (of the SPWebApplication) class. He suggested that as a governance nazi I might have issues with this idea. As it turns out I do, but only for you developers that have been slack-arsed and not done your homework! <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
</p>
<p><span id="more-733"></span></p>
<p>My first question was &quot;Does this apply to all web applications across the SharePoint farm?&quot;. Mike swore on his mother&#8217;s grave that it did (okay, in reality he said &quot;yep&quot;), so at least the modification is consistent (and consistency = less costly governance). So far so good&#8230;</p>
<p>So there is a big, big tick. (Programmers who wonder why I abuse them when they start a sentence with, &quot;Just edit web.config&#8230;&quot;, should really go back to their true calling and instead ask pertinent questions like &quot;do you want fries with that?&quot; <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>So the next question is the squirmy one. Features are applied at 4 <a href="http://msdn2.microsoft.com/en-us/library/ms476615.aspx" target="_blank">scope levels</a>. Farm, Web Application, Site Collection or Site. So here is the spot test:</p>
<p><em><strong>Which scope level do you think this feature should be applied at?</strong></em></p>
<p>If you said &quot;Site&quot; or &quot;Site Collection&quot;, go to the back of the class, you weenie! You are the sort of developer who made me bitter and twisted!&#160; The answer is of course, the Web Application scope!</p>
<p>Web.config is the configuration file for an ASP.NET <strong>web application. </strong>A web application can host <strong>one or more </strong>site collections. <strong>Do not assume that just because you are a site collection administrator, that you have administrative access to the web application hosting your site collection! </strong></p>
<p>If you set the scope of this feature at the site collection level, you are basically allowing a site collection administrator to make a change that affects all other site collections in the web application. Uh &#8211; does the site collection administrator have access to other site collections? Probably not, so why the hell would you allow them to perform a task that impacts on site collections they have no access to? You don&#8217;t &#8211; it breaks the security model.</p>
<p><em>On your dev box, this will likely work fine, because your likely running everything as administrator anyway (double weenie!), but I suspect that in production it probably will break unless your IT guys have poorly configured your farm (triple weenies).</em></p>
<p>What a weenie filled world we live in&#8230;</p>
<p>Anyway, <a href="http://blog.tedpattison.net/Lists/Posts/Post.aspx?ID=4" target="_blank">Ted Pattison</a> is definitely not a weenie. He has <a href="http://blog.tedpattison.net/Lists/Posts/Post.aspx?ID=4" target="_blank">blogged on this topic</a> also and has shown in suitable detail, how to write a web application scoped feature (nice blog BTW Ted you&#8217;re definite blogroll material).</p>
<p>I&#8217;m going to lift one image from Ted&#8217;s blog, just to show you where web application features are enabled. You may have guessed already, that since we shouldn&#8217;t do this at a site collection administrator level, that it is done in SharePoint Central Administration by a user who has farm-level permissions or permissions for the target Web Application. (Best to stick with a farm administrator in general, I believe).</p>
<p>Below is the sample screen-shot from central admin, showing how you can pick a web application and then activate a feature for it.</p>
<p><img height="220" alt="" src="http://blog.tedpattison.net/Lists/Photos/101807_0953_UsingaWebAp5.png" width="536" /></p>
<p>So thanks Mike, I&#8217;ll leave all that XML serialisation stuff to you &#8211; as I only barely got my head around that in the JavaScript series. So long as it&#8217;s web application scope you can do what you like&#8230;</p>
<p><!--adsense--></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2008/04/04/guru-of-governance/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>More SharePoint Branding &#8211; Customisation using JavaScript &#8211; Part 6</title>
		<link>http://www.cleverworkarounds.com/2008/03/12/more-sharepoint-branding-customisation-using-javascript-part-6/</link>
		<comments>http://www.cleverworkarounds.com/2008/03/12/more-sharepoint-branding-customisation-using-javascript-part-6/#comments</comments>
		<pubDate>Wed, 12 Mar 2008 13:09:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[STSDEV]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Web Parts]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2008/03/12/more-sharepoint-branding-customisation-using-javascript-part-6/</guid>
		<description><![CDATA[God help me, I&#8217;m up to part 6 of series about a technology I dislike and still going. For those of you that have just joined us, then you might want to go back to the very beginning of this series where I used JavaScript to improve the SharePoint user experience. Since then, I&#8217;ve been [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p><!--adsense--></p>
<p>God help me, I&#8217;m up to part 6 of series about a technology I dislike and still going. For those of you that have just joined us, then you might want to go back to the very beginning of this series where I used JavaScript to improve the SharePoint user experience. Since then, I&#8217;ve been trying to pick a path through the thorny maze of what you could term, &#8216;sustainable customisation&#8217;. </p>
<p>By that, I mean something that hopefully will not cause you grief and heartache the next time a service pack is applied!</p>
<p>So no mood for jokes this time &#8211; I want to get this over with so let&#8217;s get straight to it and finish this thing!</p>
<p>So where are we at?</p>
<ul>
<li><a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a> looked at how we can use JavaScript to deal with the issue of hiding form elements from the user in lists and document libraries.  </li>
<li><a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a> examined some of the issues with the part 1 JavaScript hacks and wrapped it into a web part using the content editor web part.  </li>
<li><a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a> then examined the various issues of adding this new web part to certain SharePoint pages (NewForm.aspx, EditForm.aspx and DispForm.aspx). I also covered using SharePoint Audience targeting to make the hiding/unhiding of form elements personalised to particular groups of users.  </li>
<li><a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/">Part 4</a> started to address a couple of remaining usability issues, and introduced &#8216;proper&#8217; web-part development using Visual Studio and STSDEV. I created a project to perform the same functionality in part 3, but would not requiring the user to have any JavaScript knowledge or experience.  </li>
<li><a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/">Part 5</a> then used STSDEV to create a solution package that allowed easy debugging, deployment and updating of the web part developed in part 4.</li>
</ul>
<p>So what could we possibly have left to cover? Basically this article will revisit the web part code and make some functionality improvements and then I will cover off some remaining quirks/issues that you should be aware of.</p>
<p>[Quick Navigation: <a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a>, <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a>, <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a>, <a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/">Part 4</a>, <a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/">Part 5</a> and Part 6]</p>
<p><span id="more-725"></span></p>
<h2>Code Enhancement 1 &#8211; Debug Breakpoint</h2>
<p>One thing that can be annoying when using this web part is debugging. A small typo in the list of columns to hide and the functionality can break and be difficult to troubleshoot. I have two enhancements that improve this situation. </p>
<p>The first is very simple. If you add a line like this in your JavaScript code</p>
<pre class="csharpcode">debugger;</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>When script debugging is enabled on your browser, a number of 3rd party debug tools such as <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=2f465be0-94fd-4569-b3c4-dffdf19ccd99&amp;displaylang=en">Microsoft Script Debugger</a>, <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfp2k2/html/odc_fpdebugscripts.asp">Microsoft Script Editor</a>, <a href="http://www.gotdotnet.com/team/csharp/learn/whitepapers/How%20to%20debug%20script%20in%20Visual%20Studio%20.Net.doc">Visual Studio.Net</a> and <a href="http://www.mozilla.org/projects/venkman/">Venkman</a> will treat this as a breakpoint and allow you to step through the code and perform client side debugging. This is handy of course, so wouldn&#8217;t it be nice for the web part to have a property that enables a breakpoint?</p>
<p>The code for this is insanely easy. We define a boolean property in our web part that optionally outputs the line &#8216;debugger;&#8217; just before the rest of our code runs. Using the XML Serialisation as described in Part 5, we can expose this property as a checkbox in the web part properties when used in SharePoint.</p>
<p>Below is a code sample of the property and its use.</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">bool</span> _breakpoint;

<span class="rem">// Create a custom category in the property sheet.</span>
[Category(<span class="str">"Custom Properties"</span>)]
[Personalizable(PersonalizationScope.Shared)]
[WebDisplayName(<span class="str">"Enable Breakpoint?"</span>)]
[WebDescription(<span class="str">"Add's breakpoints to Javascript code for script debuggers"</span>)]
[WebBrowsable(<span class="kwrd">true</span>)]
[XmlElement(ElementName = <span class="str">"BreakPoint"</span>)]
<span class="kwrd">public</span> <span class="kwrd">bool</span> BreakPoint {
    get
    {
        <span class="kwrd">return</span> _breakpoint;
    }
    set
    {
        _breakpoint = <span class="kwrd">value</span>;
    }
 }
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>In the render method, where applicable, we then add this line</p>
<pre class="csharpcode"><span class="kwrd">if</span> (_breakpoint)
{
      output.WriteLine(<span class="str">"   debugger;"</span>);
}
</pre>
<p>So after rebuilding and redeploying this project using STSDEV, the web part properties now reflect this new property.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image26.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="220" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb26.png" width="244" border="0"/></a> </p>
<p>Check the &#8220;Enable BreakPoint&#8221; box and click okay. If your browser has script debugging enabled (found in Internet Options/Advanced tab in IE), you will be prompted to launch a debugger then the breakpoint is executed. Below you can see both the IE property page that controls script debugging and the prompt to debug the page when Visual Studio is installed. </p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image27.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="215" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb27.png" width="326" border="0"/></a>&nbsp;<a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image28.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="290" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb28.png" width="269" border="0"/></a> </p>
<p>Choose a new Instance of Visual Studio and you will then be able to see and step through the JavaScript code as shown below</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image29.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="296" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb29.png" width="551" border="0"/></a> </p>
<h2>Code Enhancement 2 &#8211; Debug Log Window</h2>
<p>Sometimes, you will not have the benefit of being able to use a JavaScript debugger and you need a simpler method to display debug information. How about we add a debug log window that can conditionally be invoked when it is enabled in the web part properties?</p>
<p>Fortunately for us, <a href="http://ajaxcookbook.org/javascript-debug-log/">Bret Taylor</a> has done the hard work for us with a complete JavaScript debug log function. </p>
<p>So in JavaScript code, we can for example, add a line like:</p>
<pre class="csharpcode">log(<span class="str">"This is log message "</span>);</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>So once again, we can set this as a boolean property. If the property is set to true, the webpart can write the JavaScript log function to the browser and then call that function at various places in the rest of our code.</p>
<p>Below is a code sample of the property and its use</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">bool</span> _DebugLogWindow;

[Category(<span class="str">"Custom Properties"</span>)]
[DefaultValue(<span class="kwrd">false</span>)]
[Personalizable(PersonalizationScope.Shared)]
[WebDisplayName(<span class="str">"Use Debug Log Window?"</span>)]
[WebDescription(<span class="str">"Select to set value to True."</span>)]
[WebBrowsable(<span class="kwrd">true</span>)]
[XmlElement(ElementName = <span class="str">"DebugLogWindow"</span>)]
<span class="rem">// The accessor for this property.</span>
<span class="kwrd">public</span> <span class="kwrd">bool</span> DebugLogWindow
{
    get
    {
        <span class="kwrd">return</span> _DebugLogWindow;
    }
    set
    {
        _DebugLogWindow = <span class="kwrd">value</span>;
    }
}</pre>
<p>The next section of code outputs the log function itself. I know this looks ugly but thats what you get when using one programming language to write the code of another.</p>
<pre class="csharpcode" style="width: 656px; height: 393px"><span class="kwrd">if</span> (_DebugLogWindow)
{
    output.WriteLine(<span class="str">@"function log(message) {"</span>);
    output.WriteLine(<span class="str">@"if (!log.window_ || log.window_.closed) { "</span>);
    output.WriteLine(<span class="str">@"   var win = window.open("</span><span class="str">""</span><span class="str">", null, "</span><span class="str">"width=400,height=200,"</span><span class="str">" + "</span>);
    output.WriteLine(<span class="str">@"   "</span><span class="str">"scrollbars=yes,resizable=yes,status=no,"</span><span class="str">" + "</span>);
    output.WriteLine(<span class="str">@"   "</span><span class="str">"location=no,menubar=no,toolbar=no"</span><span class="str">"); "</span>);
    output.WriteLine(<span class="str">@"   if (!win) return; "</span>);
    output.WriteLine(<span class="str">@"        var doc = win.document; "</span>);
    output.WriteLine(<span class="str">@"        doc.write("</span><span class="str">"&lt;html&gt;&lt;head&gt;&lt;title&gt;Debug Log&lt;/title&gt;&lt;/head&gt;"</span><span class="str">" +"</span>);
    output.WriteLine(<span class="str">@"        "</span><span class="str">"&lt;body&gt;&lt;/body&gt;&lt;/html&gt;"</span><span class="str">"); "</span>);
    output.WriteLine(<span class="str">@"   doc.close(); "</span>);
    output.WriteLine(<span class="str">@"   log.window_ = win; "</span>);
    output.WriteLine(<span class="str">@"   }"</span>);
    output.WriteLine(<span class="str">@"   var logLine = log.window_.document.createElement("</span><span class="str">"div"</span><span class="str">"); "</span>);
    output.WriteLine(<span class="str">@"   logLine.appendChild(log.window_.document.createTextNode(message)); "</span>);
    output.WriteLine(<span class="str">@"   log.window_.document.body.appendChild(logLine); "</span>);
    output.WriteLine(<span class="str">@"}"</span>);
 }
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>So all we need now is to invoke this function in sections of code where debug output would be useful. For example:</p>
<pre class="csharpcode"><span class="kwrd">if</span> (_DebugLogWindow)
{
     output.WriteLine(<span class="str">"    log(\"We have "</span> + _fieldlist.Length + <span class="str">" fields to hide \" ); "</span>);
}
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>So let&#8217;s rebuild and redeploy these changes and see the effect.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image30.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb30.png" width="231" border="0"/></a> </p>
<p>The screen grab below shows the result of enabling this setting. We now have a second browser window spawned that logs to the screen all information passed to the log() function.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image31.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="348" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb31.png" width="603" border="0"/></a></p>
<p>&nbsp;</p>
<h2>Code Enhancement 3 &#8211; Hide Control by ID</h2>
<p>I cannot take the credit for this enhancement. I originally packaged up an early version of the web part for <a href="http://wss.made4the.net/default.aspx">Jeremy Thake</a>, a former colleague of mine to test on his environment before I published part 5 of this series. He in return sent me back another JavaScript function to hide based on HTML element ID&#8217;s.</p>
<p>Way back in Part 1, I described the JavaScript built-in method <a href="http://www.java2s.com/Code/JavaScriptReference/Javascript-Methods/getElementsByTagName.htm">getElementsByTagName</a>. Jeremy is using the function <a href="http://www.java2s.com/Code/JavaScriptReference/Javascript-Methods/getElementById.htm">getElementByID</a>. This function works on the assumption that HTML elements are assigned an optional ID attribute. e.g</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">div</span> <span class="attr">id</span><span class="kwrd">="CleverWorkarounds1"</span>
     <span class="attr">style</span><span class="kwrd">="position:absolute; width:500px; height:150px; visibility: visible"</span><span class="kwrd">&gt;</span>
some DIV tag
<span class="kwrd">&lt;/</span><span class="html">div</span><span class="kwrd">&gt;</span>
</pre>
<p>If you look in SharePoint HTML source, you will see that this is the case.Take for example this particularly feral HTML element for the CLOSE button.</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">input</span> <span class="attr">type</span><span class="kwrd">="button"</span> <span class="attr">name</span><span class="kwrd">="ctl00$m$g_100fd177_99ab_4755_a1d3_f064360d4317$ctl00$toolBarTbltop$RightRptControls$ctl02$ctl00$diidIOGoBack"</span>
   <span class="attr">value</span><span class="kwrd">="Close"</span>
   <span class="attr">id</span><span class="kwrd">="ctl00_m_g_100fd177_99ab_4755_a1d3_f064360d4317_ctl00_toolBarTbltop_RightRptControls_ctl02_ctl00_diidIOGoBack"</span>
   <span class="attr">class</span><span class="kwrd">="ms-ButtonHeightWidth"</span> <span class="attr">target</span><span class="kwrd">="_self"</span>
 <span class="kwrd">/&gt;</span>
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>So this button can be referenced by the following ID.:</p>
<pre class="csharpcode" style="width: 656px; height: 45px">document.getElementById(<span class="str">'ctl00_m_g_100fd177_99ab_4755_a1d3_f064360d4317_ctl00_toolBarTbltop_RightRptControls_ctl02_ctl00_diidIOGoBack'</span>).style.display=<span class="str">"none"</span>; </pre>
<p>Below is a code sample of the property and its use</p>
<pre class="csharpcode" style="width: 664px; height: 388px"><span class="kwrd">private</span> <span class="kwrd">string</span> _HideFieldByIdList;

<span class="rem">// Create a custom category in the property sheet.</span>
[Category(<span class="str">"Custom Properties"</span>)]
[Personalizable(PersonalizationScope.Shared)]
[WebDisplayName(<span class="str">"List of HTML element IDs to hide on this page"</span>)]
[WebDescription(<span class="str">"Comma delimited list of HTML element IDs to hide on this page"</span>)]
[WebBrowsable(<span class="kwrd">true</span>)]
[XmlElement(ElementName = <span class="str">"HideFieldByIdList"</span>)]
<span class="kwrd">public</span> <span class="kwrd">string</span> HideFieldByIdList
{
    get
    {
        <span class="kwrd">return</span> _HideFieldByIdList;
    }
    set
    {
        _HideFieldByIdList = <span class="kwrd">value</span>;
    }
}</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>Next up, we have the function written by Jeremy (along with some debug log lines added by me)</p>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<pre class="csharpcode" style="width: 656px; height: 515px"><span class="kwrd">if</span> (HideFieldByIdList != <span class="kwrd">null</span> || HideFieldByIdList != <span class="str">""</span>)
{
     <span class="kwrd">if</span> (_DebugLogWindow)
    {
        output.WriteLine(<span class="str">"    log(\"Calling function hideFieldsById\" ); "</span>);
    }
    output.WriteLine();
    output.WriteLine(<span class="str">"function hideFieldsById() { "</span>);
    _fieldlist = HideFieldByIdList.Split(<span class="str">','</span>);
    <span class="kwrd">if</span> (_fieldlist != <span class="kwrd">null</span>)&nbsp;&nbsp; {
        <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; _fieldlist.Length; i++)
        {
            <span class="kwrd">if</span> (_fieldlist[i] != <span class="str">""</span>)
            {
                <span class="kwrd">if</span> (_DebugLogWindow)
                {
                     output.WriteLine(<span class="str">"    log(\"Looking for ID "</span> + _fieldlist[i] + <span class="str">"\" ); "</span>);
                }
                 output.WriteLine(<span class="str">"document.getElementById('"</span> + _fieldlist[i] + <span class="str">"').style.display=\"none\";"</span>);
             }
         }
    }
    output.WriteLine(<span class="str">" }"</span>);
    output.WriteLine();
}</pre>
<p>So let&#8217;s test this! Redeploy the project and let&#8217;s hide the Close button on DispForm.aspx</p>
<p>Before screen-shot!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image32.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="261" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb32.png" width="509" border="0"/></a> .</p>
<p>Add the ID of the &#8220;Close&#8221; button</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image33.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="337" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb33.png" width="233" border="0"/></a> </p>
<p>After screen-shot! Wohoo!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image34.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="265" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb34.png" width="517" border="0"/></a> </p>
<h2>Quirks and Issues</h2>
<p>We are almost home after 6 posts in this series! No more coding for now as I think we have demonstrated enough of this idea. You can see how this can be used and extended quite easily.</p>
<p>There are a couple of minor points that I think are worth pointing out. One issue I covered back in my <a href="http://www.cleverworkarounds.com/2007/10/27/sharepoint-branding-part-5-%E2%80%93-feature-improvements-and-bugs/">first branding series</a>. If you deactivate this feature, the web part will not be removed from the web part library. </p>
<p>“That is by design. Deactivation of features does not remove data that was created when the feature was activated. if you want to “clean up” the data that was created, you need to create a Feature receiver handler and have the FeatureDeactivating() event handler manually remove the file.”
</p>
<p>and
</p>
<p>“Keep in mind though, data is left in SharePoint BY DESIGN. What would happen if you had deployed a page layout with a Feature and someone removed it while it was in use by thousands of pages? Oops… blamo!”
</p>
<p>So now that we know that the web part will not be deleted, let&#8217;s see what happens when we modify it. Here is the web part as it was installed by the STSDEV solution. </p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image35.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="369" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb35.png" width="483" border="0"/></a> </p>
<p>Now let&#8217;s do a flashback and modify WebPart.XML in our Visual Studio Project. I have modified the Title property to &#8220;CleverWorkArounds Hide Column1 Web Part&#8221;</p>
<pre class="csharpcode" style="width: 656px; height: 235px"><span class="kwrd">&lt;?</span><span class="html">xml</span> <span class="attr">version</span><span class="kwrd">="1.0"</span> <span class="attr">encoding</span><span class="kwrd">="utf-8"</span>?<span class="kwrd">&gt;</span>
<span class="rem">&lt;!--Created by STSDEV at 7/03/2008 11:34:05 PM--&gt;</span>
<span class="kwrd">&lt;</span><span class="html">Elements</span> <span class="attr">xmlns</span><span class="kwrd">="http://schemas.microsoft.com/sharepoint/"</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Module</span> <span class="attr">Name</span><span class="kwrd">="CleverWorkAroundsHideFields"</span> <span class="attr">List</span><span class="kwrd">="113"</span> <span class="attr">Url</span><span class="kwrd">="_catalogs/wp"</span> <span class="attr">Path</span><span class="kwrd">="WebParts"</span> <span class="attr">RootWebOnly</span><span class="kwrd">="True"</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">File</span> <span class="attr">Url</span><span class="kwrd">="CleverWorkAroundsHideFields.webpart"</span> <span class="attr">Type</span><span class="kwrd">="GhostableInLibrary"</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">Property</span> <span class="attr">Name</span><span class="kwrd">="Group"</span> <span class="attr">Value</span><span class="kwrd">="CleverWorkArounds"</span> <span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">Property</span> <span class="attr">Name</span><span class="kwrd">="Description"</span> <span class="attr">Value</span><span class="kwrd">="Web part to selectively hide columns via JavaScript"</span><span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">Property</span> <span class="attr">Name</span><span class="kwrd">="Title"</span> <span class="attr">Value</span><span class="kwrd">="CleverWorkArounds Hide Column1 Web Part"</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">File</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Module</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Elements</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>So let&#8217;s redeploy the solution, and even manually deactivate and reactivate the feature as well. When we re-examine the web part in the gallery, <strong>the change is not reflected</strong>.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image36.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="176" alt="image" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb36.png" width="548" border="0"/></a> </p>
<p>Another inconsistency (although not a major one), is that the &#8220;Description&#8221; property is ignored completely. If you look at the Webpart.XML screen-shot above, you will notice I have set the Description property to &#8220;<span class="html">Property</span> <span class="attr">Name</span><span class="kwrd">=&#8221;Description&#8221;</span> <span class="attr">Value</span><span class="kwrd">=&#8221;Web part to selectively hide columns via JavaScript</span>&#8220;.</p>
<p>But look at the web part properties above. The description is &#8220;A demo Web Part created by stsdev&#8221;.</p>
<p>I assume this is a bug with STSDEV, but in any event, its pretty minor and I can live with it.</p>
<h2>Conclusion</h2>
<p>Well gawddammit, I am finally done with JavaScript! But to round off this series, let&#8217;s summarise what we have achieved.</p>
<ul>
<li>No programming skills necessary
</li>
<li>No unghosting of Web Part pages
</li>
<li>Easy debug logging
</li>
<li>Leverage audience based content delivery
</li>
<li>Eliminated the requirement for SharePoint Designer
</li>
<li>Packaged up the functionality into an easy to deploy solution</li>
</ul>
<p>I am well pleased, and I hope that you found some useful nuggets of information in this post. </p>
<p>I still hate JavaScript, but at least here we are using it in a sustainable customisation manner. <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Bye for now</p>
<p>Paul</p>
<p><!--adsense--></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2008/03/12/more-sharepoint-branding-customisation-using-javascript-part-6/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>More SharePoint Branding &#8211; Customisation using Javascript &#8211; Part 5</title>
		<link>http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/</link>
		<comments>http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/#comments</comments>
		<pubDate>Sun, 09 Mar 2008 11:24:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[Governance]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[STSDEV]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Web Parts]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/</guid>
		<description><![CDATA[Hello and welcome to part 5 of another epic CleverWorkArounds blog post. If you think I write a lot on my blog, you should see my documentation and training material! I seem to be rare insofar as I actually like to write documentation and can churn out reasonable quality pretty fast. So if you need [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p>Hello and welcome to part 5 of another epic CleverWorkArounds blog post.</p>
<p>If you think I write a lot on my blog, you should see my documentation and training material! I seem to be rare insofar as I actually like to write documentation and can churn out reasonable quality pretty fast. So if you need your scary SharePoint farm/infrastructure audited and fully documented, you <a href="http://www.cleverworkarounds.com/about/">know who to call</a>! <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Anyhow, here is the current state of play.</p>
<ul>
<li><a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a> of this series looked at how we can use JavaScript to deal with the common request of hiding form elements from the user in lists and document libraries. We looked at a Microsoft documented method, then a better, more flexible method.</li>
<li><a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a> wrapped this JavaScript code into a web part which has been loaded into the SharePoint web part gallery.</li>
<li><a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a> then examined the trials and tribulations of getting this new web part added to certain SharePoint pages (NewForm.aspx, EditForm.aspx and DispForm.aspx), and then with a few simple edits, use this web part to hide form fields as desired. Finally, I demonstrated the power of combining this with SharePoint Audiences targeting functionality to make the hiding/unhiding of form elements personalised to particular groups of users.</li>
<li><a target="_blank" href="http://http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/">Part 4</a> introduced Visual Studio and STSDEV. I created a project to perform the same functionality in part 3, but not requiring any JavaScript knowledge or experience. By the end of part 4 I had a STSDEV project that compiled with no errors.</li>
</ul>
<p>And now we are onto Part 5 where we turn our attention to the packaging and deployment of our web part. As you are about to see, STSDEV makes this a very quick and painless experience. If you aren&#8217;t convinced of the merits of STSDEV and the SharePoint solution framework by the time you finish this article, then I don&#8217;t know what will convince you.</p>
<p>[Quick Navigation: <a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a>, <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a>, <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a>, <a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/">Part 4</a> and <a href="http://http://www.cleverworkarounds.com/2008/03/12/more-sharepoint-branding-customisation-using-javascript-part-6/">Part 6</a>]</p>
<p><span id="more-701"></span></p>
<p>So, for those of you that want to see the complete source code for an easy cut and paste into your own project, I have listed it below.</p>
<pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Web;
<span class="kwrd">using</span> System.Web.UI;
<span class="kwrd">using</span> System.Web.UI.WebControls;
<span class="kwrd">using</span> System.Web.UI.WebControls.WebParts;         

<span class="kwrd">using</span> System.Xml.Serialization;
<span class="kwrd">using</span> System.ComponentModel;         

<span class="kwrd">namespace</span> CleverWorkAroundsHideFields {         

  [XmlRoot(Namespace = <span class="str">"CleverWorkAroundsHideFields"</span>)]
  <span class="kwrd">public</span> <span class="kwrd">class</span> CleverWorkAroundsHideFields : WebPart {         

      <span class="kwrd">private</span> <span class="kwrd">string</span> _HideFieldList;
      <span class="kwrd">private</span> <span class="kwrd">string</span>[] _fieldlist;         

      <span class="rem">// Create a custom category in the property sheet.</span>
      [Category(<span class="str">"Custom Properties"</span>)]
      [Personalizable(PersonalizationScope.Shared)]
      [WebDisplayName(<span class="str">"List of columns to hide on this page"</span>)]
      [WebDescription(<span class="str">"Comma delimited list of columns to hide on this page"</span>)]
      [WebBrowsable(<span class="kwrd">true</span>)]
      [XmlElement(ElementName = <span class="str">"HideFieldList"</span>)]
      <span class="kwrd">public</span> <span class="kwrd">string</span> HideFieldList
      {
          get
          {
              <span class="kwrd">return</span> _HideFieldList;
          }
          set
          {
              _HideFieldList = <span class="kwrd">value</span>;
          }
      }         

      <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Render(HtmlTextWriter output)
      {         

          <span class="rem">// Now lets extract the list of fields from the web part properties</span>
          <span class="kwrd">if</span> (HideFieldList != <span class="kwrd">null</span>)
          {
              _fieldlist = HideFieldList.Split(<span class="str">','</span>);         

              <span class="rem">// javascript inside C# - ugh </span>
              <span class="rem">// I know this looks ugly on account of the escaped quotes. </span>
              <span class="rem">// First section is the findacontrol function</span>         

              output.WriteLine();
              output.WriteLine(<span class="str">@"&lt;script language="</span><span class="str">"javascript"</span><span class="str">" type="</span><span class="str">"text/javascript"</span><span class="str">"&gt;  "</span>);
              output.WriteLine();
              output.WriteLine(<span class="str">@"_spBodyOnLoadFunctionNames.push("</span><span class="str">"hideFields"</span><span class="str">")  "</span>);
              output.WriteLine(<span class="str">@"function findacontrol(FieldName) {  "</span>);
              output.WriteLine(<span class="str">@"var arr = document.getElementsByTagName("</span><span class="str">"!"</span><span class="str">");  //get all comments "</span>);
              output.WriteLine(<span class="str">@"for (var i=0;i &lt; arr.length; i++ ) {   "</span>);
              output.WriteLine(<span class="str">@"   // now match the field name  "</span>);
              output.WriteLine(<span class="str">@"   if (arr[i].innerHTML.indexOf(FieldName) &gt; 0) { "</span>);
              output.WriteLine(<span class="str">@"      return arr[i]; "</span>);
              output.WriteLine(<span class="str">@"   } "</span>);
              output.WriteLine(<span class="str">@"  } "</span>);
              output.WriteLine(<span class="str">@"}"</span>);
              output.WriteLine();
              output.WriteLine();         

              <span class="rem">// Now the hidefields function, which loops for each field to be hidden</span>         

              output.WriteLine(<span class="str">"function hideFields() { "</span>);
              output.WriteLine(<span class="str">"   var control; "</span>);         

              <span class="kwrd">if</span> (_fieldlist != <span class="kwrd">null</span>)
              {
                  <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; _fieldlist.Length; i++)
                  {
                      output.Write(<span class="str">"    control = findacontrol(\""</span>);
                      output.Write(_fieldlist[i]);
                      output.WriteLine(<span class="str">"\" ); "</span>);
                      output.WriteLine(<span class="str">"   control.parentNode.parentNode.style.display=\"none\""</span>);
                  }
              }
              output.WriteLine(<span class="str">" }"</span>);         

              output.WriteLine(<span class="str">"&lt;/script&gt;"</span>);
          } <span class="rem">// if</span>
      } <span class="rem">// method</span>         

   }
}</pre>
<style type="text/css">                  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>Now, let&#8217;s focus back on our STSDEV generated Visual Studio solution and make a couple of changes, to properly package up our code.</p>
<h2>Edit 1: Feature.XML</h2>
<p>You will find Feature.XML under RootFiles\TEMPLATE\Features\CleverWorkAroundsHideFields</p>
<p>In this example, I have modified the Title, Description and ImageUrl attributes of the &lt;Feature&gt; element of Feature.xml to give more meaningful, friendly descriptive text. The default image has been renamed to macgyver.jpg and you will soon see why <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<pre style="width: 656px; height: 310px" class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Feature</span>
  <span class="attr">Id</span><span class="kwrd">="8C39BCDB-9361-4412-950C-5ADE30AFF14E"</span>
<strong>  <span class="attr">Title</span><span class="kwrd">="CleverWorkArounds: JavaScript Hidden Column Manager"</span>
  <span class="attr">Description</span><span class="kwrd">="This SharePoint solution can be used to hide columns from DispForm.apsx, EditFormaspx, NewForm.aspx as well as custom web part pages. (<a href="http://www.cleverworkarounds.com)">http://www.cleverworkarounds.com)"</a></span>
</strong>  <span class="attr">Version</span><span class="kwrd">="1.0.0.0"</span>
  <span class="attr">Scope</span><span class="kwrd">="Site"</span>
  <span class="attr">Hidden</span><span class="kwrd">="false"</span>
<strong>  <span class="attr">ImageUrl</span><span class="kwrd">="CleverWorkAroundsHideFields\macgyver.jpg"</span> <span class="attr">xmlns</span><span class="kwrd">="http://schemas.microsoft.com/sharepoint/"</span><span class="kwrd">&gt;</span>
</strong>  <span class="kwrd">&lt;</span><span class="html">ElementManifests</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">ElementManifest</span>
      <span class="attr">Location</span><span class="kwrd">="WebParts.xml"</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">ElementFile</span>
      <span class="attr">Location</span><span class="kwrd">="WebParts\CleverWorkAroundsHideFields.webpart"</span> <span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">ElementManifests</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Feature</span><span class="kwrd">&gt;</span></pre>
<h2>Edit 2. Custom Icon Image</h2>
<p>I decided that if I am going to create a SharePoint Feature with an icon, I&#8217;d have to use something that captures the very essence of the &#8220;clever workaround&#8221;. When you think about it, can it be anybody but <a href="http://humorsection.blogspot.com/2006/08/funny-picture-macgyver.html">MacGyver</a>?</p>
<p><embed wmode="transparent" height="355" width="425" src="http://www.youtube.com/v/lnScL6o8Egs"></embed></p>
<p>[if you see a broken image above then your IT staff are being anal and blocking YouTube - sorry]</p>
<p>Ahhh- the memories..  *ahem*, focus Paul &#8211; back to the post.</p>
<p>So, I have a small picture of MacGyver called oddly enough, MacGyver.jpg. I have placed this file into the RootFiles\TEMPLATE\IMAGES folder in my STSDEV project as shown below.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image10.png"><img border="0" width="500" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb10.png" alt="image" height="147" style="border-width: 0px" /></a></p>
<p>Now in Visual Studio, I have added this image to the project.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image11.png"><img border="0" width="243" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb11.png" alt="image" height="146" style="border: 0px" /></a> <a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image12.png"><img border="0" width="395" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb12.png" alt="image" height="255" style="border: 0px" /></a></p>
<p>As you can see below, now macgyver.jpg is listed along with the default STSDEV image. You can delete the default image AfricanPith32.gif as we will not be needing it.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image13.png"><img border="0" width="320" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb13.png" alt="image" height="279" style="border-width: 0px" /></a></p>
<h2>Edit 3. WebParts.XML</h2>
<p>You will find WebParts.XML under RootFiles\TEMPLATE\Features\CleverWorkAroundsHideFields</p>
<p>In this example, I have modified the &lt;File&gt; element of WebParts.XML, modified the property element named &#8220;Group&#8221;, as well as added in a Description and Title property also. This XML file uses the &lt;File&gt; directive to put our web part into the web part gallery for any site collection where the feature is activated.</p>
<pre style="width: 656px; height: 199px" class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Elements</span> <span class="attr">xmlns</span><span class="kwrd">="http://schemas.microsoft.com/sharepoint/"</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Module</span> <span class="attr">Name</span><span class="kwrd">="CleverWorkAroundsHideFields"</span> <span class="attr">List</span><span class="kwrd">="113"</span> <span class="attr">Url</span><span class="kwrd">="_catalogs/wp"</span> <span class="attr">Path</span><span class="kwrd">="WebParts"</span> <span class="attr">RootWebOnly</span><span class="kwrd">="True"</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">File</span> <span class="attr">Url</span><span class="kwrd">="CleverWorkAroundsHideFields.webpart"</span> <span class="attr">Type</span><span class="kwrd">="GhostableInLibrary"</span><span class="kwrd">&gt;</span>
      <strong><span class="kwrd">&lt;</span><span class="html">Property</span> <span class="attr">Name</span><span class="kwrd">="Group"</span> <span class="attr">Value</span><span class="kwrd">="CleverWorkArounds"</span> <span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">Property</span> <span class="attr">Name</span><span class="kwrd">="Description"</span> <span class="attr">Value</span><span class="kwrd">="Web part to selectively hide columns via JavaScript"</span><span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">Property</span> <span class="attr">Name</span><span class="kwrd">="Title"</span> <span class="attr">Value</span><span class="kwrd">="CleverWorkArounds Hide Column Web Part"</span><span class="kwrd">/&gt;</span>
</strong>    <span class="kwrd">&lt;/</span><span class="html">File</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Module</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Elements</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">                  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<h2>Let&#8217;s build it!</h2>
<p>Right! If you have made it this far, then let&#8217;s do a final build using &#8220;DebugBuild&#8221; configuration. If it all compiles, we are ready to test a deployment to our development server.</p>
<p>Now you will get to see why STSDEV is such a damn useful tool. In the drop down window shown below, choose &#8220;DebugDeploy&#8221; as the build option, and then press F6 or build the solution via the &#8220;Build&#8221; menu.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image14.png"><img border="0" width="244" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb14.png" alt="image" height="157" style="border-width: 0px" /></a></p>
<p>Below is the output of the build. Look closely at the annotated output below. The web part has been packaged up into a SharePoint solution, the solution has been added to the SharePoint solution store and then activated for all web applications. (look mum, no hands!)</p>
<p><font size="2" face="Courier New">&#8212;&#8212; Build started: Project: CleverWorkAroundsHideFields, Configuration: DebugDeploy Any CPU &#8212;&#8212;<br />
c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Csc.exe /noconfig /nowarn:1701,1702 /reference:&#8221;C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\Microsoft.SharePoint.dll&#8221; /reference:c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Web.dll /reference:c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /keyfile:KeyFile.snk /out:obj\DebugDeploy\CleverWorkAroundsHideFields.dll </font></p>
<p><font size="2"><strong><em>*** The above output is the command used by Visual Studio to compile the web part DLL.</em></strong></font></p>
<p><font size="2" face="Courier New">Compile complete &#8212; 0 errors, 0 warnings<br />
CleverWorkAroundsHideFields -&gt; C:\VSPROJ\CleverWorkArounds\CleverWorkAroundsHideFields\bin\Debug\CleverWorkAroundsHideFields.dll<br />
Refreshing Deployment Files&#8230;<br />
&#8220;C:\Program Files\Common Files\stsdev.exe&#8221; /refresh CleverWorkAroundsHideFields C:\VSPROJ\CleverWorkArounds\CleverWorkAroundsHideFields\ </font></p>
<p><font size="2" face="ari"><strong><em>*** STSDEV now runs and updates some of the other files in the solution required to deploy this web part (completely hands off for the developer which is great)</em></strong></font></p>
<p><font size="2" face="Courier New">STSDEV &#8211; Simple Tools for SharePoint Developers<br />
Refreshing Solution Package Files<br />
Current Solution Name:<br />
Current Solution Directory:<br />
Refreshing deployment files&#8230;<br />
Rebuilding DeploymentFiles\manifest.xml<br />
Rebuilding DeploymentFiles\SolutionPackage.ddf<br />
Deleting Solution Package File&#8230;<br />
Building Solution Package (Debug Version)<br />
&#8220;C:\Windows\System32\makecab.exe&#8221; /F DeploymentFiles\SolutionPackage.ddf /D CabinetNameTemplate=CleverWorkAroundsHideFields.wsp<br />
Microsoft (R) Cabinet Maker &#8211; Version 5.2.3790.0<br />
Copyright (c) Microsoft Corporation. All rights reserved.. </font></p>
<p><font size="2" face="Courier New">Parsing directives<br />
Parsing directives (DeploymentFiles\SolutionPackage.ddf: 1 lines)<br />
20,812 bytes in 6 files                                         <br />
Executing directives<br />
  0.00% &#8211; manifest.xml (1 of 6)<br />
  0.00% &#8211; CleverWorkAroundsHideFields.dll (2 of 6)<br />
  0.00% &#8211; CleverWorkAroundsHideFields\feature.xml (3 of 6)<br />
  0.00% &#8211; CleverWorkAroundsHideFields\WebParts.xml (4 of 6)<br />
  0.00% &#8211; CleverWorkAroundsHideFields\WebParts\CleverWorkAroundsHideFields.webpart (5 of 6)<br />
  0.00% &#8211; IMAGES\CleverWorkAroundsHideFields\macgyver.jpg (6 of 6)                        <br />
100.00% [flushing current folder]<br />
Total files:              6     <br />
Bytes before:        20,812<br />
Bytes after:          4,955<br />
After/Before:            23.81% compression<br />
Time:                     0.02 seconds ( 0 hr  0 min  0.02 sec)<br />
Throughput:            1354.95 Kb/second<br />
</font></p>
<p><font size="2" face="ari"><strong><em>*** STSDEV now builds the web part and supporting files into a SharePoint solution (WSP) file called CleverWorkAroundsHideFields.wsp</em></strong></font></p>
<p><font size="2" face="Courier New">Installing Solution&#8230;<br />
&#8220;C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\stsadm.exe&#8221; -o addsolution -filename DeploymentFiles\CleverWorkAroundsHideFields.wsp </font></p>
<p><font size="2" face="Courier New">Operation completed successfully. </font></p>
<p><strong><font size="2" face="ari"><em>*** Now we use the SharePoint Admin tool STSADM to add the solution file CleverWorkAroundsHideFields.wsp to the SharePoint solution store. This creates a SharePoint timer job to actually perform this task. </em></font></strong></p>
<p><font size="2" face="Courier New">&#8220;C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\stsadm.exe&#8221; -o execadmsvcjobs </font></p>
<p><font size="2" face="Courier New">Executing .<br />
Operation completed successfully. </font></p>
<p><strong><em><font size="2">*** Now we have forced SharePoint to execute all outstanding timer jobs, thereby forcing the solution to be added to the store</font></em></strong></p>
<p><font size="2" face="Courier New">Deploying Solution&#8230;<br />
&#8220;C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\stsadm.exe&#8221; -o deploysolution -name CleverWorkAroundsHideFields.wsp -immediate -allowgacdeployment -allcontenturls </font></p>
<p><font size="2" face="Courier New">Timer job successfully created. </font></p>
<p><font size="2" face="Courier New">&#8220;C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\stsadm.exe&#8221; -o execadmsvcjobs </font></p>
<p><font size="2" face="Courier New">Executing .<br />
Executing solution-deployment-cleverworkaroundshidefields.wsp-0.<br />
The solution-deployment-cleverworkaroundshidefields.wsp-0 job completed successfully, but could not be properly cleaned up.  This job may execute again on this server.<br />
Operation completed successfully. </font></p>
<p><font size="2"><strong><em>*** These last two steps activated the uploaded solution using STSADM and then once again, executed all outstanding timer jobs. Note that in our example here, the final timer jobs had an error.</em></strong></font></p>
<h2>Verifying Successful Deployment</h2>
<p>We can verify what the above log is telling us by navigating to Solution Management in SharePoint Central Administration. So let&#8217;s take a look! As reported in this log, there was an error. Note the cleverworkaroundshidefields.wsp status in in an &#8220;Error State&#8221;</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image15.png"><img border="0" width="599" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb15.png" alt="image" height="155" style="border-width: 0px" /></a></p>
<h2>Error? Oh no! What to do?</h2>
<p>So for some reason, we have had a deployment error. So let&#8217;s retract this solution from SharePoint and perform an IISReset.</p>
<p>This action can be performed within Visual Studio thanks the the STSDEV functionality. Change the build type to a &#8220;DebugRetract&#8221; and press F6 or perform a build via the &#8220;Build&#8221; menu.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image16.png"><img border="0" width="236" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb16.png" alt="image" height="184" style="border-width: 0px" /></a></p>
<p>This time the log is much simpler, because we are not actually compiling our code this time. Instead, we are running the STSADM commands to retract this problematic solution.</p>
<p><font face="Courier New">&#8212;&#8212; Build started: Project: CleverWorkAroundsHideFields, Configuration: DebugRetract<br />
&#8220;C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\stsadm.exe&#8221; -o retractsolution -name CleverWorkAroundsHideFields.wsp -immediate -allcontenturls </font></p>
<p><font face="Courier New">Timer job successfully created. </font></p>
<p><font face="Courier New">&#8220;C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\stsadm.exe&#8221; -o execadmsvcjobs </font></p>
<p><font face="Courier New">Executing .<br />
Executing solution-deployment-cleverworkaroundshidefields.wsp-0.<br />
Operation completed successfully. </font></p>
<p><font face="Courier New">========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ========== </font></p>
<p>So now I perform an IISReset, and then attempt to redeploy the solution again.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image17.png"><img border="0" width="160" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb17.png" alt="image" height="159" style="border: 0px" /></a></p>
<p>For the sake of readability, I have omitted most of the build log this time.</p>
<p><font face="Courier New">&#8212;&#8212; Build started: Project: CleverWorkAroundsHideFields, Configuration: DebugDeploy</font></p>
<p><font face="Courier New"><strong>[snip lots of log output]</strong></font></p>
<p><font face="Courier New">Executing .<br />
Executing solution-deployment-cleverworkaroundshidefields.wsp-0.<br />
Operation completed successfully. </font></p>
<p><font face="Courier New">Done building project &#8220;CleverWorkAroundsHideFields.csproj&#8221;.<br />
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ========== </font></p>
<p>This time we do not have any warning messages in the Visual Studio build log. So let&#8217;s confirm via SharePoint Central Admin.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image18.png"><img border="0" width="543" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb18.png" alt="image" height="154" style="border-width: 0px" /></a></p>
<p>Great! So now we have successfully deployed the solution, the site collection administrator for this web application can activate the feature</p>
<h2>Governance Interlude</h2>
<p>I think at this time it is very important to reinforce why packaging up code into solutions is such a mandatory governance requirement. In the above example, we had a problem with the deployment of the web part. It may have been an issue with the DLL in the GAC, changes made to web.config files for each web application, or a variety of other reasons. The point is, I was able to <strong>roll back</strong> to a known good state and start over!</p>
<p>I&#8217;ve said it before, but any developer who rolls their eyes at me when I tell them that their work has to be packaged up as a solution, obviously is not serious about governance.</p>
<h2>Activating the Feature</h2>
<p>So, now that our solution has been installed and deployed to each web application, we now have a site collection feature to activate. This feature will copy our web part into the Web Part Gallery for the site collection and thereby make it available for use.</p>
<p>So as a site collection owner, we navigate to &#8220;Site Actions&#8221; and &#8220;Modify All Site Settings&#8221;. Choose the option &#8220;Site Collection Features&#8221;, and you will see the results of our work in all its glory! Wahoo!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image19.png"><img border="0" width="636" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb19.png" alt="image" height="112" style="border: 0px" /></a></p>
<p>So don&#8217;t just sit there! Activate the sucker!</p>
<h2>Testing the new web part</h2>
<p>For this example, I am going to use the same demo site and list that I used in <a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">part 1</a> of this series.</p>
<p>The site is <a href="http://tidemo/tftp">http://tidemo/tftp</a> and the list to try this on is the IT Assets list. I have navigated to the IT Assets list, and opened the entry for the first item in the list (ABCRTR01)</p>
<p>Using the ToolPaneView hack described in <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a>, open DispForm.aspx in page-edit mode as shown below.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image20.png"><img border="0" width="534" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb20.png" alt="image" height="265" style="border-width: 0px" /></a></p>
<p>Click on the Main web part zone and add a new web part. You will see CleverWorkArounds as a web part group, listing our web part. (For reference, Feature.XML is the file where name and description information is set)</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image21.png"><img border="0" width="531" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb21.png" alt="image" height="186" style="border-width: 0px" /></a>&#8216;</p>
<p>Add our web part to the page and then click on &#8220;Modify Shared Web Part&#8221; to being up the properties screen. This is where we get to see if you did all the XML serialisation code from <a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/">Part 4</a> properly!!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image22.png"><img border="0" width="539" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb22.png" alt="image" height="147" style="border-width: 0px" /></a></p>
<p>If you see the screen below, it has all worked a treat! You now have a custom web part property asking you to list the columns to hide. The below-right image shows this web part property filled in with the &#8220;Purchase Date&#8221; and &#8220;IP Address&#8221; columns listed.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image23.png"><img border="0" width="254" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb23.png" alt="image" height="182" style="border: 0px" /></a>   <a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image24.png"><img border="0" width="244" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb24.png" alt="image" height="182" style="border-width: 0px" /></a></p>
<p>Click OK and let&#8217;s see the result! Wohoo! Fields hidden!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image25.png"><img border="0" width="508" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb25.png" alt="image" height="257" style="border: 0px" /></a></p>
<h2>Conclusion</h2>
<p>So, after 5 long winded blog posts, what have we achieved? Going back over the goals they were:</p>
<ul>
<li>Allow hidden fields based on identity/audience</li>
<li>Avoid use of SharePoint Designer</li>
<li>Avoid customisations to the form pages that unghosted the pages from the site definition</li>
<li>Avoid the need for site administrators/designers to have to dabble in javascript code</li>
<li>Packaged up the web part into an easily deployable/retractable solution</li>
</ul>
<p><strong>CleverWorkAround Rating: Awesome!</strong></p>
<p>Phew! Are we done yet? It seems like I have been typing these JavaScript articles for a freakin eternity! Alas no, I&#8217;m *still* not done!</p>
<p>I have an additional enhancement to make to this web part, and I also want to alert to you a couple of issues I had with this whole process.</p>
<p>So a Part 6 is in the works, but for now, I think its time for a well deserved beer! Your shout? <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>regards</p>
<p>Paul</p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>More SharePoint Branding &#8211; Customisation using JavaScript &#8211; Part 4</title>
		<link>http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/</link>
		<comments>http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/#comments</comments>
		<pubDate>Sun, 09 Mar 2008 06:46:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Branding]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[STSDEV]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Web Parts]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/</guid>
		<description><![CDATA[Hi there. As I write this post, the media are telling me that the stock market is stuffed, the US economy is going to the dogs and banks are writing down billions from sub-prime excess. I dare not check my online broker, road traffic this morning was abysmal, I was late, brought in the wrong [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p><!--adsense--></p>
<p>Hi there. As I write this post, the media are telling me that the stock market is stuffed, the US economy is going to the dogs and banks are writing down billions from sub-prime excess. I dare not check my online broker, road traffic this morning was abysmal, I was late, brought in the wrong laptop and left an important DVD at home.</p>
<p>Could it get any worse? Who knows, but it sounds like the sort of day to re-visit JavaScript and get frustrated with writing a web part for the first time.</p>
<p>So to recap on our journey thus far..</p>
<ul>
<li><a href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a> of this series looked at how we can use JavaScript to deal with the common request of hiding form elements from the user in lists and document libraries. It looked at a Microsoft documented method, then a better, more flexible method.</li>
<li><a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a> wrapped this JavaScript code into a web part which has been loaded into the SharePoint web part gallery.</li>
<li><a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a> then examined the trials and tribulations of getting this new web part added to certain SharePoint pages (NewForm.aspx, EditForm.aspx and DispForm.aspx), and then with a few simple edits, use this web part to hide form fields as desired. Finally, I demonstrated the power of combining this with SharePoint Audiences targeting functionality to make the hiding/unhiding of form elements personalised to particular groups of users.</li>
</ul>
<p>All in all a pretty clever workaround so far if I say so myself. <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>My original goals for this JavaScript was to find an effective, easily repeatable way to customise SharePoint form pages by hiding fields or form elements when we need to. Specifically:</p>
<ul>
<li>Allow hidden fields based on identity/audience</li>
<li>Avoid use of SharePoint Designer</li>
<li>Avoid customisations to the form pages that unghosted the pages from the site definition</li>
</ul>
<p>We achieved these goals in part three, but was I satisfied? No. The quest for more clever workarounds always goes on!</p>
<p>[Quick Navigation: <a target="_blank" href="http://www.cleverworkarounds.com/2008/02/07/more-sharepoint-branding-customisation-using-javascript-part-1/">Part 1</a>, <a target="_blank" href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-2/">Part 2</a>, <a target="_blank" href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">Part 3</a>, <a href="http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-5/">Part 5</a> and Part 6]</p>
<p><span id="more-668"></span></p>
<p>So the way I am going to structure this post is to pitch it to part-time or junior developers. If you are an experienced software engineer, this article is not going to trouble you.</p>
<p>Coffee rating: <a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image8.png"><img border="0" width="25" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/01/image-thumb8.png" alt="image" height="25" /></a></p>
<h2>Remaining Issues</h2>
<p>One thing I was unhappy about with the web part in <a href="http://www.cleverworkarounds.com/2008/02/28/more-sharepoint-branding-customisation-using-javascript-part-3/">part three</a> was that JavaScript still had to be edited when using the web part on a page. I wanted to take the programming completely out of the equation. Additionally, it was about time I got off my butt and learned to code a web part anyway. I&#8217;d previously blogged about the wonderful STSDEV, and decided I&#8217;d better put my money where my mouth and actually use it before I start mandating that others do.</p>
<p>So the first part of this post is examining STSDEV, and the joyous fun I had with my first ever web part with it, then I will get onto the first part of the coding.</p>
<h2>The Web Part Requirements</h2>
<p>So what are we planning to do here? Basically it is pretty simple. The JavaScript code that hides the columns from a page looks like this.</p>
<p><img src="http://www.cleverworkarounds.com/wp-content/uploads/2008/02/image67.png" /></p>
<p>If you look closely at the above example, you will see that we have two lines that are repeated for every field we wish to hide.</p>
<pre class="csharpcode">control = findacontrol(“Device Type”);
control.parentNode.parentNode.style.display=“none”;</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>So, how about we make a web part that accepts a custom property that allows the user to list all of the fields to be hidden, and the web part can generate the complete JavaScript code for each of them to be hidden from view. This screen-shot shows the basic idea.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image.png"><img border="0" width="239" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb.png" alt="image" height="170" style="border-width: 0px" /></a></p>
<p>Note that we have listed three columns in the web part properties separated by a comma. Thus the page containing this web part would hide the existence of any of these columns.</p>
<h2>Enter STSDEV (Take 1)</h2>
<p>So first up, I grabbed STSDEV from its <a href="http://www.codeplex.com/stsdev">codeplex home</a>. I installed it and ran the EXE to receive the initial screen.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image1.png"><img border="0" width="512" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb1.png" alt="image" height="248" style="border-width: 0px" /></a> </p>
<p>On my first attempt, I created the solution in my default visual studio projects folder (C:\Documents and Settings\Paul\My Documents\Visual Studio 2005\Projects\CleverWorkarounds)</p>
<p>STSDEV happily accepted this and created my solution, which I opened with Visual Studio 2005 and accepted the obligatory warning as shown. But that&#8217;s cool &#8211; we trust those nice STSDEV guys! <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image2.png"><img border="0" width="423" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb2.png" alt="image" height="299" style="border-width: 0px" /></a> <a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image3.png"><img border="0" width="209" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb3.png" alt="image" height="300" style="border-width: 0px" /></a></p>
<p>I won&#8217;t spend too much time going into the solution created for the web part project because you can watch the <a href="http://www.codeplex.com/stsdev/Release/ProjectReleases.aspx?ReleaseId=10119">videos</a> that explain it much better anyway. But I will draw your attention to the fact that two sample web parts are included in the solution, CustomWebpart1.cs and CustomWebpart2.cs. We will rename and modify these later but first I need you to be aware of one &#8216;gotcha&#8217; that I encountered.</p>
<p>In Visual Studio try and compile this project as it is. Make sure that the build type is set to DebugBuild and press F6 or choose &#8220;Build Solution&#8221; from the &#8220;Build&#8221; menu. Uh-oh, I got a runtime error with STSDEV&#8230; Bummer</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image4.png"><img border="0" width="559" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb4.png" alt="image" height="367" style="border-width: 0px" /></a></p>
<p>This had me going for a while, because at first I had made changes to the solution before I attempted a build. So I spent some time thinking it was my changes that were the root of the issue. All it turned out to be was the spaces in the path to my project.</p>
<p><strong>C:\Documents^ ^and^ ^Settings\Paul\My^ ^Documents\Visual^ ^Studio^ ^2005\Projects\CleverWorkarounds</strong></p>
<h2>Enter STSDEV (Take 2)</h2>
<p>This time, I&#8217;ve created the project with the parent directory parameter being a path with no spaces&#8230;</p>
<p><strong>C:\VSPROJ\CleverWorkarounds</strong></p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image5.png"><img border="0" width="577" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb5.png" alt="image" height="231" style="border-width: 0px" /></a></p>
<p>Follow all the steps as per take 1 and try and compile the solution. Good &#8211; no nasty runtime burps this time.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image6.png"><img border="0" width="453" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb6.png" alt="image" height="215" style="border-width: 0px" /></a></p>
<h2>Customising the Solution</h2>
<p>So we have to now take this generic visual studio solution and make our changes. This consists of deleting stuff that we don&#8217;t need, renaming our class and updating references to the class name. Later we will customise the build/deploy process too. If you have experience with STSDEV or this seems too straightforward for me to blog about, then skip to the next section, otherwise read on for more detail of my specific example.</p>
<p>The first step is to customise our generic web part solution to our needs. We will delete CustomWebPart2.cs and rename CustomWebPart1.cs to CleverWorkaroundsHideFields.cs. When you perform the rename, you will ask if you want all project references to be renamed also. Makes sense doesn&#8217;t it?</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image7.png"><img border="0" width="564" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb7.png" alt="image" height="95" style="border-width: 0px" /></a></p>
<p>This dialog box should not be interpreted as modifying any hardcoded references to the old file name of CustomWebPart1.cs. You will still have to do some search/replace work.</p>
<p>Additionally, there are two .webpart files that go with the two default class files and you have to rename/delete these as well. They can be found in the solution under RootFiles\TEMPLATE\FEATURES\CleverWorkAroundsHideFields\WebParts.</p>
<p>Delete CustomWebPart2.webpart and rename CustomWebpart1.webpart to CleverWorkAroundsHideFields.webpart.</p>
<p>Below is the result of both changes (.cs files and .webpart files)</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image8.png"><img border="0" width="380" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb8.png" alt="image" height="302" style="border-width: 0px" /></a></p>
<p>Okay, so now this solution comes with xml files, solution files and all the other paraphernalia associated with getting a web part bundled up and installed to a farm. Now we have to delete all references to the deleted web part called CustomWebPart2 and update the references to CustomWebPart1 to CleverWorkAroundsHideFields.</p>
<p>Using the FIND/REPLACE tool, the entire project can be adjusted very quickly</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image9.png"><img border="0" width="216" src="http://www.cleverworkarounds.com/wp-content/uploads/2008/03/image-thumb9.png" alt="image" height="244" style="border-width: 0px" /></a></p>
<p>The above operation takes care of the renaming of CustomWebPart1 in one single operation. But with CustomWebPart2 we are deleting references, so it takes a little finer surgery.</p>
<p>Here are the results of the *find* for CustomWebPart2.webpart</p>
<pre class="csharpcode">Find all <span class="str">"CustomWebpart2"</span>, Subfolders, Find Results 1, <span class="str">"Entire Solution"</span>
DeploymentFiles\SolutionPackage.ddf(25):RootFiles\TEMPLATE\FEATURES\CleverWorkAroundsHideFields\WebParts\CustomWebPart2.webpart
RootFiles\TEMPLATE\FEATURES\CleverWorkAroundsHideFields\feature.xml(17):      Location=<span class="str">"WebParts\CustomWebPart2.webpart"</span> /&gt;
RootFiles\TEMPLATE\FEATURES\CleverWorkAroundsHideFields\WebParts.xml(8):    &lt;File Url=<span class="str">"CustomWebPart2.webpart"</span> Type=<span class="str">"GhostableInLibrary"</span>&gt;
Matching lines: 3    Matching files: 3    Total files searched: 9</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>You will find references to CustomWebPart2 in</p>
<ul>
<li>SolutionPackage.ddf under DeploymentFiles</li>
<li>feature.xml under RootFiles\TEMPLATE\FEATUTES\CleverWorkAroundsHideFields</li>
<li>WebParts.xml under RootFiles\TEMPLATE\FEATUTES\CleverWorkAroundsHideFields</li>
</ul>
<p>Using visual studio, open up each of these files and adjust the references. So for example in SolutionPackage.ddf I changed from:</p>
<p><font face="Courier New">;*** add files for CleverWorkAroundsHideFields\WebParts feature<br />
.Set DestinationDir=CleverWorkAroundsHideFields\WebParts<br />
RootFiles\TEMPLATE\FEATURES\CleverWorkAroundsHideFields\WebParts\CleverWorkAroundsHideFields.webpart<br />
RootFiles\TEMPLATE\FEATURES\CleverWorkAroundsHideFields\WebParts\CustomWebPart2.webpart</font></p>
<p>to</p>
<p><font face="Courier New">;*** add files for CleverWorkAroundsHideFields\WebParts feature<br />
.Set DestinationDir=CleverWorkAroundsHideFields\WebParts<br />
RootFiles\TEMPLATE\FEATURES\CleverWorkAroundsHideFields\WebParts\CleverWorkAroundsHideFields.webpart<br />
</font></p>
<p><em>Now if you are thinking to yourself, what is FEATURE.XML and Solutionpackage.DDF anyway? Then I am afraid that you have some homework to do! If you are going to code anything for SharePoint, you need to understand the concepts of </em><a href="http://www.cleverworkarounds.com/2007/10/08/a-simple-example-of-a-sharepoint-%e2%80%9cfeature%e2%80%9d/"><em>features</em></a><em> and how they are used with the </em><a href="http://www.cleverworkarounds.com/2007/11/10/sharepoint-branding-part-6-a-solution-to-all-issues/"><em>solution framework</em></a><em>. Seriously, if you are blindly editing the files using this post as a guide, then you are only going to get yourself into trouble later.</em></p>
<p>For the rest of you, finish off the renames and removals of the default class names and then try and rebuild the solution. If it all builds, you can move onto the next step of actual coding the thing.Once we finish coding, you will see pretty quickly how useful and time saving STSDEV really is.</p>
<h2>Coding the Web Part &#8211; Part 1</h2>
<p>So, now we open up CleverWorkAroundsHideFields.cs and add our code. The first step is to add references to additional libraries that this web part will use.</p>
<pre class="csharpcode"><span class="kwrd">using</span> System.ComponentModel;
<span class="kwrd">using</span> System.Xml.Serialization;</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>What are these and what do they do? Without going into loving detail, these namespaces allow you to use <strong>XML serialisation</strong>. I had not previously coded much ASP.NET stuff, so XML serialisation took me a little getting used to. But the basic idea is this.</p>
<h2>XML Serialisation Interlude</h2>
<p>If you have an object instantiated from a class, with a bunch of properties set to different values, how to you send those properties to another remote object of the same class? What if it is two separate web server or web applications?</p>
<p>XML serialisation allows you to set properties for the object that are then stored behind the scenes as XML (this is the serialisation part). The other end gets the XML (over HTTP) and deserialises it back to the native properties for the destination object. Lo and behold, we have copied the state of one object to another object.</p>
<p>Now think of the code that this saves when the other end simply has to call a deserialise method and all of the properties of the object are auto-magically filled in.</p>
<p>Now in SharePoint, web part properties have to be persisted. When you visit a page, the look and feel of the web part is determined partly by web part properties set by the site designer. Those settings are retrieved from the SharePoint database. So when those properties are first set by the administrator (i.e change the title or appearance of a web part), SharePoint <strong>serialises</strong> all of those properties to XML and that XML is stored into the database. When the page is then later loaded by a user, a web part object is created, and then the XML properties are <strong>deserialised</strong> back to the object properties so it can appear how it is supposed to.</p>
<p>Make sense? <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  I hope so because that&#8217;s all I&#8217;m saying about it! If you are still cofused, try <a href="http://www.devarticles.com/c/a/ASP.NET/XML-Serialization-in-ASP.NET/">this article</a>.</p>
<h2>Coding the Web Part &#8211; Part 2</h2>
<p>So having added the two references to the XML Serialaisation and System.ComponentModel namespace, you should have the following code.</p>
<pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Web;
<span class="kwrd">using</span> System.Web.UI;
<span class="kwrd">using</span> System.Web.UI.WebControls;
<span class="kwrd">using</span> System.Web.UI.WebControls.WebParts;
<span class="kwrd">using</span> System.Xml.Serialization;
<span class="kwrd">using</span> System.ComponentModel;</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>Make sure that there is no reference to a namespace called Microsoft.SharePoint.WebPartPages. There are actually two different web part classes available, one designed for SharePoint 2003 and the more recent one being part of ASP.NET version 2. (System.Web.UI.WebControls.Webparts).</p>
<p><em>MSDN and Microsoft code samples have a lot to answer for here! Most code samples for web parts with custom properties are based on the legacy web part class, and things have changed between old and new, especially when it comes to XML serialised properties. I wasted a lot of time here because of this!</em></p>
<p>The next step is to delete the default code in the web part class. Find the following code and delete it.</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> CreateChildControls() {
  Label lblHello = <span class="kwrd">new</span> Label();
  lblHello.Text = <span class="str">"Hello"</span>;
  Controls.Add(lblHello);
}</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>Serialsed XML parameters are in square brackets around sections of c# code. These are .NET attributes and tell the XML serializer where the various members of this object will appear in the XML and what they will be named. Without these, serialization cannot take place.</p>
<p>So the first serialised parameter is defined in between the namespace and the class itself.</p>
<pre class="csharpcode"><span class="kwrd">namespace</span> CleverWorkAroundsHideFields {
   [XmlRoot(Namespace = <span class="str">"CleverWorkAroundsHideFields"</span>)]
   <span class="kwrd">public</span> <span class="kwrd">class</span> CleverWorkAroundsHideFields : WebPart {
   }
}</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>Now if we serialised the code into XML now it would look like this</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">CleverWorkAroundsHideFields</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">CleverWorkAroundsHideFields</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>Exciting eh? So let&#8217;s now add some web part properties and serialise them as well. First up the properties of this class. If you check the section of this post titled &#8220;Web part Requirements&#8221;, I stated that the web part should accept a custom property that allows the user to list all of the fields to be hidden. So below is the property that will store this list of fields. It is about as simple as a class property can be (just store a string with a get and set method).</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">string</span> _HideFieldList; 

<span class="kwrd">public</span> <span class="kwrd">string</span> HideFieldList
{
   get
   {
      <span class="kwrd">return</span> _HideFieldList;
   }
   set
   {
      _HideFieldList = <span class="kwrd">value</span>;
   }
}</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>Now I need to add the parameters for XML serialsation. The above raw C# code above now changes to:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> CleverWorkAroundsHideFields : WebPart { 

   <span class="kwrd">private</span> <span class="kwrd">string</span> _HideFieldList; 

   <span class="rem">// Create a custom category in the property sheet.</span>
   [Category(<span class="str">"Custom Properties"</span>)]
   [Personalizable(PersonalizationScope.Shared)]
   [WebDisplayName(<span class="str">"List of columns to hide on this page"</span>)]
   [WebDescription(<span class="str">"Comma delimited list of columns to hide on this page"</span>)]
   [WebBrowsable(<span class="kwrd">true</span>)]
   [XmlElement(ElementName = <span class="str">"HideFieldList"</span>)] 

   <span class="kwrd">public</span> <span class="kwrd">string</span> HideFieldList
   {
      get
      {
         <span class="kwrd">return</span> _HideFieldList;
      }
      set
      {
         _HideFieldList = <span class="kwrd">value</span>;
      }
   }
}</pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>I haven&#8217;t serialised this into XML, but you can see how all of the properties in square brackets would form an XML document describing the properties. if I did, it would look something akin to:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">CleverWorkAroundsHideFields</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">Category</span><span class="kwrd">&gt;</span>Custom Properties<span class="kwrd">&lt;/</span><span class="html">Category</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">WebDisplayName</span><span class="kwrd">&gt;</span>List of columns to hide on this page<span class="kwrd">&lt;/</span><span class="html">WebDisplayName</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">WebDescription</span><span class="kwrd">&gt;</span>Comma delimited list of columns to hide on this page<span class="kwrd">&lt;/</span><span class="html">WebDescription</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">WebBrowsable</span><span class="kwrd">&gt;</span>True<span class="kwrd">&lt;/</span><span class="html">WebBrowsable</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">XmlElement</span> <span class="attr">ElementName</span><span class="kwrd">="HideFieldList"</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">CleverWorkAroundsHideFields</span><span class="kwrd">&gt;</span></pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>So now SharePoint has this in its database. When this webpart is rendered, the XML similar to above is retrieved and deserialised back to our WebPart class.</p>
<p><em>At this point it is a good idea to build the solution to ensure that you have no syntax errors or namespace issues. If you have trouble getting to this point, its best you not go any further until the project builds correctly.</em></p>
<p>Now where did I get these XML parameter values from? Go to the <a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.webparts.aspx">MSDN documentation</a> for the System.Web.UI.WebControls.WebParts namespace and you will find all of the available properties buried there. (Either that or cheat like me and find out via <a href="http://dkeeling.spaces.live.com/blog/cns!1FF0B17B869C973!158.entry">here</a>)</p>
<h2>Coding the Web Part &#8211; Part 3</h2>
<p>So now let&#8217;s write the code to render the JavaScript output. This is basically C# code to create the JavaScript that will render in the browser. The code is simple enough, we have looked at it in the last posts. But creating the JavaScript inside C# code makes it look worse than it really is.</p>
<p>First up, we need a new array variable called _fieldlist to store the individual fields (remember they come as a comma delimited list so we will split them to their individual names).</p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">string</span>[] _fieldlist;</pre>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Render(HtmlTextWriter output)
{   <span class="rem">// Now lets extract the list of fields from the web part properties</span>
   <span class="kwrd">if</span> (HideFieldList != <span class="kwrd">null</span>)
   {
      _fieldlist = HideFieldList.Split(<span class="str">','</span>);
      <span class="rem">// javascript inside C# - ugh    </span>
      <span class="rem">// I know this looks ugly on account of the escaped quotes.    </span>
      <span class="rem">// First section is the findacontrol function</span>
      output.WriteLine();
      output.WriteLine(<span class="str">@"&lt;script language="</span><span class="str">"javascript"</span><span class="str">" type="</span><span class="str">"text/javascript"</span><span class="str">"&gt;  "</span>);
      output.WriteLine();
      output.WriteLine(<span class="str">@"_spBodyOnLoadFunctionNames.push("</span><span class="str">"hideFields"</span><span class="str">")  "</span>);
      output.WriteLine(<span class="str">@"function findacontrol(FieldName) {  "</span>);
      output.WriteLine(<span class="str">@"var arr = document.getElementsByTagName("</span><span class="str">"!"</span><span class="str">");  //get all comments "</span>);
      output.WriteLine(<span class="str">@"for (var i=0;i &lt; arr.length; i++ ) {   "</span>);
      output.WriteLine(<span class="str">@"   // now match the field name  "</span>);
      output.WriteLine(<span class="str">@"   if (arr[i].innerHTML.indexOf(FieldName) &gt; 0) { "</span>);
      output.WriteLine(<span class="str">@"      return arr[i]; "</span>);
      output.WriteLine(<span class="str">@"   } "</span>);
      output.WriteLine(<span class="str">@"  } "</span>);
      output.WriteLine(<span class="str">@"}"</span>);
      output.WriteLine();
      output.WriteLine();
      <span class="rem">// Now the hidefields function, which loops for each field to be hidden</span>
      output.WriteLine(<span class="str">"function hideFields() { "</span>);
      output.WriteLine(<span class="str">"   var control; "</span>);
      <span class="kwrd">if</span> (_fieldlist != <span class="kwrd">null</span>)
      {
         <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; _fieldlist.Length; i++)
         {
            output.Write(<span class="str">"    control = findacontrol(\""</span>);
            output.Write(_fieldlist[i]);
            output.WriteLine(<span class="str">"\" ); "</span>);
            output.WriteLine(<span class="str">"   control.parentNode.parentNode.style.display=\"none\""</span>);
         }
      }
      output.WriteLine(<span class="str">" }"</span>);         output.WriteLine(<span class="str">"&lt;/script&gt;"</span>);
   } <span class="rem">// if</span>
} <span class="rem">// method</span></pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p>The only section of code above that is of real interest is in the JavaScript hideFields() function. Here we loop for each field supplied in the list, and construct the code. So for example, if HideFieldList contained &#8220;Column A,Column B&#8221;, the generated JavaScript code would be:</p>
<pre class="csharpcode">control = findacontrol(<span class="str">"Column A"</span>);
control.parentNode.parentNode.style.display=<span class="str">"none"</span>
control = findacontrol(<span class="str">"Column B"</span>);
control.parentNode.parentNode.style.display=<span class="str">"none"</span></pre>
<style type="text/css">  .csharpcode, .csharpcode pre  {  	font-size: small;  	color: black;  	font-family: consolas, "Courier New", courier, monospace;  	background-color: #ffffff;  	/*white-space: pre;*/  }  .csharpcode pre { margin: 0em; }  .csharpcode .rem { color: #008000; }  .csharpcode .kwrd { color: #0000ff; }  .csharpcode .str { color: #006080; }  .csharpcode .op { color: #0000c0; }  .csharpcode .preproc { color: #cc6633; }  .csharpcode .asp { background-color: #ffff00; }  .csharpcode .html { color: #800000; }  .csharpcode .attr { color: #ff0000; }  .csharpcode .alt   {  	background-color: #f4f4f4;  	width: 100%;  	margin: 0em;  }  .csharpcode .lnum { color: #606060; }</style>
<p><em>Please be careful cutting and pasting this code! Quotes seem to get screwed up sometimes.</em></p>
<h2>Conclusion (let&#8217;s have a break)</h2>
<p>Once again, this post is starting to get a little long. So I&#8217;ll stop now and let you have a breather. In part 5 of this series, we will do an initial build of this solution, which will demonstrate how useful STSDEV is at speedy packaging and deployment. I&#8217;ll show you how to package up a nice, re-usable solution, and be able to test and debug quickly and painlessly.</p>
<p>Until then, bye for now</p>
<p>Paul<br />
<!--adsense--></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2008/03/09/more-sharepoint-branding-customisation-using-javascript-part-4/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>SharePoint Branding Part 7 -The &#8216;governance&#8217; of it all..</title>
		<link>http://www.cleverworkarounds.com/2007/11/14/sharepoint-branding-the-governance-of-it-all-part-7/</link>
		<comments>http://www.cleverworkarounds.com/2007/11/14/sharepoint-branding-the-governance-of-it-all-part-7/#comments</comments>
		<pubDate>Tue, 13 Nov 2007 17:16:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Branding]]></category>
		<category><![CDATA[COBiT]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[Governance]]></category>
		<category><![CDATA[ISO17799/27001]]></category>
		<category><![CDATA[ITIL]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[master pages]]></category>
		<category><![CDATA[page layouts]]></category>
		<category><![CDATA[planning]]></category>
		<category><![CDATA[Branding Series 1]]></category>
		<category><![CDATA[Troubleshooting]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2007/11/14/sharepoint-branding-the-governance-of-it-all-part-7/</guid>
		<description><![CDATA[Well, here we are! After delving into dark arts where everybody but metrosexual web designers fear to tread (HTML and CSS), we then delved into the areas that metrosexual web designers truly fear to tread (packaging, deployment and even some c# code!). Finally, we get to the area where everybody is interested until it happens [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p>Well, here we are! After delving into dark arts where everybody but metrosexual web designers fear to tread (HTML and CSS), we then delved into the areas that metrosexual web designers truly fear to tread (packaging, deployment and even some c# code!). Finally, we get to the area where everybody is interested until it happens to get in their way! (Ooh, I am a cynical old sod tonight).</p>
<p>That is Governance!</p>
<p><span id="more-266"></span><br />
May I start by quoting from that wise band &#8220;Faith No More&#8221; and their first hit &#8220;We Care A Lot&#8221;, who in 1987 were of course thinking of collaborative document management when they wrote..</p>
<p><em>&#8220;We care a lot about the gamblers and the pushers and the geeks<br />
We care a lot about the crack and smack and whack that hits the street<br />
We care a lot about the welfare of all the boys and girls<br />
We care a lot about you people cause we&#8217;re out to save the world</em></p>
<p><em>And it&#8217;s a dirty job but someone&#8217;s gotta do it&#8221;</em></p>
<p>Now, we are only going to talk about governance in relation to branding here, which is really a pimple on the butt of the overall governance of SharePoint. In saying that though, much of the philosophical basis from which I write this article is pretty much applied to the other areas of SharePoint governance anyhow.</p>
<p>So, what are we trying to do anyway? If you go and google or wikipedia the subject of governance, you can pretty much summarise the academic definition as &#8220;cover your ass&#8221;! Whether you are answerable to the CEO of a blue chip with a billion dollar market cap, or to the CEO of a 25 user small business, if you are going to take the fall, you want to make sure you take a few others with you, right? <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Therefore, one of the first governance issues to deal with is the fact that we need a team with well defined roles and responsibilities. Each team will cover off different areas of SharePoint governance that can broadly be grouped into a few different categories:</p>
<ul>
<li>Project Management</li>
<li>Infrastructure</li>
<li>Development/Design</li>
<li>Operation</li>
<li>Training</li>
</ul>
<p>Now, you may group things a little differently then me, but you get the idea. I have deliberately NOT listed design (and with it branding) separately because it depends on the type of SharePoint project being implemented. If it is a web content management oriented project (like an internet site), then design probably warrants its own category. However, if it is a collaborative project, then design is quite likely part of development process.</p>
<p>I think this point deserves further consideration.</p>
<h2>WCM vs Collaborative Sites</h2>
<p>SharePoint is a multipurpose beast. It can be used as a straight out CMS system and compete with the likes of <a href="http://www.joomla.org/">Joomla</a>, <a href="http://drupal.org/">Drupal</a>, <a href="http://www.reddot.com/">RedDot</a> and <a href="http://www.episerver.com/en/">EpiServer</a>. It can also be used as a document management system, management reporting tool, project tracking system, collaboration platform and so on and so forth&#8230;</p>
<p>When used as a CMS only, it&#8217;s pretty good, all things considered. There are some pretty snazzy examples of WCM sites that make you stop and think, &#8220;wow &#8211; is that SharePoint?&#8221;. But the typical visitor to a WCM based SharePoint site will not likely be using many of the other goodies that SharePoint offers. In these type of sites, there are a few content authors, but mostly the people using the site are visitors consuming the web content. Really, that&#8217;s about it.</p>
<p>But if you have been reading this series of articles, I spent the first three talking about how much of a pain the core.css and application.master issue is on corporate branding. If you haven&#8217;t, I suggest taking a look.</p>
<p>The issue is that many aspects of collaborative functionality use parts of SharePoint that is tough to brand. <a href="http://cameronmoll.com/archives/2007/10/sharepoint_2007_pointedly_unskinnable/">Cameron Moll</a> has written a brilliant article on this issue and I consider it mandatory reading. Many collaborative functions are based on a central master page called APPLICATION.MASTER. Therefore, if you have made a well branded master page for your content, the user experience will be inconsistent when they perform certain administrative type tasks.</p>
<p>Cameron nails the issue perfectly here: &#8220;This is all perfectly fine in the CMS scenario, as only an infinitesimal fraction of your users will switch between published screens and admin screens. However, in the collaboration scenario, nearly any user can, and will, switch between published screens and admin screens to complete tasks. Because your skinning won’t be reflected in the admin, what should otherwise be a continuous visual flow for users instead becomes a jarring transition from your beautiful theme to SharePoint’s vanilla theme and back again&#8221;.</p>
<p>Now this entire series of articles has been based on the &#8216;other&#8217; side of SharePoint (i.e. *not* WCM). In my opinion, in a purely collaborative SharePoint implementation, branding should be one of the <strong>last</strong> things you do. Your time is better spent refining collaborative functionality. However if you are doing WCM, it should be one of the <strong>first</strong> things to do.</p>
<p>You can imagine then, that the worst case scenario for all involved in a SharePoint project is mixing WCM and collaboration. It carries with it the exact same type of problems and risks that I outlined in my <a href="http://www.cleverworkarounds.com/2007/10/31/sharepoint-sucks-at-document-management-or-does-it-a-metal-perspective/">article</a> on collaborative document management vs records management. Try and do both, and you will not only dilute the benefits of each, but you end up with an over time/budget process with plenty of pissed users and stakeholders.</p>
<p>Moral of the story? Decide what you want to be!</p>
<p>So let&#8217;s move on.</p>
<h2></h2>
<h2>Best Practice Standards</h2>
<p>A while back, I posted a series of <a href="http://www.cleverworkarounds.com/2007/10/09/it-governance-standards-cobit-iso1779927001-itil-and-pmbok-%e2%80%93-part-1/">articles</a> on best practice methodologies and the laws around compliance. For many areas of governance, much of the work is done for you by these best practice standards. Certainly, aspects of the ITIL books on ICT change management, deployment management, design and planning and operations management will factor in branding governance.</p>
<p>I hope for people who have read those articles wondering why I included my four articles in a SharePoint oriented blog, you should see it all start to come together now. They are your philosophical starting point to approaching SharePoint governance</p>
<p>For what it&#8217;s worth, although ITIL is currently flavour of the month for many IT departments, I think that you can get a lot out of ISO27000/27001 and COBiT as well. ITIL is very inwards facing in a lot of its subject areas. What I mean by that is that non IT Senior management and board level tend not to give a crap about ITIL, but are likely to have more of an interest in COBiT, particularly in the US (not just because it has prettier pictures either). COBiT is a much &#8220;higher level&#8221; standard than ITIL, and is a better philosophical starting point than ITIL which is more prescriptive. In reality the standards well complement each other, but if you are wondering which one to start on, I&#8217;d go with COBiT. (Another much more detailed post on SharePoint governance against these standards is in the works).</p>
<h2>It&#8217;s a dirty job but someone&#8217;s gotta do it</h2>
<p>So let&#8217;s start with some high level governance principles for branding a collaborative SharePoint site. Here is what we need to define and document.</p>
<ul>
<li>A management structure for supporting the development and deployment of branded MOSS Sites</li>
<li>Key roles and responsibilities within this structure</li>
<li>Policies, standards, guidelines, and decision processes required to support the deployment of branded SharePoint Sites</li>
</ul>
<p>What are the rationales for setting up a framework to assign accountabilities?</p>
<ul>
<li>Knowing who is responsible for making decisions</li>
<li>Knowing how decisions are made</li>
<li>Knowing who is responsible for implementing decisions</li>
</ul>
<p>In addition to this, branding governance aims to:</p>
<ul>
<li>Consistently provide a high quality user experience by ensuring that the branding governance plan is followed</li>
<li>Establish clear decision making authority and escalation criteria so that issues are resolved on a timely basis</li>
<li>Ensure compliance with established corporate style guide</li>
</ul>
<h2><font color="#000000">Roles and Responsibilities</font></h2>
<p>ISO27000/27001 puts a big emphasis on accountability. Without a strong culture of accountability, it is very difficult to adopt governance without it getting out of hand. One organisation I worked for had mapped out their process for dealing with the service desk and it was too big for an A4 sized page. It had to be printed on poster size and was the ugliest flowchart you have ever seen. This is a common symptom when clear lines of accountability do not exist. There is safety in complexity and ambiguity.</p>
<p>Thus, it is vitally important that the right roles are assigned the right responsibilities and people are fully aware of where their accountability lies.</p>
<p>The following table is a typical example of the roles and responsibilities of personnel involved in the governance of the MOSS branding. Depending on the size of your organisation, consolidate the roles and positions to suit. I&#8217;ve put the responsibility definitions into cleverworkarounds&#8217; plain english to make it more interesting, but you may want to formalise these a little more if you use this <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<table border="1" width="600" cellPadding="2" cellSpacing="0">
<tr>
<td width="200" vAlign="top"><strong>Role </strong></td>
<td width="198" vAlign="top"><strong>Position </strong></td>
<td width="200" vAlign="top"><strong>Responsibility</strong></td>
</tr>
<tr>
<td width="199" vAlign="top">Steering Committee</td>
<td width="198" vAlign="top">Senior Divisional Heads<br />
Marketing Manager<br />
IT Manager<br />
SharePoint Architect</td>
<td width="201" vAlign="top">The buck stops here! If it all goes to hell, these are the guys who get burned! (but have no doubt they will apportion the blame all round)As a result of that prospect, they tend to like to signoff on all branding things! (and everything else too)Oddly enough, they also therefore believe that they provide vision and direction to the MOSS branding</td>
</tr>
<tr>
<td width="198" vAlign="top">Business Owner</td>
<td width="198" vAlign="top">Board Level Project Sponsor</td>
<td width="202" vAlign="top">The person who writes the cheques! They are who the steering committee answers to. Thus, people are generally very nice to them!They get to set the direction of what they want, even if their branding taste is dodgy <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  (If they try and mix WCM and Collaboration try and tactfully dissuade them)</td>
</tr>
<tr>
<td width="199" vAlign="top">SharePoint Support Team</td>
<td width="197" vAlign="top">Application Support Manager<br />
SharePoint Administrator<br />
SharePoint Designer<br />
SharePoint Developer</td>
<td width="202" vAlign="top">These guys take all the vision stuff from the Business Owner and Steering Committee and actually designs and develops the corporate MOSS brandThis team also resolves operational issues and enforces best practice in relation to the MOSS branding solution</td>
</tr>
<tr>
<td width="199" vAlign="top">Site Collection Owner</td>
<td width="197" vAlign="top">SharePoint Administrator</td>
<td width="202" vAlign="top">Activation of branding features is performed by the site collection owner</td>
</tr>
<tr>
<td width="199" vAlign="top">Infrastructure Operations Team</td>
<td width="197" vAlign="top">Farm Owner<br />
Site Collection Owner<br />
Infrastructure Owner</td>
<td width="202" vAlign="top">These guys keep the support team honest. They ensure that branding is packaged up according to policy and install those features/solutions to the farm. This ensures the technical integrity of the branding development</td>
</tr>
</table>
<h2>Policies and Standards</h2>
<p>So now we have defined who is responsible for what, we can now put it all into policy.</p>
<h3>Corporate Style Guide</h3>
<p>The first thing you need to do is define a corporate style guide, or locate the existing one and refresh it via the steering committee. The style guide houses all relevant standards, requirements, and recommendations surrounding corporate brand. It is not a technical document, as it covers the tone, presentation and all implementation aspects, specifications, attributes and elements, summed up to present a brand consistently throughout all media.</p>
<p>This guide changes over time and its owner is likely the marketing division of the organisation and not just the SharePoint branding steering committee. It is best to engage with the division or individual that owns this guide, to ensure that the steering committee is in the loop during periods of review and updating.</p>
<p>Once you have an approved style guide, you can now apply it to SharePoint components.</p>
<h3></h3>
<h3>Master Pages</h3>
<p>If you adopt the principles of my earlier posts in this series, you may not need to have more than a single master page for your entire farm. A well defined master page with clever use of CSS override techniques allow you to offer different branding, yet using a single master page. If this is a realistic prospect for you, then it makes sense to enshrine in policy that you will only maintain one corporate master page.</p>
<p>Best to leave the master page in the master page gallery for the site collection. That document library has versioning and content approvals enabled. Thus, it eases change and configuration management, as well as packaging and deployment.</p>
<p>The master page should be named according to a consistent convention. I personally like to prepend the company name to the master pages, as well as layout pages as then it is very easy to see what components are customised from what is build in. I enshrine this in the branding policy as a mandatory requirement.</p>
<p>That master page should be well documented with all of the modifications made to it. Typically, if you have modified say, DEFAULT.MASTER, you will have to document modifications like</p>
<ul>
<li>Any assembly references added to the master page (see <a href="http://www.cleverworkarounds.com/2007/10/15/careful-with-pre-requisite-sharepoint-features/">this post</a> if you want an explanation)</li>
<li>Any hard-coded links to other CSS files and the definition of new styles</li>
<li>Modification of the HTML structure of the master page (e.g. Adding left and right borders to the default master page)</li>
<li>Any examples of non-compliance with the corporate style guide</li>
</ul>
<h3></h3>
<h3>Layout Pages</h3>
<p>A collaborative style SharePoint site may require additional layout pages. The rules pretty much apply as per master pages.</p>
<ul>
<li>Name them consistently with master pages (eg prepend company name)</li>
<li>Document their setup, where it is used and why it was required</li>
</ul>
<h3>Styles</h3>
<p>Corporate style sheet guidelines should be documented and these are a direct translation from the corporate style guide. Logo&#8217;s, fonts, formatting, colors, backgrounds, etc are documented either as mandatory standards or recommended guidelines in the CSS style guide.</p>
<p>In addition, CSS style sheets should be both well documented within the CSS file using comments, as well as documentation around the implementation of the style. If you have overridden say, some of CORE.CSS, then mention it in the comments for the style why it was done.</p>
<p>CSS styles should live in the Style Library for each site collection. Unless you have an exceptional reason, there is no point in reinventing the wheel and putting them anywhere else. Naming of CSS sheets should also be consistent with the master pages and page layouts. So if I was writing a governance policy for ABC corporation, I would use something like</p>
<ul>
<li>ABCDefault.master</li>
<li>ABCWelcomeSplash.aspx</li>
<li>ABCDefaultStyle.CSS</li>
</ul>
<h3>Site Templates</h3>
<p>Although I didn&#8217;t cover site templates in this series on branding, the concept is simple. Once you have set up a site the way you want it, you can save it as a template that can be re-used for other sites. Certainly, it is common for project oriented companies to create a project site template with a particular combination of lists, web-parts, workflows, event handlers and libraries. Each time a new project is initiated, a site is created for that project based on the template.</p>
<p>This helps us to achieve the governance of a consistent user experience, as well as improving change and configuration management.</p>
<p>The process of creating a site template is potentially complex as the amount of collaborative functionality provided grows over time. Therefore, guidelines for the development of site templates must be developed to ensure they meet minimum standards. Potentially, site templates will be used by different organisational groups, with their own unique requirements. You will need to find a balance between overall site/branding consistency versus the costs and overheads of accommodating unique requirements.</p>
<p>Therefore, a formal approval process culminating with steering committee approval should be in place to manage the ongoing management of every corporate site template. The corporate style guide will also very likely influence the look and feel of custom site templates.</p>
<p>For each template, you also need to determine which parts of the template may be changed by site owners, and which may not. This can be enforced by security settings, but you still need the official policy to fall back on if tool based controls do not give you what you need.</p>
<p>Having said all of this, much of the governance around site templates is focused on non-branding considerations such as security, audiences, functionality and the like. We will not discuss this here as it is not really a branding consideration.</p>
<p>The point is, site templates have similar branding governance requirements to master pages, page layouts and styles.</p>
<h2>Operational Management</h2>
<p>In the previous section I looked at the governance requirements of branding from a SharePoint building block point of view. Now lets take an ITIL oriented perspective</p>
<h3>Change management and approvals</h3>
<p>With change management, go straight to ITIL and get what you need as far as process is concerned. ITIL defines the objective of change management as:</p>
<p>&#8220;The objective of Change Management in this context is to ensure that standardized methods and procedures are used for efficient and prompt handling of all changes to controlled IT infrastructure, in order to minimise the number and impact of any related <a href="http://en.wikipedia.org/w/index.php?title=Incidents&amp;action=edit">Incidents</a> upon service.</p>
<p>ITIL defines a CAB or change authority board that advises the &#8216;change manager&#8217; prior to change approval. For my money, the steering committee will delegate the CAB function to the other groups who assume *custodianship* of the process. For example, the steering committee still bear ultimate accountability over the deployment of branding, but once the policy has been set, they delegate the validation of the deployment to the IT Infrastructure Operations Team.</p>
<p>Now bear in mind, we are talking about branding only here, and ITIL in the wrong hands can create ridiculous amounts of red tape.</p>
<p>But in relation to change management, this is the sort of stuff that should be considered.</p>
<ul>
<li>Change justification. Have we recorded the request (who and why)?</li>
<li>Assess the impact of the change (cost vs benefit)</li>
<li>Test the change. Any branding changes require comprehensive testing on a non production environment. You never know how various web-parts render, and a formal testing methodology must be defined to ensure that say, your latest snazzy style turns out to make the calendar view look crap.</li>
<li>Packaging and deployment. Updates to branding should be packaged and deployed in accordance with corporate policy. The goal here is to ensure efficient, consistent deployment with easy means of rollback. We will delve more into packaging and deployment in a moment.</li>
<li>Implement the change, update documentation and logs</li>
<li>Conduct post implementation review of the change</li>
</ul>
<h3>Packaging and deployment of branding</h3>
<p>Well, unless you are reading this series backwards, I think you should have a fair idea by now that I recommend that all branding should be implemented as a SharePoint solution. Check article <a href="http://www.cleverworkarounds.com/2007/10/25/sharepoint-branding-part-4-packaging-up-your-masterpiece-into-a-feature/">four</a>, <a href="http://www.cleverworkarounds.com/2007/10/27/sharepoint-branding-part-5-%e2%80%93-feature-improvements-and-bugs/">five</a> and <a href="http://www.cleverworkarounds.com/2007/11/10/sharepoint-branding-part-6-a-solution-to-all-issues/">six</a> for more info. For me personally, I consider that if an application developer does not comply with this requirement (or whines about having to comply), then they have no serious idea about the importance of governance. That for me is a risk that I would prefer not to live with.</p>
<p>You will need to ensure that if 3rd party developers are doing your branding, that they are aware of all your other branding requirements, such as naming conventions so that the content packaged up inside the solution follows your governance standard.</p>
<p>When branding is packaged up into a SharePoint solution, we have a single file than can be easily deployed to the farm, upgraded and rolled back. In a disaster recovery situation, re-applying your branding is literally as easy as installing the solution and activating it.</p>
<h3><strong>Source control </strong></h3>
<p>On a large scale site, you may opt to use source control like <a href="http://subversion.tigris.org/">Subversion</a> for your branding components, especially if you are writing custom event receiver assemblies as I described in article <a href="http://www.cleverworkarounds.com/2007/11/10/sharepoint-branding-part-6-a-solution-to-all-issues/">six</a>.</p>
<p>But then again, SharePoint itself is actually a great platform for implementing a governance site. You can make use of version enabled document libraries to hold your packaged solutions, procedures, standards and guidelines and other related content. Plus, you can use a calendar list+workflow for scheduling and notifying stakeholders of updates or changes, a task list for logging and tracking issues and infopath+workflows for automating the change management process.</p>
<p>Furthermore, I have found <a href="http://www.colligo.com/products/sharepoint/reader.asp">Colligo Reader</a> to be very useful for SharePoint governance sites, as it alleviates the chicken-egg risk of storing all of your governance and change history in the same tool that you are governing. Often I am asked, &#8220;what if SharePoint is down, how can I get to my documentation?&#8221;.</p>
<p>Colligo allows you to have a full offline sync of all your governance lists, documents and views, thereby significantly reducing this risk and that barrier to adoption. I also suggest that you buy a copy of this product and add to your governance policy that you will always keep an up to date sync of your governance site offline.</p>
<h2>Summing Up</h2>
<p>So finally it ends. I originally thought I&#8217;d cover it all in 3 articles but in the end it took 7 large articles. But I&#8217;ve now gotten to the end of this arduous task of attempting to cover SharePoint branding from end-to-end. I hope that you have found this series of articles of use, and I appreciate you for sticking with me. If these articles were of help to you, please drop me a line and let me know. If you really want to show your appreciation, and you live in Perth, West Australia, I&#8217;m quite partial to Hoegaarden <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  (but if its your buy I&#8217;ll drink anything! <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' />  )</p>
<p>over and out</p>
<p>Paul</p>
<p><!--adsense--></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2007/11/14/sharepoint-branding-the-governance-of-it-all-part-7/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>SharePoint Branding Part 6 &#8211; A &quot;solution&quot; to all issues?</title>
		<link>http://www.cleverworkarounds.com/2007/11/10/sharepoint-branding-part-6-a-solution-to-all-issues/</link>
		<comments>http://www.cleverworkarounds.com/2007/11/10/sharepoint-branding-part-6-a-solution-to-all-issues/#comments</comments>
		<pubDate>Fri, 09 Nov 2007 22:42:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Branding]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[Governance]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[Branding Series 1]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2007/11/10/sharepoint-branding-part-6-a-solution-to-all-issues/</guid>
		<description><![CDATA[There has been a bit of a gap in this series between part 5 and 6 &#8211; and fortunately for the both of us, I think this is the penultimate post in my series on SharePoint branding. While it has been an interesting exercise for me, I must confess each successive article is getting harder [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p>There has been a bit of a gap in this series between part 5 and 6 &#8211; and fortunately for the both of us, I think this is the penultimate post in my series on SharePoint branding. While it has been an interesting exercise for me, I must confess each successive article is getting harder to write as my interest is shifting <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />   So many sub-disciplines within MOSS &#8211; I think I might delve into WCM soon <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p><span id="more-265"></span></p>
<p>To recap for those of you hitting this page first, I suggest you go back and read this series in order.</p>
<ul>
<li><a href="http://www.cleverworkarounds.com/2007/10/08/sharepoint-branding-how-css-works-with-master-pages-part-1/">Part 1</a> dealt with the publishing feature, and some general masterpage/CSS concepts and some quirks (core.css and application.master) that have to be worked around.</li>
<li><a href="http://www.cleverworkarounds.com/2007/10/11/sharepoint-branding-how-css-works-with-master-pages-part-2/">Part 2</a> delved into the methods to work around the application.master and core.css issue</li>
<li><a href="http://www.cleverworkarounds.com/2007/10/13/sharepoint-branding-%e2%80%93-how-css-works-with-master-pages-%e2%80%93-part-3/">Part 3</a> delved further into the methods to work around the application.master and core.css issue and the option that solved a specific problem for me</li>
<li><a href="http://www.cleverworkarounds.com/2007/10/25/sharepoint-branding-part-4-packaging-up-your-masterpiece-into-a-feature/">Part 4</a> then changed tack and introduced how to package up your clever branding via features</li>
<li><a href="http://www.cleverworkarounds.com/2007/10/27/sharepoint-branding-part-5-%e2%80%93-feature-improvements-and-bugs/">Part 5</a> expanded on features and also noted a couple of major bugs that can catch you out if you aren&#8217;t aware of them</li>
</ul>
<p>Now, we will finish off on features and move onto solutions. As you will see, aside from playing a very important part in SharePoint deployment/governance process, solutions actually solve one of the bugs I mentioned in <a href="http://www.cleverworkarounds.com/2007/10/27/sharepoint-branding-part-5-%e2%80%93-feature-improvements-and-bugs/">part 5</a> &#8211; the one where deactivating and reactivating a branding feature does not always update the components. (More on that later).</p>
<p>In addition, whilst our feature is not too bad, it is not uber clever yet! As described in the previous article, a site collection administrator still has to manually perform some tasks after activating the feature. This may be totally fine, but generally, you would only activate a branding feature, if you meant to use it.</p>
<p>So presently, we have to pick the our master page from the master page list, as well as apply the right theme based CSS file as shown in the two images below.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/image15.png"><img border="0" src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb2.png" /></a></p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/image16.png"><img border="0" src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb3.png" /></a></p>
<p>We know how much of a strain those 2 steps must be to those bleating, underworked and overpaid site administrators, but fear not, lazy ones! We do have the means to do this automagically!</p>
<h2></h2>
<h2>Feature Receiver Assembly</h2>
<p>SharePoint features have the facility where you can write custom code that is triggered when certain events happen to features. It is a class called <a href="http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.spfeaturereceiver.aspx">SPFeatureReceiver</a> and when used, it traps events that are raised after Feature installation, uninstallation, activation, or deactivation action has been performed.</p>
<p>We are going to write some code that waits for the feature to be activated, and then set the master page for the site collection to pimpmysharepoint.master. While we are at it, we will do the CSS override too.</p>
<p>At this point if you are not a programmer, your eyes may glaze over at the stuff below. If you are happy to believe me that you can make the master page default to pimpmysharepoint.master then feel free to skip to the next section.</p>
<p>For the rest of you&#8230;</p>
<p>In our Feature.XML file, we add a new parameter in the &lt;feature&gt; XML element called &#8220;<a href="http://msdn2.microsoft.com/en-us/library/ms436075.aspx">ReceiverAssembly</a>&#8220;. It specifies the assembly holding the feature. Another parameter called ReceiverClass specifies the class within the aforementioned assembly. The XML element looks something like</p>
<p>ReceiverAssembly=&#8221;CleverWorkarounds.PimpMySharePoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c4r56efbb122b266&#8243;<br />
ReceiverClass =&#8221;CleverWorkarounds.PimpMySharePoint.SetDefaultMasterPage&#8221; &gt;</p>
<p>This now tells the feature that when the feature is installed, activated, deactivated or uninstalled, call the above assembly DLL and look in the CleverWorkarounds.PimpMySharePoint.SetDefaultMasterPage class.</p>
<p>Let&#8217;s look at that class source code.</p>
<p><font face="Courier New">namespace CleverWorkarounds.PimpMySharePoint<br />
{<br />
    public class SetDefaultMasterPage : Microsoft.SharePoint.SPFeatureReceiver<br />
    {<br />
        public override void FeatureActivated (SPFeatureReceiverProperties properties)<br />
        {<br />
            SPWeb MyCurrentWeb = properties.Feature.Parent as SPWeb;<br />
            MyCurrentWeb.MasterUrl = &#8220;/_catalogs/masterpage/pimpmysharepoint.master&#8221;;<br />
            MyCurrentWeb.CustomMasterUrl = &#8220;/_catalogs/masterpage/pimpmysharepoint.master&#8221;;<br />
            MyCurrentWeb.AlternateCSSURL = &#8220;/Style Library/pimpmintyfresh.css&#8221;;<br />
            MyCurrentWeb.Update();<br />
       }<br />
    }<br />
}</font></p>
<p>The namespace line (namespace CleverWorkarounds.PimpMySharePoint) matches the first part of the &#8220;ReceiverAssembly&#8221; parameter in the FEATURE.XML file. The class line (public class SetDefaultMasterPage : Microsoft.SharePoint.SPFeatureReceiver ) corresponds to the ReceiverClass parameter in the FEATURE.XML</p>
<p>Now SharePoint can find the DLL and the class to use.</p>
<p>Inside the class, it expects to find some code for each event. In the example above,  we are only looking at the &#8220;FeatureActivated&#8221; event. So this assembly will only do something on feature activation, not install/uninstall/deactivation.</p>
<p>Looking at the activated event, it&#8217;s pretty easy to see what is happening.</p>
<p>SPWeb MyCurrentWeb = properties.Feature.Parent as SPWeb;<br />
            MyCurrentWeb.MasterUrl = &#8220;/_catalogs/masterpage/pimpmysharepoint.master&#8221;;<br />
            MyCurrentWeb.CustomMasterUrl = &#8220;/_catalogs/masterpage/pimpmysharepoint.master&#8221;;<br />
            MyCurrentWeb.AlternateCSSURL = &#8220;/Style Library/pimpmintyfresh.css&#8221;;<br />
            MyCurrentWeb.Update();</p>
<p>This code gets the current site collection the feature has been activated on, and sets the master page to pimpmysharepoint.master and sets the default CSS override..</p>
<p>Here is the full FEATURE.XML that incorporates the featuredependency directive we talked about in the last post, along with the receiverclass.</p>
<p><font face="Courier New">&lt;Feature Id=”01c34560-6561-11dc-8314-0800200c9a66″<br />
    Title=”Pimp my SharePoint”<br />
    Description=”This is a feature that adds a new sexy CSS”<br />
    Version=”1.0.0.0&#8243;<br />
    Scope=”Site”<br />
    ReceiverAssembly=&#8221;CleverWorkarounds.PimpMySharePoint, Version=1.0.0.0, Culture=neutral,    PublicKeyToken=c4r56efbb122b266&#8243;<br />
    ReceiverClass =&#8221;CleverWorkarounds.PimpMySharePoint.SetDefaultMasterPage&#8221;<br />
    xmlns=”</font><a href="http://schemas.microsoft.com/sharepoint/”"><font face="Courier New">http://schemas.microsoft.com/sharepoint/”</font></a><font face="Courier New">&gt;<br />
    &lt;ActivationDependencies&gt;<br />
        &lt;ActivationDependency FeatureId=”F6924D36-2FA8-4f0b-B16D-06B7250180FA”/&gt;<br />
    &lt;/ActivationDependencies&gt;<br />
    &lt;ElementManifests&gt;<br />
        &lt;ElementManifest Location=”ProvisionedFiles.xml”/&gt;<br />
    &lt;/ElementManifests&gt;<br />
&lt;/Feature&gt; </font></p>
<p>So ,now the feature is much more clever. As clever as a branding feature needs to be. Of course, if the feature is deactivated, you should also write code against the deactivating event and reset all the customisations back to defaults, but for my purpose, this is <strong>clever!</strong></p>
<p>CleverWorkAround Rating &#8211; Sweeeeeet</p>
<h2>Uh-Oh, but what about the assembly DLL?</h2>
<p>Hang on a second! It&#8217;s all well and good to have a feature refer to an assembly DLL that you have written to do clever things, but what if that DLL isn&#8217;t there? Shall we be like Mythbusters and try anyway? <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </p>
<p><font face="courier new">C:\&gt;stsadm -o installfeature -name pimpmysharepoint</font></p>
<p><font face="courier new">Operation completed successfully.</font></p>
<p><img src="http://www.listal.com/image/28461/60.jpg" /> Damn, that myth is totally busted <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>Ah well, let&#8217;s activate the feature since &#8216;activation&#8217; was the only event we actually trapped for!</p>
<p><img src="http://shopping.discovery.com/DiscoveryStore/images/products/xxsmall/24704-038_XXS.jpg" /> YEAH BABY! A big, feral error runtime error! Now that is what I call a mythbusters moment!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2007/11/image.png"><img border="0" width="644" src="http://www.cleverworkarounds.com/wp-content/uploads/2007/11/image-thumb.png" alt="image" height="250" style="border-width: 0px" /></a></p>
<p>And for those lovely search engine spiders, here it is in plain text (in teeny tiny font because you probably don&#8217;t care that much about it anyway <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Anyway, the first line confirms it. &#8220;Feature x could not be installed because the loading of the event receiver assembly x failed&#8221;.</p>
<p><font size="1">Feature &#8217;01c34560-6561-11dc-8314-0800200c9a63&#8242; could not be installed because the loading of event receiver assembly &#8220;CleverWorkarounds.PimpMySharePoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c4r56efbb122b266&#8243; failed: System.IO.FileLoadException: Could not load file or assembly &#8216;CleverWorkarounds.PimpMySharePoint\, Version\=1.0.0.0\, Culture\=neutral\,\tPublicKeyToken\=c4r56efbb122b266&#8242; or one of its dependencies. The given assembly name or codebase was invalid. (Exception from HRESULT: 0&#215;80131047)<br />
File name: &#8216;CleverWorkarounds.PimpMySharePoint\, Version\=1.0.0.0\, Culture\=neutral\,\tPublicKeyToken\=c4r56efbb122b266&#8242;<br />
   at System.Reflection.AssemblyName.nInit(Assembly&amp; assembly, Boolean forIntrospection, Boolean raiseResolveEvent)<br />
   at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark&amp; stackMark, Boolean forIntrospection)<br />
   at System.Reflection.Assembly.Load(String assemblyString)<br />
   at Microsoft.SharePoint.Administration.SPFeatureDefinition.get_ReceiverObject() </font></p>
<p><font size="1">   at Microsoft.SharePoint.Administration.SPFeatureDefinition.get_ReceiverObject()<br />
   at Microsoft.SharePoint.SPFeature.DoActivationCallout(Boolean fActivate, Boolean fForce)<br />
   at Microsoft.SharePoint.SPFeature.Deactivate(SPSite siteParent, SPWeb webParent, Boolean fForce)<br />
   at Microsoft.SharePoint.SPFeatureCollection.Remove(Guid featureId, Boolean force)<br />
   at Microsoft.SharePoint.SPFeatureCollection.Remove(Guid featureId)<br />
   at Microsoft.SharePoint.ApplicationPages.DeactivateFeaturePage.LnkbtnDeactivateFeature_Click(Object objSender, EventArgs evtargs)<br />
   at System.Web.UI.WebControls.LinkButton.OnClick(EventArgs e)<br />
   at System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument)<br />
   at System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)<br />
   at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)<br />
   at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)<br />
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) </font></p>
<p>So, it should now be obvious that the DLL holding your event receiver class should be deployed to your web front end servers, either in the GAC, or in the BIN folder of each web app under INETPUB.</p>
<p>But how lame is that? You go to all that trouble to make a auto-installing feature and then you need to manually do this bit??? Isn&#8217;t that a little counter intuitive?</p>
<p>Fear not readers, you now know why SharePoint &#8220;Solutions&#8221; are the things that REALLY matter!</p>
<h2>SharePoint Solutions &#8211; The plain english description</h2>
<p>Back in this <a href="http://www.cleverworkarounds.com/2007/10/08/sharepoint-%E2%80%9Cfeatures%E2%80%9D-in-plain-english/">early post</a>, I defined SharePoint Features as &#8220;a method to add/customise many areas of SharePoint&#8221;. Well, guess what, so are solutions as well! So what is the difference between the two?</p>
<p>Well, to answer that, let&#8217;s consider some of the things that you cannot do in a feature.</p>
<ul>
<li>You cannot deploy an assembly to the GAC</li>
<li>You cannot edit the web.config of a web application</li>
<li>You cannot install a feature to all web front end servers in a farm at once</li>
</ul>
<p>The latter is an important one. One of my clients has a 5 server farm with 3 WFE servers. If say, I have to update a webpart, I have to put the assembly into the GAC on all three servers. I then have to edit web.config on the web applications to mark the control as safe.</p>
<p>This is not only tedious but risky. Mistakes can be made, leaving WFE servers in an inconsistent state. (Hands up who has killed a web application because of a mistake in web.config. I bet all of you!)</p>
<p>If we have to roll back to a previous version, we have to do it manually on all three WFE servers. Also, what if we have several related features to install at once? That&#8217;s a lot of manual work and I am cheap and lazy!</p>
<p>So, <a href="http://msdn2.microsoft.com/en-us/library/aa543214.aspx">MSDN</a> says this about solutions: &#8220;The Microsoft Windows SharePoint Services solution framework provides a way to bundle all of the components for extending Windows SharePoint Services in a new file, called a solution file. A solution file is a cabinet or .CAB-based format with a .wsp extension. A solution is a deployable, reusable package that can contain a set of features, site definitions, and assemblies that you can apply to a site, and can also enable or disable individually. You can use the solution file to deploy the contents of a Web Part package, including assemblies, class resources, .dwp files, and other package components&#8221;</p>
<p>Therefore, to really be clever with the deployment of our clever branding, we now need to take our feature, and add it to a solution, that also copies the feature receiver assembly (DLL) into the GAC. In addition, the solution will do this consistently to all WFE servers, ensuring that they are consistent. If any one of them has a problem, we can roll back the solution deployment, fix the issue, and then re-deploy the solution.</p>
<p>CleverWorkAround Rating: Mandatory! If it is not a solution, I ain&#8217;t putting it in!!</p>
<h2></h2>
<h2>Okay so how do I build my solution then?</h2>
<p>Well, I have to say, when MOSS07/WSS3 came out, this was a truly <a href="http://msdn2.microsoft.com/en-us/library/bb466225.aspx">ugly</a> process. In the last year, plenty of clever people have written tools to make the job easier.  Let&#8217;s examine the one I use: <a href="http://www.codeplex.com/wspbuilder">WSPBUILDER</a></p>
<p>I won&#8217;t fully detail the product &#8211; hey that&#8217;s what the wspbuilder site is for. But I will explain how to use it for the purpose of this branding exercise.</p>
<p>So assuming you have WspBuilder installed, we have two things to install.</p>
<ol>
<li>The &#8220;CleverWorkarounds.PimpMySharePoint.DLL&#8221; eventreceiver assembly.</li>
<li>The PIMPMYSHAREPOINT feature</li>
</ol>
<p>To create the solution, you can follow these basic steps (although real SharePoint developers will snigger at this, as I am not integrating this into a visual studio project).:</p>
<ul>
<li>In the folder where WspBuilder was installed (I&#8217;ll assume C:\Program Files\WSPBuilder for now), create the following folder structure if it does not exist:
<ul>
<li>12\Template\Features (eg C:\Program Files\WSPBuilder<strong>\</strong>12\Template\Features)</li>
</ul>
</li>
<li>Copy the PIMPMYFEATURE folder into the above folder, resulting in C:\Program Files\WSPBuilder<strong>\</strong>12\Template\Features\PimpMySharePoint</li>
<li>In the folder where WspBuilder was installed (I&#8217;ll assume C:\Program Files\WSPBuilder), create the GAC folder if it does not exist:
<ul>
<li>C:\Program Files\WSPBuilder\GAC</li>
</ul>
</li>
<li>Copy the CleverWorkarounds.PimpMySharePoint.DLL<strong> </strong>assembly to the C:\Program Files\WSPBuilder\GAC folder</li>
<li>Open a command prompt, and CD to the location of wspbuilder
<ul>
<li>cd \program files\wspbuilder</li>
</ul>
</li>
<li>Type wspbuilder at the prompt and press Enter
<ul>
<li>c:\program files\wspbuilder&gt;wspbuilder</li>
</ul>
</li>
<li>The wspbuilder program will package up your components and create three files.
<ul>
<li>wspbuilder.wsp</li>
<li>manifest.xml       </li>
<li>solutionid.txt</li>
</ul>
</li>
</ul>
<p>For those of you who are really interested, the WSP file name will default to the name of the folder where WSPBUILDER.EXE resides. I strongly suggest renaming this to a meaningful name or running wspbuilder from an appropriately named folder. For our purposes, I renamed it to pimpmysharepoint.wsp.</p>
<p>Right! Now we have our magical WSP file. We need to add this solution to the SharePoint farm &#8216;solution store&#8217;, and then deploy this solution.</p>
<h2>Deploying the solution and testing</h2>
<p>To add the solution to the store, we use the STSADM command. But first, let&#8217;s clean up so we can test this.</p>
<p>Firstly, delete or rename the pimpmysharepoint feature in the C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES folder. We want to see that the solution adds it back when deployed.</p>
<p>Also check the C:\WINDOWS\ASSEMBLY and ensure your assembly is not in the GAC. If it is, remove it.</p>
<p>So, back to STSADM. Below is the syntax..</p>
<p><font face="Courier New">C:\Program Files\WSPBuilder&gt;stsadm -o addsolution -filename pimpmysharepoint.wsp </font></p>
<p><font face="Courier New">Operation completed successfully. </font></p>
<p><font face="Courier New">C:\Program Files\WSPBuilder&gt; </font></p>
<p>Okay, now what? Well.. we now <strong>deploy</strong> this feature.</p>
<p>Deployment can be performed via STSADM or SharePoint Central Administration. I actually prefer central administration because it tells me more and leaves less to chance. (I tend to type badly and make spelling errors <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>In Central Administration, navigate to Operations -&gt; Solutions Management under &#8220;Global Configuration&#8221;</p>
<p>Well how about that! There is our pimpmysharepoint.wsp file. Note that its status is &#8220;not deployed&#8221;.</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2007/11/image1.png"><img border="0" width="644" src="http://www.cleverworkarounds.com/wp-content/uploads/2007/11/image-thumb1.png" alt="image" height="138" style="border-width: 0px" /></a></p>
<p>I guess the only thing to do is to deploy it then! <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Clicking the pimpmysharepoint.wsp link presents us with the solution deployment screen. Here we can see a summary of the solution. One of the key thing that we can see is that our solution contains an assembly DLL (&#8220;contains global assembly&#8221; is YES)</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2007/11/image2.png"><img border="0" width="574" src="http://www.cleverworkarounds.com/wp-content/uploads/2007/11/image-thumb2.png" alt="image" height="301" style="border-width: 0px" /></a></p>
<p>Click &#8220;Deploy Solution&#8221;. The next screen is the most important one of all. We are provided with a means to deploy this solution at a later time (perhaps on a weekend or other quiet time). The other really interesting thing is because this solution is of type &#8220;web front end server&#8221; (see previous image), we have the choice of which web application to deploy this solution to.</p>
<p>This is really important! Just because we have a solution added to the farm solution store, does not mean that we want to pimpmysharepoint feature installed on every web application.</p>
<p>I personally prefer to specify the web application the feature is for, rather than deploy to all of them. For a start, if you deploy to all, you are including the central administration site itself, as well as the SSP sites. I think 95% of the time they don&#8217;t need it. I&#8217;d rather keep such an important web application nice and vanilla).</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2007/11/image3.png"><img border="0" width="644" src="http://www.cleverworkarounds.com/wp-content/uploads/2007/11/image-thumb3.png" alt="image" height="320" style="border-width: 0px" /></a></p>
<p>For what its worth, depending on the solution components and scope, you can pick all or one web application to deploy to. If you have more than one web application that needs this feature, you can come back into this screen again via the solution management section in central admin. From there you are able to choose another web application.</p>
<p>Regardless of this, the assembly only gets loaded into the GAC once! It will do a version check if it finds one already there.</p>
<p>Click OK and if all goes to plan, the solution is deployed!</p>
<p>Let&#8217;s go and check!</p>
<p>First up, examine C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES folder. Is there a PIMPMYSHAREPOINT folder? Yes indeedie!</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2007/11/image4.png"><img border="0" width="644" src="http://www.cleverworkarounds.com/wp-content/uploads/2007/11/image-thumb4.png" alt="image" height="224" style="border-width: 0px" /></a></p>
<p>Secondly, is our DLL in the GAC? Yep..</p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2007/11/image5.png"><img border="0" width="310" src="http://www.cleverworkarounds.com/wp-content/uploads/2007/11/image-thumb5.png" alt="image" height="192" style="border-width: 0px" /></a></p>
<p>So things seems to be looking good!</p>
<p>Note! If we had several WFE servers, in this case, the feature and assembly would be been installed on all WFE servers for the solution to successfully be deployed. From a governance point of view, this is a significant time saver and ensures all WFE servers are consistent.  If say, the deployment of the solution failed for one WFE server, you will be notified of the failure.</p>
<h2></h2>
<h2>Upgrades and rollback</h2>
<p>But it gets even better. Solutions can be upgraded. So you have new master page content and optimise the code in your feature receiver event handler. Simply recreate the WSP file using WSPBuilder. Then you can replace the existing solution with your updated one.</p>
<p>The beauty of this is that an upgraded solution will update the feature, install the newer assembly on all WFE servers. In addition, if something goes wrong, SharePoint will automatically roll back to the pre-upgrade solution as well!</p>
<p>A solution is upgraded when a newer WSP file is created. The STSADM -o upgradesolution command is used to do the upgrade. For example.</p>
<p><font face="Courier New">C:\Program Files\WSPBuilder&gt;stsadm -o upgradesolution -name pimpmysharepoint.wsp -filename pimpmysharepoint-v2.wsp </font></p>
<p>Want to retract a deployed solution from a site? That&#8217;s easy too. You can do it via the solution management admin screen in central administration or use the STSADM -o retractsolution command. You can retract a solution from one or all web applications as well.</p>
<p>In our sample, retracting a solution from a web application will remove the feature from the feature list. You will no longer be able to activate it.</p>
<p>Finally, you can completely remove the solution as well. This will do a complete cleanup. The PIMPMYSHAREPOINT feature folder will be deleted from C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES  and the cleverworkarounds.pimpmysharepoint assembly will be removed from the GAC.</p>
<h2></h2>
<h2>But wait! there&#8217;s more!</h2>
<p>If I haven&#8217;t convinced you enough already, I will give you one more reason. In <a href="http://www.cleverworkarounds.com/2007/10/27/sharepoint-branding-part-5-%e2%80%93-feature-improvements-and-bugs/">part 5</a> of this series, I outlined the stupidly annoying issue where the deactivation and reactivation of a branding feature will not work properly. Specifically, feature files will <strong>not be overwritten </strong>when they have been modified via publishing a new version of files within the site collection galleries. &#8220;Seems that as soon as a <strong>new version </strong>has been published, any updates via a feature <strong>will not overwrite</strong>. The feature gives no indication that this has occurred either!&#8221;</p>
<p>But guess what! When you upgrade a solution via STSADM -o upgradesolution, this issue does not occur. All updates to features that are packaged into a solution get properly distributed to any site collection that has the pimpmysharepoint branding feature activated!</p>
<p>Why the behaviour is different when deactivating and activating a feature is anybody&#8217;s guess, but it works for me!</p>
<h2>Summing Up</h2>
<p>My aim in this article was to educate and convince you that solution&#8217;s the best way to install features. Notwithstanding the fix for my annoying feature bug, the ability to push out updates across multiple servers consistently, and ease of upgrades and retracting make your complex environment just that little bit more manageable.</p>
<p>So if a 3rd party tells you &#8220;oh just put this updated DLL into the GAC&#8221;, politely tell them that if it is not packaged into a solution, you are not going to do it! <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Might sound tough, but there is pretty good reasoning behind this attitude. My <a href="http://www.cleverworkarounds.com/2007/11/14/sharepoint-branding-the-governance-of-it-all-part-7/">last post</a> of this branding series will expand on this sort of thing when I cover the governance of SharePoint branding, based on all we have learned so far.</p>
<p>For now though, I hope you found this post useful!</p>
<p><!--adsense--></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2007/11/10/sharepoint-branding-part-6-a-solution-to-all-issues/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Finally &#8211; clever filtered lookups!</title>
		<link>http://www.cleverworkarounds.com/2007/11/06/finally-clever-filtered-lookups/</link>
		<comments>http://www.cleverworkarounds.com/2007/11/06/finally-clever-filtered-lookups/#comments</comments>
		<pubDate>Mon, 05 Nov 2007 22:24:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Branding]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[Solutions]]></category>
		<category><![CDATA[columns]]></category>
		<category><![CDATA[datacogs]]></category>
		<category><![CDATA[filtered lookups]]></category>
		<category><![CDATA[lists]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2007/11/06/finally-clever-filtered-lookups/</guid>
		<description><![CDATA[Pretty much since I started with MOSS2007 (and back in the pre 2007 days too), I&#8217;ve required smarter drop down choices for my columns. Basically, I needed a secondary drop down list filtered based on the choice from a primary drop down list &#8211; the whole category/sub category thing. Seems amazing to me that it [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p>Pretty much since I started with MOSS2007 (and back in the pre 2007 days too), I&#8217;ve required smarter drop down choices for my columns. Basically, I needed a secondary drop down list filtered based on the choice from a primary drop down list &#8211; the whole category/sub category thing. Seems amazing to me that it is not available out of the box.</p>
<p>On my to-do list was to write a detailed post critiquing all the workarounds out there (such as <a href="http://blog.u2u.info/DottextWeb/patrick/articles/466.aspx">Patrick&#8217;s Javascript method</a> and <a href="http://dattard.blogspot.com/2007/04/sharepoint-2007-filtered-lookups.html">Dattard&#8217;s designer work</a>) and rate their cleverness &#8211; as per the branding series.</p>
<p><span id="more-250"></span><br />
But why bother now? Fellow aussies and clever guys at DataCogs Infomation Technology have provided the best workaround yet via two well coded custom field controls , all packaged up into a solution &#8211; too damn easy!
</p>
<p><a title="http://datacogs.com/datablogs/archive/2007/08/26/641.aspx" href="http://datacogs.com/datablogs/archive/2007/08/26/641.aspx">http://datacogs.com/datablogs/archive/2007/08/26/641.aspx</a></p>
<p>This for me is the mother of all clever workarounds. It is a snap to install and activate and source code is provided. What&#8217;s more, the primary/secondary lists can be on different sites. How good is that!</p>
<p>So, thanks, fellas, you have saved me writing a long blog post <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>CleverWorkarounds Rating: <strong>Pure Genius</strong></p>
<p><!--adsense--></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2007/11/06/finally-clever-filtered-lookups/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SharePoint Branding Part 5 &#8211; Feature Improvements and Bugs</title>
		<link>http://www.cleverworkarounds.com/2007/10/27/sharepoint-branding-part-5-%e2%80%93-feature-improvements-and-bugs/</link>
		<comments>http://www.cleverworkarounds.com/2007/10/27/sharepoint-branding-part-5-%e2%80%93-feature-improvements-and-bugs/#comments</comments>
		<pubDate>Fri, 26 Oct 2007 17:14:32 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Branding]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[SharePoint]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[master pages]]></category>
		<category><![CDATA[Branding Series 1]]></category>
		<category><![CDATA[SharePoint Branding]]></category>
		<category><![CDATA[SharePoint Features]]></category>

		<guid isPermaLink="false">http://www.cleverworkarounds.com/2007/10/27/sharepoint-branding-part-5-%e2%80%93-feature-improvements-and-bugs/</guid>
		<description><![CDATA[So, here we are at the fifth article in my series on SharePoint branding. By now, we have left all the master page stuff way behind, and we have created a custom feature to install our branding to a server. To recap for those of you hitting this page first, I suggest you go back [...]<p class="tags">No Tags</p>]]></description>
			<content:encoded><![CDATA[<p><!--adsense--></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, here we are at the fifth article in my series on SharePoint branding. By now, we have left all the master page stuff way behind, and we have created a custom feature to install our branding to a server.<br />
</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">To recap for those of you hitting this page first, I suggest you go back and read this series in order.<br />
</font></span></p>
<ul style="margin-left: 41pt">
<li><a href="http://www.cleverworkarounds.com/2007/10/08/sharepoint-branding-how-css-works-with-master-pages-part-1/"><span style="font-size: 14pt; color: #669966; font-family: trebuchet ms; text-decoration: underline"><font size="2">Part 1</font></span></a><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2"> dealt with the publishing feature, and some general masterpage/CSS concepts and some quirks (core.css and application.master) that have to be worked around.<br />
</font></span></li>
<li><a href="http://www.cleverworkarounds.com/2007/10/11/sharepoint-branding-how-css-works-with-master-pages-part-2/"><span style="font-size: 14pt; color: #669966; font-family: trebuchet ms; text-decoration: underline"><font size="2">Part 2</font></span></a><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2"> delved into the methods to work around the application.master and core.css issue<br />
</font></span></li>
<li><a href="http://www.cleverworkarounds.com/2007/10/13/sharepoint-branding-%e2%80%93-how-css-works-with-master-pages-%e2%80%93-part-3/"><span style="font-size: 14pt; color: #669966; font-family: trebuchet ms; text-decoration: underline"><font size="2">Part 3</font></span></a><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2"> delved further into the methods to work around the application.master and core.css issue and the option that solved a specific problem for me<br />
</font></span></li>
<li><a href="http://www.cleverworkarounds.com/2007/10/25/sharepoint-branding-part-4-packaging-up-your-masterpiece-into-a-feature/"><span style="font-size: 14pt; color: #669966; font-family: trebuchet ms; text-decoration: underline"><font size="2">Part 4</font></span></a><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2"> then changed tack and introduced how to package up your clever branding<br />
</font></span></li>
</ul>
<p><span style="font-size: 14pt; font-family: trebuchet ms"></span></p>
<p><span id="more-248"></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Now we will move onto some more advanced aspects of features to make it more clever and identify two really annoying bugs that can make the whole experience painful. You should be aware of them.<br />
</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, picking up where we left off, we have a feature that we successfully deployed to the SharePoint server. It performed the tasks of copying CSS files to the style library of the activated site collection and copying the master page file to the master page gallery.</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">As described in the previous article, we still have to manually perform some tasks after activating the feature. We have to pick the PIMPMYSHAREPOINT.MASTER from the master page list, as well as apply the right theme based CSS file as shown in the three images below.<br />
</font></span></p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/clip-image001.gif"><font size="2"><img border="0" src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb1.gif" /></font></a><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/image15.png"><font size="2"><img border="0" src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb2.png" /></font></a><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/image16.png"><font size="2"><img border="0" src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb3.png" /></font></a><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">This is clever, in the sense that site collection and farm administrators do not have to worry about manually copying the files into the style library and master page gallery, but it&#8217;s still a manual task. In addition, as discussed in prior articles, this all depends on the &#8220;Office SharePoint Server Publishing Infrastructure&#8221; feature need to be active first.</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Let&#8217;s see what happens, if it is not <strong>activated. </strong></font></span></p>
<h2>Breaking the rules <span style="font-size: 18pt; font-family: trebuchet ms"></span></h2>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Below, you can see that the publishing feature is not active. (The lack of ability to pick a new master page is a tell-tale sign).</font></span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb4.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">To make 100% sure we are dealing with a clean site with no publishing, let&#8217;s examine the site in SharePoint Designer. Does a style library exist? Nah-uh!</font></span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb5.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, first up, let&#8217;s see if <strong>our </strong>feature will install and activate.</font></span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb6.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">C:\&gt;stsadm -o installfeature -name PimpMySharePoint</font></span><span style="font-family: trebuchet ms"><br />
</span></span></p>
<p><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">Operation completed successfully.</font></span><span style="font-family: trebuchet ms"><br />
</span></span></p>
<p><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">C:\wspbuilder&gt;</font></span></span><span style="font-size: 14pt"><span style="font-family: trebuchet ms"></span></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, what can we conclude from this? It seems feature dependencies do not prevent the <strong>installation</strong> of the feature to the server.<br />
</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Ah, but of course, we all know by now that a feature has no effect until it&#8217;s activated. So, let&#8217;s do that next for a test site.</font></span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb7.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">GONG! We have a problem. Something went wrong!<br />
</font></span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb8.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Now the error message here sucks in terms of readability, I wonder what list does not exist? The style library maybe?</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2"><em>Failed to instantiate file &#8220;PimpMintyFresh.css&#8221; from module &#8220;MyPimpedStyles&#8221;: The specified list does not exist.   at Microsoft.SharePoint.Library.SPRequestInternalClass.EnableModuleFromXml(String bstrFeatureDirectory, String bstrUrl, String bstrXML)<br />
   at Microsoft.SharePoint.Library.SPRequest.EnableModuleFromXml(String bstrFeatureDirectory, String bstrUrl, String bstrXML</em><br />
</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Looking closely at the message, it is saying that it tried to copy PimpMintyFresh.CSS to the location defined my the module MyPimpedStyles. As a refresher, here the the XML file containing the module directive.</font></span></p>
<p><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">&lt;Elements xmlns=&#8221;</font><a href="http://schemas.microsoft.com/sharepoint/"><span style="color: #669966; text-decoration: underline"><font size="2">http://schemas.microsoft.com/sharepoint/&#8221;</font></span></a><font size="2">&gt;<br />
    </font><font size="2"><strong>&lt;Module Name=&#8221;MyPimpedStyles&#8221; Url=&#8221;Style Library&#8221; RootWebOnly=&#8221;TRUE&#8221;&gt;       <br />
        &lt;File Url=&#8221;PimpMintyFresh.jpg&#8221; Type=&#8221;GhostableInLibrary&#8221; /&gt;   <br />
</strong>        &lt;File Url=&#8221;PimpMySharePoint.css&#8221; Type=&#8221;GhostableInLibrary&#8221; /&gt;    <br />
[snip]</font></span><span style="font-family: trebuchet ms"><br />
</span></span></p>
<p><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">    &lt;/Module&gt;<br />
&lt;/Elements&gt;</font></span></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Can you see the &lt;module&gt; directive that has a parameter called &#8220;name&#8221; with a value of MypimpedStyles? The other parameter in &lt;module&gt; is the URL parameter, which for MypimpedStyles is &#8220;Style Library&#8221;.</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">The error states &#8220;The specified list does not exist&#8221;, which means that there is no &#8220;Style Library&#8221;. Makes sense doesn&#8217;t it &#8211; as the publishing feature, not yet activated, has not created it?<br />
</font></span></p>
<h2>Okay let&#8217;s obey the rules then!</h2>
<p><span style="font-size: 18pt; font-family: trebuchet ms"><font size="2"><br />
</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, after breaking it by trying our feature without its pre-requisites, let&#8217;s now be good children and activate the pre-requisite publishing feature before retrying this process.</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Step 1. Activate the &#8220;Office SharePoint Server Publishing Infrastructure&#8221;</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">GONG! WHAT THE?&#8230; An error now!</font></span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb9.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">The explanation is a hint&#8230;</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">&#8220;The specified name is already in use&#8221;</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">&#8230;and the full text version for uncle google <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </font></span></p>
<p><span style="font-family: trebuchet ms"><span style="font-size: 10pt">&#8220;A list, survey, discussion board, or document library cannot have the same name as another list, survey, discussion board, or document library in this Web site.  Use your browser&#8217;s Back button, and type a new name.   at Microsoft.SharePoint.Library.SPRequestInternalClass.CreateList(String bstrWebUrl, String bstrTitle, String bstrDescription, String bstrListUrl, String bstrFeatureId, Int32 lTemplateID, String bstrDocTemplateType, ListQuickLaunchOptions qlOpt)<br />
   at Microsoft.SharePoint.Library.SPRequest.CreateList(String bstrWebUrl, String bstrTitle, String bstrDescription, String bstrListUrl, String bstrFeatureId, Int32 lTemplateID, String bstrDocTemplateType, ListQuickLaunchOptions qlOpt) &#8220;</span></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So what could be causing this? Let&#8217;s look again at the site in SharePoint Designer.</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">AHA! &#8211; A style library folder got created &#8211; nice error checking MS!<br />
</font></span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb10.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">But this &#8220;Style library&#8221; must be a folder, not a document library because of the previous error message &#8220;The specified list does not exist&#8221;.</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Anyway, the obvious thing to do is to delete this style library. So let&#8217;s do that using Designer and then re-attempt activating the publishing feature.</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Aaah &#8230; That&#8217;s better!</font></span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb11.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, for educational value, have a look at the site now in designer. As you can see below, the publishing feature adds a lot of stuff! If you want more detail on what the publishing feature adds to a site collection, check my </font><a href="http://www.cleverworkarounds.com/2007/10/08/sharepoint-branding-how-css-works-with-master-pages-part-1/"><span style="color: #669966; text-decoration: underline"><font size="2">first post</font></span></a><font size="2"> in this series or head over to </font><a href="http://www.mindsharpblogs.com/Penny/archive/2007/09/28/2973.aspx"><span style="color: #669966; text-decoration: underline"><font size="2">Penny&#8217;s</font></span></a><font size="2"> blog.</font></span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb12.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, although we have been clever in creating a feature for our branding, it&#8217;s just not darn clever enough. I wonder if we can make this better?</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">CleverWorkaround Rating &#8211; better than nothing<br />
</font></span></p>
<h2>Being Cleverer</h2>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">(is &#8216;cleverer&#8217; a word?)</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Another XML element that we can add to our FEATURE.XML is called, <strong>&#8220;ActivationDependencies&#8221;. </strong>MSDN explains it all but it&#8217;s pretty self explanatory anyway. Here is an example of an activationdependence for the publishing feature.</font></span></p>
<p><span style="font-size: 10pt; font-family: courier new">&lt;ActivationDependencies&gt;</span></p>
<p><span style="font-size: 10pt; font-family: courier new"></span><span style="font-size: 10pt; font-family: courier new">&lt;ActivationDependency FeatureId=&#8221;F6924D36-2FA8-4f0b-B16D-06B7250180FA&#8221;/&gt;</span><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span><span style="font-size: 10pt; font-family: courier new">&lt;/ActivationDependencies&gt;</span><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">How do we know that this is the Publishing Feature? The FeatureID refers to the GUID of the FEATURE.XML for that feature. (So now it should make sense why each feature needs a unique GUID).<br />
</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So here is the amended FEATURE.XML.</font></span></p>
<p><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">&lt;Feature Id=&#8221;01c34560-6561-11dc-8314-0800200c9a66&#8243;</font></span></span></p>
<p><span style="font-size: 14pt"><span style="font-family: courier new"></span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">Title=&#8221;Pimp my SharePoint&#8221;</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">Description=&#8221;This is a feature that adds a new sexy CSS&#8221;</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">Version=&#8221;1.0.0.0&#8243;</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">Scope=&#8221;Site&#8221;</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">xmlns=&#8221;http://schemas.microsoft.com/sharepoint/&#8221;&gt;</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">&lt;ActivationDependencies&gt;</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">&lt;ActivationDependency FeatureId=&#8221;F6924D36-2FA8-4f0b-B16D-06B7250180FA&#8221;/&gt;</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">&lt;/ActivationDependencies&gt;</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">&lt;ElementManifests&gt;</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">&lt;ElementManifest Location=&#8221;ProvisionedFiles.xml&#8221;/&gt;</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">&lt;/ElementManifests&gt;</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">&lt;/Feature&gt;</font></span><span style="font-family: trebuchet ms"><br />
</span></span></p>
<h2>Backing out..</h2>
<p><span style="font-size: 18pt; font-family: trebuchet ms"></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, now we get to see one of the main benefits of features. The fact that they can be deactivated and uninstalled. The process is basically the reverse of the install/activate process. We deactivate the feature on all sites where it is used, and then we uninstall the feature. We then install our new feature.</font></span></p>
<p><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">C:\&gt;stsadm -o uninstallfeature -name pimpmysharepoint</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">Operation completed successfully.</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">C:\&gt;stsadm -o installfeature -name pimpmysharepoint</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">Operation completed successfully.</font></span><span style="font-family: trebuchet ms"><br />
</span></span><span style="font-size: 14pt"><span style="font-family: courier new"><font size="2">C:\&gt;</font></span><span style="font-family: trebuchet ms"><br />
</span></span></p>
<h2>Reactivating</h2>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, now let&#8217;s activate our feature with this dependency information. That&#8217;s better&#8230; we get a friendly message that lists the feature by name (even though we only supplied the GUID).</font></span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb13.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, we do as asked and activate the publishing feature. Now let&#8217;s re-attempt the install of our feature.<br />
</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Yay</font></span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb14.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, now we check the style library &#8211; all good!</font></span></p>
<p><a href="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/image16.png"><font size="2"><img border="0" src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb15.png" /></font></a><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<h2>The next experiment</h2>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">At this point, I need to acknowledge the value of </font><a href="http://www.andrewconnell.com/blog/archive/2006/12/20/5451.aspx"><span style="color: #669966; text-decoration: underline"><font size="2">Andrew Connell&#8217;s</font></span></a><font size="2"> blog. We are going to discuss some interesting quirks in the next section, and his site was really useful.<br />
</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, the next experiment. Let&#8217;s deactivate this feature and reactivate it to see what actually gets removed. Click deactivate against the pimpmysharepoint feature and accept the obligatory warning.</font></span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb16.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">It has deactivated ok.<br />
</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, let&#8217;s check the style library again. Interesting &#8211; the files are still there. I initially thought that a feature would clean up after itself. But <a href="http://www.andrewconnell.com/blog/archive/2006/12/20/5451.aspx">Yoda Andrew</a>, sets the record straight.</font></span></p>
<p>&#8220;That is by design. Deactivation of features does not remove data that was created when the feature was activated. if you want to &#8220;clean up&#8221; the data that was created, you need to create a Feature receiver handler and have the FeatureDeactivating() event handler manually remove the file.&#8221;</p>
<p>and</p>
<p>&#8220;Keep in mind though, data is left in SharePoint BY DESIGN. What would happen if you had deployed a page layout with a Feature and someone removed it while it was in use by thousands of pages? Oops&#8230; blamo!&#8221;</p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Andrew has spoken &#8211; amen!</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, that left me wondering what happens when a feature is reactivated. Do newer files overwrite these orphans?</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Test 1: Update master page in the feature definition and reactivate</font></span></p>
<ul>
<li><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Update master page with small change and copy to the feature folder</font></span></li>
<li><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Deactivate the feature</font></span></li>
<li><span style="font-size: 14pt"><span style="font-family: trebuchet ms"><font size="2">Check if the site still renders with the feature deactivated</font></span></span></li>
<li><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Uninstall the feature</font></span></li>
<li><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Install the Feature</font></span></li>
<li><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Reactivate the Feature</font></span></li>
<li><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Re-Examine site. Master page changes are reflected</font></span></li>
</ul>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Test Passed!</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Test 2. Publish a master page as a major version in SharePoint designer and repeat test 1.</font></span></p>
<ul style="margin-left: 41pt">
<li><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Make a benign change and publish it as a major version<br />
</font></span></li>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb17.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></ul>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb18.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb19.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt"><span style="font-family: trebuchet ms"></span></span></p>
<ul>
<li><span style="font-size: 14pt"><span style="font-family: trebuchet ms"><font size="2">Deactivate and uninstall feature</font></span></span></li>
<li><span style="font-size: 14pt"><span style="font-family: trebuchet ms"><font size="2">Check if the site still renders with the feature deactivated</font></span></span></li>
<li><span style="font-size: 14pt"><span style="font-family: trebuchet ms"><font size="2">Update the master page file and recreate the feature</font></span></span></li>
<li><span style="font-size: 14pt"><span style="font-family: trebuchet ms"><font size="2">Reactivate the feature on the site collection</font></span></span></li>
<li><span style="font-size: 14pt"><span style="font-family: trebuchet ms"><font size="2">Check the site &#8211; the rendering does NOT reflect the updated master page in the feature.<br />
</font></span></span><span style="font-size: 14pt; font-family: trebuchet ms"></span></li>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Test Failed!</font></span></ul>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">The feature has <strong>not </strong>overwritten the master page on the site. Seems that as soon as a <strong>new version </strong>has been published, any updates via a feature <strong>will not overwrite</strong>. The feature gives no indication that this has occurred either! This is serious! So, how can we re-push out branding? T</font></span><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">his breaks the whole model. </font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Another bug? By design?</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">CleverWorkaround Rating: Shame, Shame, Shame<br />
</font></span></p>
<h2>More Gripes</h2>
<p><span style="font-size: 18pt; font-family: trebuchet ms"></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, I think to myself, what if I delete the master page from the gallery prior to deactivating, reinstalling and reactivating the feature? Sure, it defeats the purpose of feature based updates as it introduces a manual step, but maybe it will solve the problem.</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">I tried and deleted it and I got this error.</font></span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb20.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Okay, makes sense. I forgot to set the master page of the site collection back to default.master or something else. So I did that and re-attempted.<br />
</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">GONG! Same issue! &#8211; Not having a good SharePoint day.</font></span></p>
<p><font size="2"><img src="http://www.cleverworkarounds.com/wp-content/uploads/2007/10/102607-1713-sharepointb21.png" /></font><span style="font-size: 14pt; font-family: trebuchet ms"><br />
</span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Now, I will cut a long story short here and explain this bug to you. It&#8217;s a different one from the master page not being updated by the feature, but is just as annoying. </font></span><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">If you create a new site collection with no sub-sites, the master page above will delete just fine once you stop using it. But if you have made any sub-sites you may have this problem.</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">What seems to happen is this. If you make a <strong>sub-site</strong>, and then tell it to <strong>inherit the master page settings </strong>from the parent, AND then <strong>delete </strong>that sub-site, SharePoint seems to &#8216;forget&#8217; to update its internal status that the master page is no longer used for the deleted sub-site. Thus, you are prevented from deleting, when it is actually not in use. </font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"></span><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Check this KB article, it describes the issue but not the cause. </font><a href="http://support.microsoft.com/kb/926812"><span style="color: #669966; text-decoration: underline"><font size="2">http://support.microsoft.com/kb/926812</font></span></a></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, would you believe that in real life, I got nailed by both these two bugs at the same time! Made troubleshooting a real bitch I can tell you!</font></span></p>
<h2>Wrapping up</h2>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">So, to sum up, features are a &#8220;good thing&#8221; &#8482; and you should use them and also mandate their use. As I have demonstrated, they are beset by a couple of bugs that can give you a few more grey hairs, but once you are aware of this, they can be worked around with some governance rules. I hope, though, that Microsoft fix this rather soon &#8211; as it&#8217;s their bigger, enterprise customers who are more likely to be affected! (i.e. more sites, more people making changes, etc).<br />
</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">For what it&#8217;s worth, I found a workaround <img src='http://www.cleverworkarounds.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  which will be fully detailed in my <a href="http://www.cleverworkarounds.com/2007/11/10/sharepoint-branding-part-6-a-solution-to-all-issues/">next exciting installment</a> where I finish off features and finally dive into SOLUTIONS!</font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2">Bye for now! </font></span></p>
<p><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2"><br />
 </font></span><span style="font-size: 14pt; font-family: trebuchet ms"><font size="2"><span style="font-size: 14pt; font-family: trebuchet ms"></span></font></span></p>
<p style="display: inline; margin: 0px; padding: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e5ba61f6-834b-47c8-9d02-087ee23143da" class="wlWriterSmartContent">del.icio.us Tags: <a rel="tag" href="http://del.icio.us/popular/SharePoint">SharePoint</a> , <a rel="tag" href="http://del.icio.us/popular/SharePoint%20Branding">SharePoint Branding</a> , <a rel="tag" href="http://del.icio.us/popular/Masterpages">Masterpages</a> , <a rel="tag" href="http://del.icio.us/popular/SharePoint%20Features">SharePoint Features</a></p>
<p style="display: inline; margin: 0px; padding: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:08826b5a-2d95-4272-a782-a167c3db7f51" class="wlWriterSmartContent">Technorati Tags: <a rel="tag" href="http://technorati.com/tags/SharePoint/">SharePoint</a> , <a rel="tag" href="http://technorati.com/tags/SharePoint%20Branding/">SharePoint Branding</a> , <a rel="tag" href="http://technorati.com/tags/Masterpages/">Masterpages</a> , <a rel="tag" href="http://technorati.com/tags/SharePoint%20Features/">SharePoint Features</a></p>
<p><!--adsense--></p>
<p class="tags">No Tags</p>]]></content:encoded>
			<wfw:commentRss>http://www.cleverworkarounds.com/2007/10/27/sharepoint-branding-part-5-%e2%80%93-feature-improvements-and-bugs/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
