<?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>Knifecore</title>
	<atom:link href="http://hermanussen.eu/sitecore/wordpress/feed/" rel="self" type="application/rss+xml" />
	<link>http://hermanussen.eu/sitecore/wordpress</link>
	<description>A Sitecore sandwich, buttered, with crazy code</description>
	<lastBuildDate>Tue, 08 May 2012 20:58:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Making Sitecore faster with MongoDB</title>
		<link>http://hermanussen.eu/sitecore/wordpress/2012/05/making-sitecore-faster-with-mongodb/</link>
		<comments>http://hermanussen.eu/sitecore/wordpress/2012/05/making-sitecore-faster-with-mongodb/#comments</comments>
		<pubDate>Tue, 08 May 2012 20:58:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[sitecore modules]]></category>

		<guid isPermaLink="false">http://hermanussen.eu/sitecore/wordpress/?p=107</guid>
		<description><![CDATA[Most Sitecore implementations that I&#8217;ve worked with are backed by SQL Server for storing the content. If you look at the database model, you will see that it is quite simple. It is designed around the key principles of the CMS itself (items and field values), rather than the data structure of the content. This [...]]]></description>
			<content:encoded><![CDATA[<p>Most Sitecore implementations that I&#8217;ve worked with are backed by SQL Server for storing the content. If you look at the database model, you will see that it is quite simple. It is designed around the key principles of the CMS itself (items and field values), rather than the data structure of the content.</p>
<p>This data structure is not only very simple, it also doesn&#8217;t really need any relationships besides the one between items and field values (for different languages and versions). In fact, everything comes down to just items and some data related to those particular items. A document-oriented database instead of a relational database may be a better fit!</p>
<p>With this in mind, I attempted to create a data provider for Sitecore that works with <a title="MongoDB website" href="http://www.mongodb.org/">MongoDB</a>. And after a few months of not working on it at all, I finally finished it in the last few evenings. Since it has not been properly tested and very likely has some major bugs still in it, I ask you to regard this as a VERY experimental implementation.</p>
<p>Nevertheless, I encourage anyone who is interested to play around with the module that I&#8217;ve shared on the Sitecore Shared Source website. You can find the MongoDBDataProvider <a title="MongoDBDataProvider" href="http://trac.sitecore.net/MongoDBDataProvider/wiki/WikiStart">here</a>.</p>
<p><strong>Setting up the module</strong></p>
<p>Here are some easy steps to get started with the MongoDB data provider.</p>
<ol>
<li><a title="MongoDB quickstart for Windows" href="http://www.mongodb.org/display/DOCS/Quickstart+Windows">Install MongoDB</a> on your local machine and start it (no need to create a database)</li>
<li>Get the <a title="Subversion URL for MongoDBDataProvider" href="http://svn.sitecore.net/MongoDBDataProvider/">latest source code from SVN</a></li>
<li>Build the project</li>
<li>Copy the dll and dependencies (MongoDB.Bson and MongoDB.Driver) to the bin folder in your Sitecore site</li>
<li>Copy MongoDataProvider.config to your App_Config/Include folder</li>
<li>Copy Transfer.aspx and TestDataProvider.aspx to your website</li>
<li>Open Transfer.aspx in your browser and select the database you want to copy into MongoDB</li>
<li>Open the Sitecore desktop and open the mongodb database to see if everything is working correctly</li>
</ol>
<p>After setting things up, you can also change the database that your website works with (go to the &lt;sites /&gt; element in your web.config) to the &#8220;mongodb&#8221; database.</p>
<p><strong>Measuring the speed</strong></p>
<p>I&#8217;ve said it before:</p>
<blockquote><p>In my opinion, any performance improvement (especially if it has significant drawbacks) must be proven to be worth it!</p></blockquote>
<p>So I&#8217;ve made a page that tests the performance of any DataProvider that you select. It disregards any caching and tests several different operations a bunch of times and returns how long it took to run the operations. This might actually come in handy if you want to check your own custom made DataProvider.</p>
<p>Go to TestDataProvider.aspx and select the SQL Server data provider and the MongoDB data provider if you want to check the performance gain on your machine. My results are as follows:</p>
<table>
<colgroup>
<col width="86"></col>
<col width="227"></col>
<col width="227"></col>
<col width="227"></col>
</colgroup>
<tbody>
<tr>
<td width="86" height="32"><span style="color: #ffffff;"><strong>Operation</strong></span></td>
<td width="227"><span style="color: #ffffff;"><strong>Duration (in milliseconds) – SQL</strong></span></td>
<td width="227"><span style="color: #ffffff;"><strong>Duration (in milliseconds) – MongoDB with safe mode ON</strong></span></td>
<td width="227"><span style="color: #ffffff;"><strong>Duration (in milliseconds) – MongoDB with safe mode OFF</strong></span></td>
</tr>
<tr>
<td height="17"><span style="color: #ffffff;">Create</span></td>
<td><span style="color: #ffffff;">3723</span></td>
<td><span style="color: #ffffff;">1057</span></td>
<td><span style="color: #ffffff;">776</span></td>
</tr>
<tr>
<td height="17"><span style="color: #ffffff;">Add versions</span></td>
<td><span style="color: #ffffff;">5333</span></td>
<td><span style="color: #ffffff;">2750</span></td>
<td><span style="color: #ffffff;">2181</span></td>
</tr>
<tr>
<td height="32"><span style="color: #ffffff;">Change some field values</span></td>
<td><span style="color: #ffffff;">7005</span></td>
<td><span style="color: #ffffff;">1325</span></td>
<td><span style="color: #ffffff;">1092</span></td>
</tr>
<tr>
<td height="17"><span style="color: #ffffff;">Get parent id&#8217;s</span></td>
<td><span style="color: #ffffff;">2075</span></td>
<td><span style="color: #ffffff;">318</span></td>
<td><span style="color: #ffffff;">328</span></td>
</tr>
<tr>
<td height="17"><span style="color: #ffffff;">Get child id&#8217;s</span></td>
<td><span style="color: #ffffff;">901</span></td>
<td><span style="color: #ffffff;">275</span></td>
<td><span style="color: #ffffff;">279</span></td>
</tr>
<tr>
<td height="32"><span style="color: #ffffff;">Get item definitions</span></td>
<td><span style="color: #ffffff;">2026</span></td>
<td><span style="color: #ffffff;">351</span></td>
<td><span style="color: #ffffff;">348</span></td>
</tr>
<tr>
<td height="32"><span style="color: #ffffff;">Get item versions</span></td>
<td><span style="color: #ffffff;">2051</span></td>
<td><span style="color: #ffffff;">693</span></td>
<td><span style="color: #ffffff;">676</span></td>
</tr>
<tr>
<td height="32"><span style="color: #ffffff;">Get field values</span></td>
<td><span style="color: #ffffff;">1986</span></td>
<td><span style="color: #ffffff;">656</span></td>
<td><span style="color: #ffffff;">678</span></td>
</tr>
<tr>
<td height="17"><span style="color: #ffffff;">Delete</span></td>
<td><span style="color: #ffffff;">9379</span></td>
<td><span style="color: #ffffff;">372</span></td>
<td><span style="color: #ffffff;">44</span></td>
</tr>
<tr>
<td height="17"><span style="color: #ffffff;"><strong>Total</strong></span></td>
<td><span style="color: #ffffff;">34479</span></td>
<td><span style="color: #ffffff;">7798</span></td>
<td><span style="color: #ffffff;">6401</span></td>
</tr>
</tbody>
</table>
<p>Note that the <a title="MongoDB safe mode explanation" href="http://stackoverflow.com/questions/4604868/mongodb-c-sharp-safemode-official-driver">safe mode</a> in MongoDB makes writing to the database more reliable, and also a little slower (you can find a setting for this in MongoDataProvider.config). Turning the safe mode off might be interesting on content delivery environments, because that&#8217;s where the performance really matters and you can always re-publish something if you need to (though it would be very annoying if this would be needed).</p>
<p>Here&#8217;s a chart with the results:</p>
<p><a href="http://hermanussen.eu/sitecore/wordpress/wp-content/uploads/2012/05/DataProvider-speed-measurement-results.png"><img class="size-full wp-image-124 alignnone" title="DataProvider speed measurement results" src="http://hermanussen.eu/sitecore/wordpress/wp-content/uploads/2012/05/DataProvider-speed-measurement-results.png" alt="DataProvider speed measurement results" width="999" height="362" /></a></p>
<p>This may seem very impressive, but keep in mind that these results do NOT necessarily translate into similar improvements in speed for your entire website. A few things to keep in mind:</p>
<ul>
<li>Both the MongoDB data provider and this speed measurement tool have just been developed and have not had a chance to mature. Both are very likely to have serious bugs and may disregard some matters that definitely should be regarded. I&#8217;d be happy to hear from you if you would like to point out some of the things I have missed.</li>
<li>Sitecore relies heavily on caching on different levels. That&#8217;s why a site (or an individual page) may be very slow only on the first request. Perhaps if your content editors publish content very often and the cache needs to be cleared on each publish, it may be a good idea to look for a faster data provider such as this module.</li>
<li>The SQL Server data provider has some internal caching that I&#8217;m not sure the MongoDB data provider is exactly on par with. That means that the MongoDB data provider might actually be slower than the SQL Server data provider in a &#8216;real world scenario&#8217;.</li>
</ul>
<p>Anyway, it&#8217;s been great fun trying this different approach to storing Sitecore data and I hope you enjoyed reading about it!</p>
]]></content:encoded>
			<wfw:commentRss>http://hermanussen.eu/sitecore/wordpress/2012/05/making-sitecore-faster-with-mongodb/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>CompiledDomainModel 0.5.5.0 released!</title>
		<link>http://hermanussen.eu/sitecore/wordpress/2012/04/compileddomainmodel-0-5-5-0-released/</link>
		<comments>http://hermanussen.eu/sitecore/wordpress/2012/04/compileddomainmodel-0-5-5-0-released/#comments</comments>
		<pubDate>Sun, 08 Apr 2012 20:19:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[sitecore modules]]></category>

		<guid isPermaLink="false">http://hermanussen.eu/sitecore/wordpress/?p=100</guid>
		<description><![CDATA[Though the CompiledDomainModel Sitecore module is now a commonly used and deeply rooted part of our Sitecore development strategy within our organisation, that doesn&#8217;t mean that there&#8217;s no room for improvements. That&#8217;s why I sometimes fix some bugs or add a few features. The easter bunny brings us release 0.5.5.0. And because I haven&#8217;t blogged [...]]]></description>
			<content:encoded><![CDATA[<p>Though the <a href="http://trac.sitecore.net/CompiledDomainModel/wiki">CompiledDomainModel</a> Sitecore module is now a commonly used and deeply rooted part of our Sitecore development strategy within our organisation, that doesn&#8217;t mean that there&#8217;s no room for improvements.</p>
<p>That&#8217;s why I sometimes fix some bugs or add a few features. The easter bunny brings us release 0.5.5.0. And because I haven&#8217;t blogged about the previous release, I&#8217;ll also include the release notes for that one:</p>
<p><img class="alignnone" title="CompiledDomainModel logo" src="/sitecore/CompiledDomainModel/cdm.png" alt="" width="563" height="346" /></p>
<p>Release 0.5.0.0:</p>
<ul>
<li> Added support for relative fixed paths. So you can use a similar syntax as with fixed paths for paths within the content tree that have a fixed structure, but can be available in different locations.</li>
<li> The names of the DomainObjectSets are now included in the namespaces of the generated code. This allows for a better separation of projects/sites.</li>
<li> Items are now created by matching them by Sitecore ID, instead of template name</li>
<li> Some members made virtual</li>
<li> Compatibility with automatic databinding by turning it off during code generation</li>
<li> Fieldtype support added for
<ol>
<li>ImageField</li>
<li>FileField</li>
</ol>
</li>
<li> Generated code no longer uses XPath to get the descendants of a specific type; uses a &#8216;safer&#8217; way now</li>
<li> Added a GutterRenderer that displays the fixed paths and configured templates in the bar next to the content tree (<a href="http://hermanussen.eu/sitecore/wordpress/2011/03/the-sitecore-gutter/">more info</a>)</li>
<li> Generated code now starts with a prefix that can be used by external tools (like <a href="http://hermanussen.eu/sitecore/wordpress/2011/04/update-compileddomainmodel-from-visual-studio/">this one</a>) to refresh the generated code.</li>
</ul>
<p>Release 0.5.5.0:</p>
<ul>
<li> Added &#8220;FromParent(&#8230;)&#8221; static method to create relative fixed paths by resolving the child item by itself</li>
<li> Added the option to the global settings to remove dependencies with the CDM module</li>
<li> Added IItemWrapperCore, to allow dependencies with generated code to be removed.</li>
<li> Better way of determining template and contributing template hierarchy.</li>
<li> Fixed a bug that deals with a rather exotic NullReferenceException in the ConfigurationUtil class.</li>
</ul>
<p>You can find downloads on the <a title="CDM releases page" href="http://trac.sitecore.net/CompiledDomainModel/wiki/Releases">Releases page</a>. If you have any questions, just let me know!</p>
]]></content:encoded>
			<wfw:commentRss>http://hermanussen.eu/sitecore/wordpress/2012/04/compileddomainmodel-0-5-5-0-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Happy holidays bookmarklet</title>
		<link>http://hermanussen.eu/sitecore/wordpress/2011/12/happy-holidays-bookmarklet/</link>
		<comments>http://hermanussen.eu/sitecore/wordpress/2011/12/happy-holidays-bookmarklet/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 21:41:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[fun]]></category>

		<guid isPermaLink="false">http://hermanussen.eu/sitecore/wordpress/?p=90</guid>
		<description><![CDATA[The holiday season is almost here and I&#8217;d like to wish everyone a merry christmas and a happy 2012! May your Sitecore successes be as great or even greater next year! If you&#8217;re not into the holiday spirit yet, then here&#8217;s a very ugly and utterly useless bookmarklet that can turn your Sitecore desktop into [...]]]></description>
			<content:encoded><![CDATA[<p>The holiday season is almost here and I&#8217;d like to wish everyone a merry christmas and a happy 2012! May your Sitecore successes be as great or even greater next year!</p>
<p>If you&#8217;re not into the holiday spirit yet, then here&#8217;s a very ugly and utterly useless <a title="Bookmarklet explanation on Wikipedia" href="http://en.wikipedia.org/wiki/Bookmarklet">bookmarklet</a> that can turn your Sitecore desktop into a hideously decadent, blindingly colorful freakshow to match your equally obscene chistmas decorations (including usb christmas trees) that make your office look like a department store.</p>
<p>Just paste the following snippet into the url field of a new bookmark and click it when you have your Sitecore desktop opened (tested in Chrome only). I promise that the script does not intentionally mess up your work, but nevertheless: use it at your own risk.</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<pre style="margin: 0; line-height: 125%;">javascript<span style="color: #303030;">:</span>(<span style="color: #008000; font-weight: bold;">function</span>(){<span style="color: #008000; font-weight: bold;">var</span> wallPaper<span style="color: #303030;">=</span><span style="color: #007020;">document</span>.getElementById(<span style="background-color: #fff0f0;">'Wallpaper'</span>);<span style="color: #008000; font-weight: bold;">if</span>(wallPaper<span style="color: #303030;">!=</span><span style="color: #008000; font-weight: bold;">null</span>){wallPaper.src<span style="color: #303030;">=</span><span style="background-color: #fff0f0;">'http://christmasstockimages.com/free/decorations/red_baubles.jpg'</span>;wallPaper.setAttribute(<span style="background-color: #fff0f0;">'style'</span>,<span style="background-color: #fff0f0;">'display:block;'</span>);}<span style="color: #008000; font-weight: bold;">var</span> desktop<span style="color: #303030;">=</span><span style="color: #007020;">document</span>.getElementById(<span style="background-color: #fff0f0;">'Desktop'</span>);<span style="color: #008000; font-weight: bold;">if</span>(desktop<span style="color: #303030;">!=</span><span style="color: #008000; font-weight: bold;">null</span>){desktop.setAttribute(<span style="background-color: #fff0f0;">'style'</span>,<span style="background-color: #fff0f0;">''</span>);}setInterval(<span style="color: #008000; font-weight: bold;">function</span>(){<span style="color: #008000; font-weight: bold;">var</span> iframes<span style="color: #303030;">=</span><span style="color: #007020;">document</span>.getElementsByTagName(<span style="background-color: #fff0f0;">'iframe'</span>);<span style="color: #008000; font-weight: bold;">for</span>(<span style="color: #008000; font-weight: bold;">var</span> i<span style="color: #303030;">=</span><span style="color: #0000d0; font-weight: bold;">0</span>;i<span style="color: #303030;">&lt;</span>iframes.length;i<span style="color: #303030;">++</span>){<span style="color: #008000; font-weight: bold;">var</span> iframedoc<span style="color: #303030;">=</span>iframes[i].contentDocument;<span style="color: #008000; font-weight: bold;">if</span>(iframedoc.getElementById(<span style="background-color: #fff0f0;">'christmasstyle'</span>)<span style="color: #303030;">==</span><span style="color: #008000; font-weight: bold;">null</span>){<span style="color: #008000; font-weight: bold;">var</span> cssNode<span style="color: #303030;">=</span>iframedoc.createElement(<span style="background-color: #fff0f0;">'link'</span>);cssNode.id<span style="color: #303030;">=</span><span style="background-color: #fff0f0;">'christmasstyle'</span>;cssNode.type<span style="color: #303030;">=</span><span style="background-color: #fff0f0;">'text/css'</span>;cssNode.rel<span style="color: #303030;">=</span><span style="background-color: #fff0f0;">'stylesheet'</span>;cssNode.href<span style="color: #303030;">=</span><span style="background-color: #fff0f0;">'http://hermanussen.eu/sitecore/bookmarklets/christmas.css?rnd='</span><span style="color: #303030;">+</span><span style="color: #007020;">Math</span>.random();cssNode.media<span style="color: #303030;">=</span><span style="background-color: #fff0f0;">'screen'</span>;cssNode.title<span style="color: #303030;">=</span><span style="background-color: #fff0f0;">'dynamicLoadedSheet'</span>;iframedoc.getElementsByTagName(<span style="background-color: #fff0f0;">"head"</span>)[<span style="color: #0000d0; font-weight: bold;">0</span>].appendChild(cssNode);}}},<span style="color: #0000d0; font-weight: bold;">1000</span>);<span style="color: #008000; font-weight: bold;">var</span> cssNode<span style="color: #303030;">=</span><span style="color: #007020;">document</span>.createElement(<span style="background-color: #fff0f0;">'link'</span>);cssNode.id<span style="color: #303030;">=</span><span style="background-color: #fff0f0;">'christmasstyle'</span>;cssNode.type<span style="color: #303030;">=</span><span style="background-color: #fff0f0;">'text/css'</span>;cssNode.rel<span style="color: #303030;">=</span><span style="background-color: #fff0f0;">'stylesheet'</span>;cssNode.href<span style="color: #303030;">=</span><span style="background-color: #fff0f0;">'http://hermanussen.eu/sitecore/bookmarklets/christmas.css?rnd='</span><span style="color: #303030;">+</span><span style="color: #007020;">Math</span>.random();cssNode.media<span style="color: #303030;">=</span><span style="background-color: #fff0f0;">'screen'</span>;cssNode.title<span style="color: #303030;">=</span><span style="background-color: #fff0f0;">'dynamicLoadedSheet'</span>;<span style="color: #007020;">document</span>.getElementsByTagName(<span style="background-color: #fff0f0;">"head"</span>)[<span style="color: #0000d0; font-weight: bold;">0</span>].appendChild(cssNode);})()</pre>
</div>
<p>Here&#8217;s a quick preview of the horror that awaits you:</p>
<p><img class="alignnone" title="Christmas bookmarklet screenshot" src="/sitecore/bookmarklets/christmas_bookmarklet.png" alt="" width="839" height="481" /></p>
<p>Happy holidays!</p>
]]></content:encoded>
			<wfw:commentRss>http://hermanussen.eu/sitecore/wordpress/2011/12/happy-holidays-bookmarklet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sitecore Editor Android App</title>
		<link>http://hermanussen.eu/sitecore/wordpress/2011/09/sitecore-editor-android-app/</link>
		<comments>http://hermanussen.eu/sitecore/wordpress/2011/09/sitecore-editor-android-app/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 19:25:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[sitecore tips]]></category>

		<guid isPermaLink="false">http://hermanussen.eu/sitecore/wordpress/?p=79</guid>
		<description><![CDATA[As a former Java developer and Android phone owner, I wanted to try out some Android development. The Android platform is based on Java technology, so it wasn&#8217;t too hard to figure out. I got the idea to develop an alternative content editor for Sitecore. It wasn&#8217;t too difficult to connect to Sitecore and do [...]]]></description>
			<content:encoded><![CDATA[<p>As a former Java developer and Android phone owner, I wanted to try out some Android development. The Android platform is based on Java technology, so it wasn&#8217;t too hard to figure out. I got the idea to develop an alternative content editor for Sitecore.</p>
<p>It wasn&#8217;t too difficult to connect to Sitecore and do some basic actions like traversing the content tree, getting databases and getting item fields. I just used the standard Service.asmx (located in: /sitecore/shell/WebService/service.asmx). Using the ksoap2-android library for connecting to the service, I implemented the basic features.</p>
<p>The app is far from complete and has not been tested very thoroughly, but it does support the following features:</p>
<ul>
<li>Log in to Sitecore using the login screen (the url and user name are saved for next time)</li>
<li>Choose what database you want to connect to (&#8216;master&#8217; would be the best option for most people)</li>
<li>Traverse the content tree by selecting the item to traverse into for each level in the content tree (displays the icons too)</li>
<li>Press items a little longer to popup a choice menu for other actions</li>
<li>Rename items</li>
<li>Edit the raw values of the items (language/version can be selected at the top)</li>
<li>Choose between viewing the standard Sitecore fields or not</li>
<li>The Sitecore path where you are will be displayed at the bottom of the screen</li>
<li>Tested on my Samsung Galaxy S II with Android 2.3, but it should work on Android 2.2+</li>
</ul>
<p style="text-align: left;"><img class="aligncenter" title="Login screen" src="http://hermanussen.eu/sitecore/SitecoreEditor/login_screen.png" alt="" width="246" height="406" /><img class="aligncenter" title="Traverse items screen" src="http://hermanussen.eu/sitecore/SitecoreEditor/traversal_screen.png" alt="" width="245" height="403" /><img class="aligncenter" title="Edit item screen" src="http://hermanussen.eu/sitecore/SitecoreEditor/edit_item_screen.png" alt="" width="244" height="405" />If this is to become a serious App to be used by content editors on the road, I think a lot more basic features will have to be added. Publishing/unpublishing, adding and deleting items, and having more than just raw value support would be the bare minimum. I welcome any feedback on this and I would like to know if people are seriously interested in this.</p>
<p>If you want to give it a go on your Android phone, then capture the following QR code on your phone or hit the image (it&#8217;s also a link) to download the App.</p>
<p><a href="http://hermanussen.eu/sitecore/SitecoreEditor/SitecoreEditor.apk"><img class="aligncenter" title="Sitecore Editor Android App" src="https://chart.googleapis.com/chart?cht=qr&amp;chs=300x300&amp;chl=http%3A%2F%2Fhermanussen.eu%2Fsitecore%2FSitecoreEditor%2FSitecoreEditor.apk" alt="" width="300" height="300" /></a>Please note that the app is not available on the Android Market. But all you need to do is change one setting to allow this. A very good explanation can be found <a title="Applications outside the Android Market" href="http://www.androidcentral.com/just-browsing-applications-outside-android-market">here</a>.</p>
<p>Also, the CM server needs to be publically accessible, or your Android device should have access to the internal network (with the CM server on it) in order for the  application to work. Otherwise, the App will not be able to connect to the webservice.</p>
]]></content:encoded>
			<wfw:commentRss>http://hermanussen.eu/sitecore/wordpress/2011/09/sitecore-editor-android-app/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bypass the content API for better performance</title>
		<link>http://hermanussen.eu/sitecore/wordpress/2011/06/bypass-the-content-api-for-better-performance/</link>
		<comments>http://hermanussen.eu/sitecore/wordpress/2011/06/bypass-the-content-api-for-better-performance/#comments</comments>
		<pubDate>Thu, 02 Jun 2011 14:26:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[code snippets]]></category>

		<guid isPermaLink="false">http://hermanussen.eu/sitecore/wordpress/?p=74</guid>
		<description><![CDATA[The Sitecore content API provides a very easy way of accessing your content. It is highly optimized for performance with internal caching. You can find a great overview of the different query strategies here. But in some specific cases, the API will not provide you with the right tools to get what you want, with [...]]]></description>
			<content:encoded><![CDATA[<p>The Sitecore content API provides a very easy way of accessing your content. It is highly optimized for performance with internal caching. You can find a great overview of the different query strategies <a title="Options for querying items from Sitecore" href="http://firebreaksice.com/options-for-querying-items-from-sitecore/">here</a>.</p>
<p>But in some specific cases, the API will not provide you with the right tools to get what you want, with the performance that you want. In those cases you have 2 options:</p>
<ol>
<li>Persist a more suitable representation of your data. E.g.: output caching, Sitecore caching, Lucene indexing.</li>
<li>Strip some overhead, so functionality that is not needed at that point can be skipped. An example will follow.</li>
</ol>
<p>Both of these methods have their drawbacks, so it is important to evaluate them when choosing a solution. Some drawbacks for the first method:</p>
<ol>
<li>More storage/memory is needed.</li>
<li>The data representation must be kept consistent with the original data (can result in bugs that are hard to spot if implemented incorrectly).</li>
</ol>
<p>Drawbacks of the second method:</p>
<ol>
<li>Relies on the underlying implementation. You may have to change the implementation with future upgrades.</li>
<li>If the stripped functionality turns out to be needed in the future, the implementation may become unsuitable.</li>
</ol>
<p><strong>An example of the second method<br />
</strong></p>
<p>If we want to get the descendant nodes of a certain item, we can easily use the content API:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">item.Axes.GetDescendants()</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>But if we want to limit the descendants to items with a certain template, this is a better method:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">item.Axes.SelectItems(<span style="color: #a31515;">"descendant::*[@@TemplateName='File']"</span>)</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>However, in this case, we will not get items with template &#8216;Jpeg&#8217; or &#8216;Pdf&#8217;. Those templates inherit from the &#8216;File&#8217; template. So if we want to get all descendants that inherit from the &#8216;File&#8217; template, we need a helper method:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1
2
3
4
5
6
7</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">private</span> <span style="color: #2b91af;">bool</span> InheritsFromTemplate(TemplateItem templateItem, Sitecore.Data.ID templateId)
{
    <span style="color: #0000ff;">return</span> templateItem.ID == templateId
        || (templateItem.BaseTemplates != <span style="color: #0000ff;">null</span>
            &amp;&amp; templateItem.BaseTemplates
                .Where(baseTempl =&gt; InheritsFromTemplate(baseTempl, templateId)).Count() &gt; 0);
}</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>You could make this into an extension method if you want. Here&#8217;s how we can use this method to get all the descendants that inherit from &#8216;File&#8217;:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1
2</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">item.Axes.GetDescendants()
    .Where(desc =&gt; InheritsFromTemplate(desc.Template, FileTemplateId))</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>This will be quite slow if there are many descendants. We will bypass the content API and query the SQL server database directly to make it much faster.<br />
<!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;"><span style="color: #008000;">/// &lt;summary&gt;</span>
<span style="color: #008000;">/// A complex example that returns the actual descendants that inherit from a specific template id.</span>
<span style="color: #008000;">/// &lt;/summary&gt;</span>
<span style="color: #008000;">/// &lt;param name="item"&gt;The item for which to determine the descendants.&lt;/param&gt;</span>
<span style="color: #008000;">/// &lt;param name="templateId"&gt;The ID of the template of which the result items have to inherit.&lt;/param&gt;</span>
<span style="color: #008000;">/// &lt;returns&gt;The actual descendants that inherit from the template that was passed.&lt;/returns&gt;</span>
<span style="color: #0000ff;">public</span> IEnumerable&lt;Item&gt; GetDescendantsInheritingTemplate(Item item, Sitecore.Data.TemplateID templateId)
{
    Assert.IsNotNull(item, <span style="color: #a31515;">"A valid Sitecore item must be provided to this method"</span>);

    <span style="color: #008000;">// query SQL server directly</span>
    <span style="color: #2b91af;">string</span> query = <span style="color: #a31515;">@"with cteChildren as</span>
<span style="color: #a31515;">                    (select ID, TemplateID</span>
<span style="color: #a31515;">                    from [dbo].[Items]</span>
<span style="color: #a31515;">                    where ID = CAST(@itemId AS UNIQUEIDENTIFIER)</span>
<span style="color: #a31515;">                    union all</span>
<span style="color: #a31515;">                    select e.ID, e.TemplateID</span>
<span style="color: #a31515;">                    from cteChildren cte</span>
<span style="color: #a31515;">                    inner join [dbo].[Items] e</span>
<span style="color: #a31515;">                    on cte.ID = e.ParentID),</span>
<span style="color: #a31515;">                cteSubItems as</span>
<span style="color: #a31515;">                (</span>
<span style="color: #a31515;">                select ItemId from SharedFields</span>
<span style="color: #a31515;">                where FieldId = '12C33F3F-86C5-43A5-AEB4-5598CEC45116'</span>
<span style="color: #a31515;">                    and Value like '%' + @templateId + '%'</span>
<span style="color: #a31515;">                    union all</span>
<span style="color: #a31515;">                select sf.ItemId from SharedFields sf inner join cteSubItems ic</span>
<span style="color: #a31515;">                on sf.Value like '%' + CAST(ic.ItemId as varchar(36)) + '%'</span>
<span style="color: #a31515;">                where sf.FieldId = '12C33F3F-86C5-43A5-AEB4-5598CEC45116'</span>
<span style="color: #a31515;">                )</span>
<span style="color: #a31515;">                select cteChild.ID</span>
<span style="color: #a31515;">                from (select ItemId from cteSubItems union select @templateId) cteSit</span>
<span style="color: #a31515;">                    inner join cteChildren cteChild on cteSit.ItemId = cteChild.TemplateID"</span>;

    Sitecore.Data.DataProviders.Sql.DataProviderReader reader = dataApi.CreateReader(query,
        <span style="color: #a31515;">"itemId"</span>, item.ID.ToString().Trim(<span style="color: #0000ff;">new</span>[] { <span style="color: #a31515;">'{'</span>, <span style="color: #a31515;">'}'</span> }),
        <span style="color: #a31515;">"templateId"</span>, templateId.ID.ToString().Trim(<span style="color: #0000ff;">new</span>[] { <span style="color: #a31515;">'{'</span>, <span style="color: #a31515;">'}'</span> }));

    <span style="color: #008000;">// return to the content API to get the actual items (therefore also applies security)</span>
    List&lt;Item&gt; result = <span style="color: #0000ff;">new</span> List&lt;Item&gt;();
    <span style="color: #0000ff;">while</span> (reader.Read())
    {
        Sitecore.Data.ID itemId = <span style="color: #0000ff;">new</span> Sitecore.Data.ID(reader.InnerReader.GetGuid(0));
        <span style="color: #0000ff;">if</span> (itemId != item.ID)
        {
            Item descItem = Sitecore.Context.Database.GetItem(itemId);
            <span style="color: #0000ff;">if</span> (descItem != <span style="color: #0000ff;">null</span>)
            {
                result.Add(descItem);
            }
        }
    }
    <span style="color: #0000ff;">return</span> result;
}</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>Place the query in a stored procedure if you want to use this method in production. For reference, <a title="Accessing hierarchical node structures from sql" href="http://bloggingabout.net/blogs/program.x/archive/2008/07/29/sitecore-accessing-hierarchical-node-structures-from-sql.aspx">here is a different article</a> which discusses bypassing the content API.</p>
<p><strong>Measuring speed</strong></p>
<p>In my opinion, any performance improvement (especially if it has significant drawbacks) must be proven to be worth it! So I&#8217;ve measured the speed of this method and a simpler one against the normal Sitecore way of doing things. Here&#8217;s the result:</p>
<p><img class="alignnone" title="Speed measuring results" src="/sitecore/wordpress/wp-content/uploads/bypass_content_api_screenshot.png" alt="" width="519" height="161" /></p>
<p>As you can see, the performance gain can be significant. So if the drawbacks are acceptable, this may be a good option. Here is the aspx so you can test it for yourself:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">&lt;%@ Page Language=<span style="color: #a31515;">"C#"</span> AutoEventWireup=<span style="color: #a31515;">"true"</span> Debug=<span style="color: #a31515;">"true"</span> %&gt;
&lt;%@ Import Namespace=<span style="color: #a31515;">"Sitecore.Data.Items"</span> %&gt;
&lt;%@ Import Namespace=<span style="color: #a31515;">"Sitecore.Diagnostics"</span> %&gt;
&lt;%@ Import Namespace=<span style="color: #a31515;">"Sitecore.Data.SqlServer"</span> %&gt;
&lt;script runat=<span style="color: #a31515;">"server"</span>&gt;

    <span style="color: #0000ff;">private</span> SqlServerDataApi dataApi = <span style="color: #0000ff;">new</span> SqlServerDataApi(
            Sitecore.Configuration.Settings.GetConnectionString(Sitecore.Context.Database.ConnectionStringName)
        );

    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// A simple example that determines the number of descendants that an item has.</span>
    <span style="color: #008000;">/// Note that this method disregards any security settings!</span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #008000;">/// &lt;param name="item"&gt;The item for which to count descendants.&lt;/param&gt;</span>
    <span style="color: #008000;">/// &lt;returns&gt;The number of descendants.&lt;/returns&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #2b91af;">int</span> GetDescendantsCount(Item item)
    {
        Assert.IsNotNull(item, <span style="color: #a31515;">"A valid Sitecore item must be provided to this method"</span>);
        <span style="color: #2b91af;">string</span> query = <span style="color: #a31515;">@"with cteChildren as</span>
<span style="color: #a31515;">                               (select ID</span>
<span style="color: #a31515;">                                from [dbo].[Items]</span>
<span style="color: #a31515;">                                where ID = CAST(@ItemId AS UNIQUEIDENTIFIER)</span>
<span style="color: #a31515;">                              union all</span>
<span style="color: #a31515;">                                select e.ID</span>
<span style="color: #a31515;">                                from cteChildren cte</span>
<span style="color: #a31515;">                                inner join [dbo].[Items] e</span>
<span style="color: #a31515;">                                on cte.ID = e.ParentID)</span>
<span style="color: #a31515;">                            select count(ID) - 1 from cteChildren"</span>;
        Sitecore.Data.DataProviders.Sql.DataProviderReader reader
            = dataApi.CreateReader(query, <span style="color: #a31515;">"ItemId"</span>, item.ID.ToString().Trim(<span style="color: #0000ff;">new</span>[] { <span style="color: #a31515;">'{'</span>, <span style="color: #a31515;">'}'</span> }));
        <span style="color: #0000ff;">return</span> reader.Read() ? reader.InnerReader.GetInt32(0) : 0;
    }

<span style="color: #008000;">/// &lt;summary&gt;</span>
<span style="color: #008000;">/// A complex example that returns the actual descendants that inherit from a specific template id.</span>
<span style="color: #008000;">/// &lt;/summary&gt;</span>
<span style="color: #008000;">/// &lt;param name="item"&gt;The item for which to determine the descendants.&lt;/param&gt;</span>
<span style="color: #008000;">/// &lt;param name="templateId"&gt;The ID of the template of which the result items have to inherit.&lt;/param&gt;</span>
<span style="color: #008000;">/// &lt;returns&gt;The actual descendants that inherit from the template that was passed.&lt;/returns&gt;</span>
<span style="color: #0000ff;">public</span> IEnumerable&lt;Item&gt; GetDescendantsInheritingTemplate(Item item, Sitecore.Data.TemplateID templateId)
{
    Assert.IsNotNull(item, <span style="color: #a31515;">"A valid Sitecore item must be provided to this method"</span>);

    <span style="color: #008000;">// query SQL server directly</span>
    <span style="color: #2b91af;">string</span> query = <span style="color: #a31515;">@"with cteChildren as</span>
<span style="color: #a31515;">                    (select ID, TemplateID</span>
<span style="color: #a31515;">                    from [dbo].[Items]</span>
<span style="color: #a31515;">                    where ID = CAST(@itemId AS UNIQUEIDENTIFIER)</span>
<span style="color: #a31515;">                    union all</span>
<span style="color: #a31515;">                    select e.ID, e.TemplateID</span>
<span style="color: #a31515;">                    from cteChildren cte</span>
<span style="color: #a31515;">                    inner join [dbo].[Items] e</span>
<span style="color: #a31515;">                    on cte.ID = e.ParentID),</span>
<span style="color: #a31515;">                cteSubItems as</span>
<span style="color: #a31515;">                (</span>
<span style="color: #a31515;">                select ItemId from SharedFields</span>
<span style="color: #a31515;">                where FieldId = '12C33F3F-86C5-43A5-AEB4-5598CEC45116'</span>
<span style="color: #a31515;">                    and Value like '%' + @templateId + '%'</span>
<span style="color: #a31515;">                    union all</span>
<span style="color: #a31515;">                select sf.ItemId from SharedFields sf inner join cteSubItems ic</span>
<span style="color: #a31515;">                on sf.Value like '%' + CAST(ic.ItemId as varchar(36)) + '%'</span>
<span style="color: #a31515;">                where sf.FieldId = '12C33F3F-86C5-43A5-AEB4-5598CEC45116'</span>
<span style="color: #a31515;">                )</span>
<span style="color: #a31515;">                select cteChild.ID</span>
<span style="color: #a31515;">                from (select ItemId from cteSubItems union select @templateId) cteSit</span>
<span style="color: #a31515;">                    inner join cteChildren cteChild on cteSit.ItemId = cteChild.TemplateID"</span>;

    Sitecore.Data.DataProviders.Sql.DataProviderReader reader = dataApi.CreateReader(query,
        <span style="color: #a31515;">"itemId"</span>, item.ID.ToString().Trim(<span style="color: #0000ff;">new</span>[] { <span style="color: #a31515;">'{'</span>, <span style="color: #a31515;">'}'</span> }),
        <span style="color: #a31515;">"templateId"</span>, templateId.ID.ToString().Trim(<span style="color: #0000ff;">new</span>[] { <span style="color: #a31515;">'{'</span>, <span style="color: #a31515;">'}'</span> }));

    <span style="color: #008000;">// return to the content API to get the actual items (therefore also applies security)</span>
    List&lt;Item&gt; result = <span style="color: #0000ff;">new</span> List&lt;Item&gt;();
    <span style="color: #0000ff;">while</span> (reader.Read())
    {
        Sitecore.Data.ID itemId = <span style="color: #0000ff;">new</span> Sitecore.Data.ID(reader.InnerReader.GetGuid(0));
        <span style="color: #0000ff;">if</span> (itemId != item.ID)
        {
            Item descItem = Sitecore.Context.Database.GetItem(itemId);
            <span style="color: #0000ff;">if</span> (descItem != <span style="color: #0000ff;">null</span>)
            {
                result.Add(descItem);
            }
        }
    }
    <span style="color: #0000ff;">return</span> result;
}

    <span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> BenchMark(Func&lt;<span style="color: #2b91af;">int</span>&gt; func, <span style="color: #2b91af;">int</span> times)
    {
        DateTime start = DateTime.Now;
        <span style="color: #2b91af;">int</span> lastResult = -1;
        <span style="color: #0000ff;">for</span> (<span style="color: #2b91af;">int</span> i = 0; i &lt; times; i++)
        {
            lastResult = func();
        }
        <span style="color: #0000ff;">return</span> <span style="color: #2b91af;">string</span>.Format(<span style="color: #a31515;">"{0}&lt;br /&gt;(performed {1} times, and took an average of {2} milliseconds)"</span>,
            lastResult,
            times,
            Math.Round(((DateTime.Now - start).TotalMilliseconds / times)));
    }

    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Page_Load(<span style="color: #2b91af;">object</span> sender, EventArgs e)
    {
        DataBind();
    }

    <span style="color: #0000ff;">private</span> Item MyItem
    {
        <span style="color: #0000ff;">get</span>
        {
            <span style="color: #0000ff;">return</span> Sitecore.Context.Database.GetRootItem();
        }
    }

    <span style="color: #0000ff;">private</span> Sitecore.Data.ID FileTemplateId
    {
        <span style="color: #0000ff;">get</span>
        {
            <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span> Sitecore.Data.ID(<span style="color: #a31515;">"{962B53C4-F93B-4DF9-9821-415C867B8903}"</span>);
        }
    }

    <span style="color: #0000ff;">private</span> <span style="color: #2b91af;">bool</span> InheritsFromTemplate(TemplateItem templateItem, Sitecore.Data.ID templateId)
    {
        <span style="color: #0000ff;">return</span> templateItem.ID == templateId
            || (templateItem.BaseTemplates != <span style="color: #0000ff;">null</span>
                &amp;&amp; templateItem.BaseTemplates
                    .Where(baseTempl =&gt; InheritsFromTemplate(baseTempl, templateId)).Count() &gt; 0);
    }

&lt;/script&gt;
<span style="color: #0000ff;">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;</span>

&lt;html xmlns=<span style="color: #a31515;">"http://www.w3.org/1999/xhtml"</span>&gt;
&lt;head runat=<span style="color: #a31515;">"server"</span>&gt;
    &lt;title&gt;Test direct SQL server database access&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;ol&gt;
        &lt;li&gt;Count all descendants (using sitecore content API) =
            &lt;%# BenchMark(() =&gt; MyItem.Axes.GetDescendants().Count(), 50) %&gt;&lt;/li&gt;
        &lt;li&gt;Count all descendants (directly with the database, disregards security) =
            &lt;%# BenchMark(() =&gt; GetDescendantsCount(MyItem), 50)%&gt;&lt;/li&gt;

        &lt;li&gt;Get all descendants that inherit from 'File' (using sitecore content API) =
            &lt;%# BenchMark(() =&gt; MyItem.Axes.GetDescendants()
                    .Where(desc =&gt; InheritsFromTemplate(desc.Template, FileTemplateId)).Count(), 50) %&gt;&lt;/li&gt;
        &lt;li&gt;Get all descendants that inherit from 'File' (directly with the database) =
            &lt;%# BenchMark(() =&gt; GetDescendantsInheritingTemplate(MyItem,
                    <span style="color: #0000ff;">new</span> Sitecore.Data.TemplateID(FileTemplateId)).Count(), 50)%&gt;&lt;/li&gt;
    &lt;/ol&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
]]></content:encoded>
			<wfw:commentRss>http://hermanussen.eu/sitecore/wordpress/2011/06/bypass-the-content-api-for-better-performance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Design Structure Matrix (DSM) for your content tree</title>
		<link>http://hermanussen.eu/sitecore/wordpress/2011/05/design-structure-matrix-dsm-for-your-content-tree/</link>
		<comments>http://hermanussen.eu/sitecore/wordpress/2011/05/design-structure-matrix-dsm-for-your-content-tree/#comments</comments>
		<pubDate>Sun, 29 May 2011 17:27:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[code snippets]]></category>

		<guid isPermaLink="false">http://hermanussen.eu/sitecore/wordpress/?p=63</guid>
		<description><![CDATA[A design structure matrix (or dependency structure matrix) can help you to analyze the dependencies of your system and spot potential problems. This is especially useful when analyzing code, like you can do with the .NET Reflector Add-In you can find here. Since certain aspects of your system structure can also be derived from the [...]]]></description>
			<content:encoded><![CDATA[<p>A <a title="Introduction to DSM" href="http://129.187.108.94/dsmweb/en/understand-dsm/technical-dsm-tutorial0/introduction-to-dsm.html">design structure matrix</a> (or dependency structure matrix) can help you to analyze the dependencies of your system and spot potential problems. This is especially useful when analyzing code, like you can do with the <a title=".NET Reflector" href="http://www.reflector.net/">.NET Reflector</a> Add-In you can find <a title="Dependency Structure Matrix PlugIn for .NET Reflector" href="http://tcdev.free.fr/">here</a>.</p>
<p>Since certain aspects of your system structure can also be derived from the Sitecore content tree, I thought it might be useful to make a DSM for that. The aspx at the end of this post can be used to analyze the dependencies in your content tree!</p>
<p><strong>An example of how this can be useful:</strong></p>
<p>Let&#8217;s say you have a multisite Sitecore environment that currently has 3 websites (A, B and C). Some parts of the websites are quite similar and developers have copied different items between the websites. Website B is (functionally) essentially a subsite of site A. You could say that website B &#8216;depends&#8217; on website A. And actually, since website A will have a link to site B, website A also depends on website B. Website C should be completely independent.</p>
<p><img class="aligncenter" title="Image 1" src="/sitecore/wordpress/wp-content/uploads/dsm_1.png" alt="" width="167" height="389" /></p>
<p>Now, I have opened the DSM aspx. After selecting the master database, expanding all the relevant nodes and selecting the websites, I am now ready to create a DSM. After clicking the &#8220;Update DSM data&#8221; button, I can see the following:</p>
<p><img class="alignnone" title="Image 2" src="/sitecore/wordpress/wp-content/uploads/dsm_2.png" alt="" width="212" height="121" /></p>
<p>From this matrix, I can see the following (start reading by choosing a row and then choose the cell; the numbers in the top row reference the items in the column on the left):</p>
<p>- Website A (or one of its descendants) has 1 link to website B (or one of its descendants).<br />
- Website B (or one of its descendants) has 3 link to website A (or one of its descendants).<br />
- Website C (or one of its descendants) has 1 link to website B (or one of its descendants).</p>
<p>That last one could be a problem! Website C should have no links to the other websites. This probably happened because I copied something from website B to website C and I forgot to change the link.</p>
<p>To see where the problem is exactly, I click on the table cell (coordinate: 1.3 Website C, 1.2). The information in the next image is displayed:</p>
<p><img class="alignnone" title="Image 3" src="/sitecore/wordpress/wp-content/uploads/dsm_3.png" alt="" width="526" height="96" /></p>
<p>The menu configuration for website C references a page in website B, instead of a page in website C. After I correct this error, I click &#8220;Update DSM data&#8221; again. Now the matrix looks like this:</p>
<p><img class="alignnone" title="Image 4" src="/sitecore/wordpress/wp-content/uploads/dsm_4.png" alt="" width="214" height="122" /></p>
<p>That&#8217;s better; Only websites A and B now have references to each other.</p>
<p>If I need a more detailed look, I can select anything that I think is relevant in the tree. So the aspx page could look like this:</p>
<p><a href="http://hermanussen.eu/sitecore/wordpress/wp-content/uploads/dsm_5.png"><img class="alignnone" title="Image 5" src="/sitecore/wordpress/wp-content/uploads/dsm_5.png" alt="" width="1225" height="515" /></a></p>
<p>You have to get used to reading this type of matrix, but it can be a very useful tool. This example is obviously quite simple; more complex situations may be found in the &#8220;real world&#8221;.</p>
<p>The tool is not exclusively for solving problems. It can also be helpful for quickly understanding how a system is setup.</p>
<p>Just copy the following code to an aspx file and you&#8217;re ready to use the tool:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">&lt;%@ Page Language=<span style="color: #a31515;">"C#"</span> AutoEventWireup=<span style="color: #a31515;">"true"</span> %&gt;
&lt;%@ Import Namespace=<span style="color: #a31515;">"System.Linq"</span> %&gt;
&lt;%@ Import Namespace=<span style="color: #a31515;">"System.Collections.Generic"</span> %&gt;
&lt;%@ Import Namespace=<span style="color: #a31515;">"Sitecore.Data.Items"</span> %&gt;
&lt;script runat=<span style="color: #a31515;">"server"</span>&gt;

    <span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> OnLoad(EventArgs e)
    {
        <span style="color: #0000ff;">base</span>.OnLoad(e);
        <span style="color: #0000ff;">if</span> (!IsPostBack)
        {
            ddlDatabase.DataSource = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">object</span>[] { <span style="color: #a31515;">"- select database -"</span> }.Concat(Sitecore.Configuration.Factory.GetDatabaseNames());
            ddlDatabase.DataBind();
        }
    }

    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> DatabaseSelected(<span style="color: #2b91af;">object</span> sender, EventArgs e)
    {
        <span style="color: #0000ff;">if</span> (!<span style="color: #a31515;">"- select database -"</span>.Equals(ddlDatabase.SelectedValue))
        {
            plhTreeViewExplanation.Visible = <span style="color: #0000ff;">true</span>;
            Sitecore.Data.Database database = Sitecore.Configuration.Factory.GetDatabase(ddlDatabase.SelectedValue);
            <span style="color: #0000ff;">if</span> (database != <span style="color: #0000ff;">null</span>)
            {
                Item item = database.GetRootItem();
                trvSitecore.Nodes.Clear();
                PopulateTree(trvSitecore.Nodes, item);
                trvSitecore.CollapseAll();
            }
        }
        <span style="color: #0000ff;">else</span>
        {
            plhTreeViewExplanation.Visible = <span style="color: #0000ff;">false</span>;
        }
    }

    <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> PopulateTree(TreeNodeCollection nodes, Item item)
    {
        <span style="color: #0000ff;">foreach</span>(Item child <span style="color: #0000ff;">in</span> item.GetChildren())
        {
            TreeNode node = <span style="color: #0000ff;">new</span> TreeNode(child.Name, child.ID.ToString())
                {
                    ShowCheckBox = <span style="color: #0000ff;">true</span>,
                    SelectAction = TreeNodeSelectAction.Expand,
                    PopulateOnDemand = <span style="color: #0000ff;">true</span>
                };
            nodes.Add(node);
        }
    }

    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> PopulateNode(<span style="color: #2b91af;">object</span> sender, TreeNodeEventArgs e)
    {
        Item item = Sitecore.Configuration.Factory.GetDatabase(ddlDatabase.SelectedValue).GetItem(e.Node.Value);
        <span style="color: #0000ff;">if</span> (item != <span style="color: #0000ff;">null</span>)
        {
            PopulateTree(e.Node.ChildNodes, item);
            e.Node.Expand();
        }
    }

    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> UpdateDsm(<span style="color: #2b91af;">object</span> sender, EventArgs e)
    {
        <span style="color: #0000ff;">if</span> (!<span style="color: #a31515;">"- select database -"</span>.Equals(ddlDatabase.SelectedValue))
        {
            DsmItems = <span style="color: #0000ff;">new</span> List&lt;DsmItem&gt;();
            DsmItem.CreateRecursive(Sitecore.Configuration.Factory.GetDatabase(ddlDatabase.SelectedValue), <span style="color: #0000ff;">null</span>, trvSitecore.Nodes, DsmItems);
            <span style="color: #0000ff;">foreach</span> (DsmItem it <span style="color: #0000ff;">in</span> DsmItems)
            {
                it.DetermineDependencies(DsmItems);
            }
            <span style="color: #0000ff;">if</span> (DsmItems.Count == 0)
            {
                DsmItems = <span style="color: #0000ff;">null</span>;
            }
            rptDsm.DataBind();
            txtSelectedItem.Value = <span style="color: #a31515;">""</span>;
            SelectedSourceItem = <span style="color: #0000ff;">null</span>;
            SelectedTargetItem = <span style="color: #0000ff;">null</span>;
            SelectedItemLinks = <span style="color: #0000ff;">null</span>;
            rptDetail.DataBind();
        }
    }

    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> UpdateDetail(<span style="color: #2b91af;">object</span> sender, EventArgs e)
    {
        <span style="color: #0000ff;">if</span> (!<span style="color: #a31515;">"- select database -"</span>.Equals(ddlDatabase.SelectedValue)
                &amp;&amp; !<span style="color: #2b91af;">string</span>.IsNullOrEmpty(txtSelectedItem.Value))
        {
            Sitecore.Data.ID[] ids = Sitecore.Data.ID.ParseArray(txtSelectedItem.Value);
            <span style="color: #0000ff;">if</span> (ids.Length == 2)
            {
                Sitecore.Data.Database database = Sitecore.Configuration.Factory.GetDatabase(ddlDatabase.SelectedValue);
                <span style="color: #0000ff;">if</span> (database != <span style="color: #0000ff;">null</span>)
                {
                    Item item1 = database.GetItem(ids[1]);
                    Item item2 = database.GetItem(ids[0]);
                    <span style="color: #0000ff;">if</span> (item1 != <span style="color: #0000ff;">null</span> &amp;&amp; item2 != <span style="color: #0000ff;">null</span>)
                    {
                        SelectedSourceItem = item1;
                        SelectedTargetItem = item2;
                        SelectedItemLinks = DsmItem.GetReferences(<span style="color: #0000ff;">new</span>[] { item1 }.Concat(item1.Axes.GetDescendants()),
                            <span style="color: #0000ff;">new</span>[] { item2 }.Concat(item2.Axes.GetDescendants()));
                        rptDetail.DataBind();
                    }
                }
            }
        }
    }

    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">DsmItem</span>
    {
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> CreateRecursive(Sitecore.Data.Database database, DsmItem parent, TreeNodeCollection nodes, List&lt;DsmItem&gt; createdItems)
        {
            <span style="color: #2b91af;">int</span> i = 1;
            <span style="color: #0000ff;">foreach</span> (TreeNode node <span style="color: #0000ff;">in</span> nodes)
            {
                <span style="color: #0000ff;">if</span> (MustBeAdded(node))
                {
                    Item nodeItem = database.GetItem(node.Value);
                    <span style="color: #0000ff;">if</span> (nodeItem != <span style="color: #0000ff;">null</span>)
                    {
                        DsmItem newItem = <span style="color: #0000ff;">new</span> DsmItem(nodeItem, i, parent, node.Checked);
                        createdItems.Add(newItem);
                        <span style="color: #0000ff;">if</span> (node.Expanded ?? <span style="color: #0000ff;">false</span>)
                        {
                            CreateRecursive(database, newItem, node.ChildNodes, createdItems);
                        }
                        i++;
                    }
                }
            }
        }

        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #2b91af;">bool</span> MustBeAdded(TreeNode node)
        {
            <span style="color: #0000ff;">return</span> node.Checked || node.ChildNodes.OfType&lt;TreeNode&gt;().Where(childNode =&gt; MustBeAdded(childNode)).Count() &gt; 0;
        }

        <span style="color: #0000ff;">public</span> Item Item { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">set</span>; }
        <span style="color: #0000ff;">public</span> IDictionary&lt;DsmItem,<span style="color: #2b91af;">int</span>&gt; Dependencies { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">set</span>; }
        <span style="color: #0000ff;">private</span> <span style="color: #2b91af;">int</span> Number { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span>; }
        <span style="color: #0000ff;">public</span> <span style="color: #2b91af;">string</span> Reference { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">set</span>; }
        <span style="color: #0000ff;">public</span> DsmItem Parent { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">set</span>; }
        <span style="color: #0000ff;">protected</span> IEnumerable&lt;Item&gt; SubTree { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span>; }
        <span style="color: #0000ff;">public</span> <span style="color: #2b91af;">bool</span> IsActive { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">set</span>; }

        <span style="color: #0000ff;">public</span> DsmItem(Item item, <span style="color: #2b91af;">int</span> number, DsmItem parent, <span style="color: #2b91af;">bool</span> active)
        {
            Item = item;
            Number = number;
            Parent = parent;
            Reference = Parent == <span style="color: #0000ff;">null</span> ? Number.ToString() : <span style="color: #2b91af;">string</span>.Format(<span style="color: #a31515;">"{0}.{1}"</span>, Parent.Reference, Number);
            IsActive = active;
            <span style="color: #0000ff;">if</span> (IsActive)
            {
                SubTree = <span style="color: #0000ff;">new</span>[] { item }.Concat(item.Axes.GetDescendants() ?? <span style="color: #0000ff;">new</span> Item[0]);
            }
        }

        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> DetermineDependencies(IEnumerable&lt;DsmItem&gt; allItems)
        {
            <span style="color: #0000ff;">if</span> (IsActive)
            {
                Dependencies = allItems
                    .Select(item =&gt; <span style="color: #0000ff;">new</span> { K = item, V = Item.ID == item.Item.ID ? -1 : (item.IsActive ? GetTotalReferenceCount(SubTree, item.SubTree) : 0) })
                    .ToDictionary(k =&gt; k.K, v =&gt; v.V);
            }
        }

        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> IEnumerable&lt;Sitecore.Links.ItemLink&gt; GetReferences(IEnumerable&lt;Item&gt; sources, IEnumerable&lt;Item&gt; targets)
        {
            <span style="color: #0000ff;">return</span> sources.SelectMany(source =&gt; (Sitecore.Globals.LinkDatabase.GetReferences(source) ?? <span style="color: #0000ff;">new</span> Sitecore.Links.ItemLink[0]))
                .Where(link =&gt; targets.Select(target =&gt; target.ID).Contains(link.TargetItemID)).Distinct();
        }

        <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #2b91af;">int</span> GetTotalReferenceCount(IEnumerable&lt;Item&gt; sources, IEnumerable&lt;Item&gt; targets)
        {
            <span style="color: #0000ff;">return</span> GetReferences(sources, targets).Count();
        }
    }

    <span style="color: #0000ff;">public</span> List&lt;DsmItem&gt; DsmItems { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span>; }

    <span style="color: #0000ff;">public</span> Item SelectedSourceItem { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span>; }
    <span style="color: #0000ff;">public</span> Item SelectedTargetItem { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span>; }
    <span style="color: #0000ff;">public</span> IEnumerable&lt;Sitecore.Links.ItemLink&gt; SelectedItemLinks { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span>; }
&lt;/script&gt;

<span style="color: #0000ff;">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;</span>

&lt;html xmlns=<span style="color: #a31515;">"http://www.w3.org/1999/xhtml"</span>&gt;
&lt;head runat=<span style="color: #a31515;">"server"</span>&gt;
    &lt;title&gt;Sitecore design structure matrix&lt;/title&gt;
    &lt;style type=<span style="color: #a31515;">"text/css"</span>&gt;
    table.dsmtable td {
        min-width: 25px;
    }
    table.dsmtable td.self
    {
    	background-color: #000000;
    }
    table.dsmtable td.inactive
    {
    	background-color: #cccccc;
    }
    div.leftpane
    {
        float:left;
        padding-right: 5px;
    }
    div.rightpane
    {
        border-left: 2px solid #cccccc;
        overflow: auto;
        padding-left: 5px;
    }
    .hiddenbutton
    {
    	visibility: hidden;
    }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form id=<span style="color: #a31515;">"form1"</span> runat=<span style="color: #a31515;">"server"</span>&gt;
        &lt;div class=<span style="color: #a31515;">"leftpane"</span>&gt;
            &lt;asp:DropDownList runat=<span style="color: #a31515;">"server"</span> ID=<span style="color: #a31515;">"ddlDatabase"</span> AutoPostBack=<span style="color: #a31515;">"true"</span> OnSelectedIndexChanged=<span style="color: #a31515;">"DatabaseSelected"</span> /&gt;
            &lt;asp:PlaceHolder runat=<span style="color: #a31515;">"server"</span> ID=<span style="color: #a31515;">"plhTreeViewExplanation"</span> Visible=<span style="color: #a31515;">"false"</span>&gt;
                &lt;p&gt;Select the parts of the content tree that you want to research&lt;/p&gt;
            &lt;/asp:PlaceHolder&gt;
            &lt;asp:TreeView runat=<span style="color: #a31515;">"Server"</span> ID=<span style="color: #a31515;">"trvSitecore"</span> ShowLines=<span style="color: #a31515;">"true"</span> EnableClientScript=<span style="color: #a31515;">"false"</span> OnTreeNodePopulate=<span style="color: #a31515;">"PopulateNode"</span> /&gt;
        &lt;/div&gt;
        &lt;div class=<span style="color: #a31515;">"rightpane"</span>&gt;
            &lt;asp:Button runat=<span style="color: #a31515;">"server"</span> ID=<span style="color: #a31515;">"btnUpdateDsm"</span> Text=<span style="color: #a31515;">"Update DSM data"</span> OnClick=<span style="color: #a31515;">"UpdateDsm"</span> /&gt;
            &lt;asp:Repeater runat=<span style="color: #a31515;">"server"</span> ID=<span style="color: #a31515;">"rptDsm"</span> DataSource=<span style="color: #a31515;">"</span>&lt;%# DsmItems %&gt;"&gt;
                &lt;HeaderTemplate&gt;
                    &lt;table class=<span style="color: #a31515;">"dsmtable"</span> border=<span style="color: #a31515;">"1"</span> celpadding=<span style="color: #a31515;">"0"</span> cellspacing=<span style="color: #a31515;">"0"</span>&gt;
                        &lt;asp:Repeater runat=<span style="color: #a31515;">"server"</span> DataSource=<span style="color: #a31515;">"</span>&lt;%# DsmItems %&gt;"&gt;
                            &lt;HeaderTemplate&gt;&lt;tr&gt;&lt;th&gt;&amp;nbsp;&lt;/th&gt;&lt;/HeaderTemplate&gt;
                            &lt;ItemTemplate&gt;
                                &lt;th&gt;&lt;%# ((DsmItem) Container.DataItem).Reference %&gt;&lt;/th&gt;
                            &lt;/ItemTemplate&gt;
                            &lt;FooterTemplate&gt;&lt;/tr&gt;&lt;/FooterTemplate&gt;
                        &lt;/asp:Repeater&gt;
                &lt;/HeaderTemplate&gt;
                &lt;ItemTemplate&gt;
                    &lt;tr&gt;
                    &lt;td&gt;
                        &lt;%# ((DsmItem) Container.DataItem).Reference %&gt;&amp;nbsp;&lt;%# ((DsmItem) Container.DataItem).Item.Name %&gt;
                    &lt;/td&gt;
                        &lt;asp:PlaceHolder runat=<span style="color: #a31515;">"server"</span> Visible=<span style="color: #a31515;">"</span>&lt;%# ! ((DsmItem) Container.DataItem).IsActive %&gt;"&gt;
                            &lt;asp:Repeater runat=<span style="color: #a31515;">"server"</span> DataSource=<span style="color: #a31515;">"</span>&lt;%# DsmItems %&gt;"&gt;
                                &lt;ItemTemplate&gt;&lt;td class=<span style="color: #a31515;">"inactive"</span>&gt;&amp;nbsp;&lt;/td&gt;&lt;/ItemTemplate&gt;
                            &lt;/asp:Repeater&gt;
                        &lt;/asp:PlaceHolder&gt;
                        &lt;asp:Repeater runat=<span style="color: #a31515;">"server"</span> DataSource=<span style="color: #a31515;">"</span>&lt;%# ((DsmItem) Container.DataItem).Dependencies %&gt;"&gt;
                            &lt;ItemTemplate&gt;
                                &lt;td&lt;%# ((KeyValuePair&lt;DsmItem,<span style="color: #2b91af;">int</span>&gt;) Container.DataItem).Key.IsActive ? (((KeyValuePair&lt;DsmItem,<span style="color: #2b91af;">int</span>&gt;) Container.DataItem).Value == -1 ? <span style="color: #a31515;">" class=\"self\""</span> : <span style="color: #2b91af;">string</span>.Format(<span style="color: #a31515;">" style=\"cursor:pointer;cursor:hand\" onclick=\"javascipt: document.getElementById('{2}').value = '{0}|{1}'; document.getElementById('{3}').click();\""</span>, ((KeyValuePair&lt;DsmItem,<span style="color: #2b91af;">int</span>&gt;) Container.DataItem).Key.Item.ID, ((DsmItem) DataBinder.Eval(Container.Parent, <span style="color: #a31515;">"Parent.DataItem"</span>)).Item.ID, txtSelectedItem.ClientID, btnUpdateDetail.ClientID)) : <span style="color: #a31515;">" class=\"inactive\""</span> %&gt;&gt;
                                    &lt;%# ((KeyValuePair&lt;DsmItem,<span style="color: #2b91af;">int</span>&gt;) Container.DataItem).Value &gt; 0 ? ((KeyValuePair&lt;DsmItem,<span style="color: #2b91af;">int</span>&gt;) Container.DataItem).Value.ToString() : <span style="color: #a31515;">"&amp;nbsp;"</span> %&gt;
                                &lt;/td&gt;
                            &lt;/ItemTemplate&gt;
                        &lt;/asp:Repeater&gt;
                    &lt;/tr&gt;
                &lt;/ItemTemplate&gt;
                &lt;FooterTemplate&gt;
                    &lt;/table&gt;
                &lt;/FooterTemplate&gt;
            &lt;/asp:Repeater&gt;
            &lt;input runat=<span style="color: #a31515;">"server"</span> ID=<span style="color: #a31515;">"txtSelectedItem"</span> type=<span style="color: #a31515;">"hidden"</span> /&gt;
            &lt;asp:Button runat=<span style="color: #a31515;">"server"</span> ID=<span style="color: #a31515;">"btnUpdateDetail"</span> CssClass=<span style="color: #a31515;">"hiddenbutton"</span> OnClick=<span style="color: #a31515;">"UpdateDetail"</span> /&gt;
            &lt;asp:Repeater runat=<span style="color: #a31515;">"server"</span> ID=<span style="color: #a31515;">"rptDetail"</span> DataSource=<span style="color: #a31515;">"</span>&lt;%# SelectedItemLinks %&gt;"&gt;
                &lt;HeaderTemplate&gt;
                    &lt;p&gt;References for '&lt;%# SelectedSourceItem.Name %&gt;' and its descendants to '&lt;%# SelectedTargetItem.Name %&gt;' and its descendants:&lt;/p&gt;
                    &lt;ul&gt;
                &lt;/HeaderTemplate&gt;
                &lt;ItemTemplate&gt;
                    &lt;li&gt;&lt;%# ((Sitecore.Links.ItemLink)Container.DataItem).GetSourceItem().Paths.FullPath %&gt;
                    &lt;br /&gt;references&lt;br /&gt;
                    &lt;%# ((Sitecore.Links.ItemLink)Container.DataItem).GetTargetItem().Paths.FullPath %&gt;&lt;/li&gt;
                &lt;/ItemTemplate&gt;
                &lt;FooterTemplate&gt;
                    &lt;/ul&gt;
                &lt;/FooterTemplate&gt;
            &lt;/asp:Repeater&gt;
        &lt;/div&gt;
    &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
]]></content:encoded>
			<wfw:commentRss>http://hermanussen.eu/sitecore/wordpress/2011/05/design-structure-matrix-dsm-for-your-content-tree/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Manage Sitecore config across environments (DTAP)</title>
		<link>http://hermanussen.eu/sitecore/wordpress/2011/05/manage-sitecore-config-across-environments-dtap/</link>
		<comments>http://hermanussen.eu/sitecore/wordpress/2011/05/manage-sitecore-config-across-environments-dtap/#comments</comments>
		<pubDate>Thu, 19 May 2011 06:24:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[sitecore tips]]></category>

		<guid isPermaLink="false">http://hermanussen.eu/sitecore/wordpress/?p=56</guid>
		<description><![CDATA[Managing different Sitecore environments can be quite cumbersome. One of the things that I think is annoying is managing the configuration. In my Web.config alone, I currently have 2910 lines of Sitecore configuration, excluding the different configuration files in App_Config! I&#8217;m sure others have found this annoying as well. Here&#8217;s a way of making things [...]]]></description>
			<content:encoded><![CDATA[<p>Managing different Sitecore environments can be quite cumbersome. One of the things that I think is annoying is managing the configuration. In my Web.config alone, I currently have 2910 lines of Sitecore configuration, excluding the different configuration files in App_Config! I&#8217;m sure others have found this annoying as well. Here&#8217;s a way of making things a lot easier.</p>
<p><strong>Disclaimer: by no means do I claim that this is the best way of doing this. If you know a better way, then please let me know!</strong></p>
<p><span style="text-decoration: underline;">The problem:</span></p>
<p>The problem is not that we have a lot of configuration; that is actually a good thing! But when you have separate environments, like in a <a title="Wikipedia article about DTAP" href="http://en.wikipedia.org/wiki/Development,_testing,_acceptance_and_production">DTAP</a> (Development, Testing, Acceptance and Production) setup, small changes to the configuration for each environment may be required. Here are a few suggestions for possible differences:</p>
<ul>
<li>Different connectionstrings</li>
<li>Different dataFolder, mediaFolder, tempFolder</li>
<li>Different cache sizes</li>
<li>Different Sitecore databases for websites (in development, it can be helpful to work on the master database directly)</li>
</ul>
<p>If you copy all the config files when deploying to a different environment, you will have to go through all of the configuration to make the environment specific changes. And if you do not copy all the config files, you will have to make all the normal changes (that are not environment specific) by hand. Chances are, you may forget something in both cases.</p>
<p><span style="text-decoration: underline;">A solution that we have used in the past:</span></p>
<p>We have made a folder structure containing the Web.config, ConnectionStrings.config and any other config file that contains environment specific settings for each environment. It looked similar to this:<br />
&gt; Web.config (development version can be in the original location)<br />
&gt; App_Config<br />
&gt;&gt; ConnectionStrings.config<br />
&gt; TEST<br />
&gt;&gt; Web.config<br />
&gt;&gt; App_Config<br />
&gt;&gt;&gt; ConnectionStrings.config<br />
&gt; ACC<br />
&#8230;</p>
<p>This appears to be better, because you know exactly what you need to include in your deployment. But with this approach, you rely on all the developers for keeping everything consistent; if someone makes a change to the DEV version of a config file and forgets to make the same changes for the other environments, the whole thing breaks.</p>
<p>Moreover, if you want to check the consistency between the different files, you will have to wade through these huge config files. A good diff tool like <a title="WinMerge website" href="http://winmerge.org/">WinMerge</a> can only go so far in helping you with this.</p>
<p><span style="text-decoration: underline;">A better solution:</span></p>
<p>I really would like to have only the differences between the environments in separate files. So the file structure as mentioned before is useful only if:</p>
<ul>
<li>Only the Web.config file is used. No other config files please!</li>
<li>The Web.config needs to be as small as possible, containing only the environment specific Sitecore settings.</li>
</ul>
<p>Luckily, putting all the Sitecore config in a separate file is quite easy. I made a new config file under App_Config called Sitecore.config and I copied the entire &lt;sitecore /&gt; section into it. Then I made the Web.config point to it, like this:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1
2
3</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">  &lt;sitecore&gt;
    &lt;sc.include file=<span style="color: #a31515;">"/App_Config/Sitecore.config"</span> /&gt;
  &lt;/sitecore&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>That cleans up the Web.config nicely! Why not externalize everything in the Web.config? Well, because the other configuration can be implemented differently (it is not specific to Sitecore) and may rely on the configuration being specified in the Web.config. Furthermore, the Web.config may be changed by IIS Manager. Be aware of this!</p>
<p><span style="text-decoration: underline;">Environment specific settings:</span></p>
<p>But this still does not solve our problem, because now we would need different versions of Sitecore.config for each environment. This would give us the same problems.</p>
<p>Again, Sitecore has a nice built in solution for this problem. The differences between the environments will mostly be references to file paths, urls or arbitrary strings. So all we really need in most cases is a simple text replace. Sitecore uses the &lt;sc.variable /&gt;  element for this.</p>
<p>So let&#8217;s move some variables that were copied to the Sitecore.config back to the Web.config first.</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1
2
3
4
5
6</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">  &lt;sitecore&gt;
    &lt;sc.variable name=<span style="color: #a31515;">"dataFolder"</span> value=<span style="color: #a31515;">"C:\Inetpub\wwwroot\SitecoreWebsite\data\"</span> /&gt;
    &lt;sc.variable name=<span style="color: #a31515;">"mediaFolder"</span> value=<span style="color: #a31515;">"/upload"</span> /&gt;
    &lt;sc.variable name=<span style="color: #a31515;">"tempFolder"</span> value=<span style="color: #a31515;">"/temp"</span> /&gt;
    &lt;sc.include file=<span style="color: #a31515;">"/App_Config/Sitecore.config"</span> /&gt;
  &lt;/sitecore&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>Now we have a nice base to work from.</p>
<p><span style="text-decoration: underline;">The ConnectionStrings.config:</span></p>
<p>The connection strings are not in the &lt;sitecore /&gt; section. So we need a way to include them in the Web.config. Turns out, this is pretty easy. However, <strong>I must warn you here</strong>: I did see something that worried me with <a title=".NET Reflector website" href="http://reflector.red-gate.com/">.NET Reflector</a> in ConfigModifier.dll, so I&#8217;m not sure that this solution will never break. It appears to read the connection strings directly from the App_Config/ConnectionStrings.config path. I may be mistaken, and I&#8217;ve had no problems with it so far. But if you want to be sure, then skip this step for now.</p>
<p>Change the connectionStrings section in your Web.config file, like this:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1
2
3
4
5
6</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">  <span style="color: #008000;">&lt;!--&lt;connectionStrings configSource="App_Config\ConnectionStrings.config" /&gt;--&gt;</span>
  &lt;connectionStrings&gt;
    &lt;add name=<span style="color: #a31515;">"core"</span> connectionString=<span style="color: #a31515;">"[insert_connection_string]"</span> /&gt;
    &lt;add name=<span style="color: #a31515;">"master"</span> connectionString=<span style="color: #a31515;">"[insert_connection_string]"</span> /&gt;
    &lt;add name=<span style="color: #a31515;">"web"</span> connectionString=<span style="color: #a31515;">"[insert_connection_string]"</span> /&gt;
  &lt;/connectionStrings&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>Don&#8217;t forget to remove the original ConnectionStrings.config file to avoid confusion.</p>
<p><span style="text-decoration: underline;">Specifying differences:</span></p>
<p>From now on, if you want to make something environment specific, you do the following:</p>
<ol>
<li>Replace the string in Sitecore.Config with a meaningful variable, for example<br />
<!-- HTML generated using hilite.me -->&nbsp;</p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1
2
3
4
5</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">      <span style="color: #008000;">&lt;!--  MEDIA - CACHING ENABLED</span>
<span style="color: #008000;">            Indicates if caching of media files is enabled.</span>
<span style="color: #008000;">            Default value: true</span>
<span style="color: #008000;">      --&gt;</span>
      &lt;setting name=<span style="color: #a31515;">"Media.CachingEnabled"</span> value=<span style="color: #a31515;">"$(setting.Media.CachingEnabled)"</span> /&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
</li>
<li>Then add a &lt;sc.variable /&gt; element to the Web.config for each environment (or only do it for DEV and use a diff tool before the deployment to see what you need to change)<br />
<!-- HTML generated using hilite.me -->&nbsp;</p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">&lt;sc.variable name=<span style="color: #a31515;">"setting.Media.CachingEnabled"</span> value=<span style="color: #a31515;">"true"</span> /&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
</li>
</ol>
<p>Here is a simple example of what your &lt;sitecore /&gt; section may look like for one environment in particular:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1
2
3
4
5
6
7
8
9</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">  &lt;sitecore&gt;
    &lt;sc.variable name=<span style="color: #a31515;">"dataFolder"</span> value=<span style="color: #a31515;">"C:\Inetpub\wwwroot\SitecoreWebsite\data\"</span> /&gt;
    &lt;sc.variable name=<span style="color: #a31515;">"mediaFolder"</span> value=<span style="color: #a31515;">"/upload"</span> /&gt;
    &lt;sc.variable name=<span style="color: #a31515;">"tempFolder"</span> value=<span style="color: #a31515;">"/temp"</span> /&gt;
    &lt;sc.variable name=<span style="color: #a31515;">"setting.WelcomeTitle"</span> value=<span style="color: #a31515;">"Welcome to Sitecore - DEV"</span> /&gt;
    &lt;sc.variable name=<span style="color: #a31515;">"setting.Media.CachingEnabled"</span> value=<span style="color: #a31515;">"false"</span> /&gt;
    &lt;sc.variable name=<span style="color: #a31515;">"sites.website.database"</span> value=<span style="color: #a31515;">"master"</span> /&gt;
    &lt;sc.include file=<span style="color: #a31515;">"/App_Config/Sitecore.config"</span> /&gt;
  &lt;/sitecore&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p><span style="text-decoration: underline;">Checking configuration:</span></p>
<p>So there you have it. An easier way of managing configuration across multiple environments. This way, you can always just Copy the App_Config folder and quickly identify differences between environments by comparing the cleaned up Web.config files.</p>
<p>Finally, I&#8217;d like to point out an easy way to check the current configuration of a Sitecore website. This allows you to see if your configuration changes worked out correctly. Go to this location on your site: /sitecore/admin/ShowConfig.aspx.</p>
]]></content:encoded>
			<wfw:commentRss>http://hermanussen.eu/sitecore/wordpress/2011/05/manage-sitecore-config-across-environments-dtap/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Better FieldRenderer usage with CDM</title>
		<link>http://hermanussen.eu/sitecore/wordpress/2011/05/better-fieldrenderer-usage-with-cdm/</link>
		<comments>http://hermanussen.eu/sitecore/wordpress/2011/05/better-fieldrenderer-usage-with-cdm/#comments</comments>
		<pubDate>Sat, 07 May 2011 11:44:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[code snippets]]></category>

		<guid isPermaLink="false">http://hermanussen.eu/sitecore/wordpress/?p=50</guid>
		<description><![CDATA[We&#8217;ve been using CompiledDomainModel for several projects now. And we keep inventing new ways to make things even better. Yesterday I was brainstorming with some colleagues about a better way of using the Sitecore FieldRenderer in combination with CDM. I found a very neat new way of doing this. But I&#8217;d like to share some [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve been using <a title="CDM Shared Source Module page" href="http://trac.sitecore.net/CompiledDomainModel/wiki">CompiledDomainModel</a> for several projects now. And we keep inventing new ways to make things even better.</p>
<p>Yesterday I was brainstorming with some colleagues about a better way of using the Sitecore FieldRenderer in combination with CDM. I found a very neat new way of doing this. But I&#8217;d like to share some of the different options, so that you can choose the best one for you.</p>
<p><strong>Traditional FieldRenderer without CDM:</strong></p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">&lt;sc:FieldRenderer runat=<span style="color: #a31515;">"server"</span> Item=<span style="color: #a31515;">"</span>&lt;%# SomeItem %&gt;" FieldName="Some field" /&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
<ul>
<li>Simple implementation</li>
<li>Spelling errors result in not displaying anything instead of an error</li>
<li>Not wrapped, so no custom functionality can be placed on the item</li>
</ul>
<p><strong>Use CDM without FieldRenderer:</strong></p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">&lt;%# SomeItemWrapper.SomeField %&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
<ul>
<li>Easy implementation</li>
<li>Typed access</li>
<li>The rendering pipeline is not used, so the page editor will not make this output editable</li>
</ul>
<p><strong>Traditional FieldRenderer with CDM (currently the most used with CDM):</strong></p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">&lt;sc:FieldRenderer runat=<span style="color: #a31515;">"server"</span> Item=<span style="color: #a31515;">"</span>&lt;%# SomeItemWrapper.Item %&gt;" FieldName="&lt;%# SomeType.FIELD_SOME_FIELD %&gt;" /&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
<ul>
<li>A bit of a pain to unwrap the Sitecore item every time</li>
<li>Spelling errors result in compilation errors, which is great!</li>
<li>The FieldName can refer to a field from an entirely different type (though this is not a very common mistake)</li>
</ul>
<p><strong>Custom FieldRenderer with CDM:</strong></p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">&lt;cl:CdmFieldRenderer runat=<span style="color: #a31515;">"server"</span> ItemWrapper=&lt;%# SomeItemWrapper %&gt; FieldName="&lt;%# SomeType.FIELD_SOME_FIELD %&gt;" /&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
<ul>
<li>The same as the previous one, but without the need to unwrap the Sitecore item every time</li>
<li>You need to use a non-standard control</li>
</ul>
<p><strong>Custom FieldRenderer with CDM and lambda expression:</strong></p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">&lt;cl:CdmFieldRenderer runat=<span style="color: #a31515;">"server"</span> Value=&lt;%# () =&gt; SomeItemWrapper.SomeField %&gt; /&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
<ul>
<li>The best possible type-safety</li>
<li>Only usable in .NET 4</li>
<li>You need to use a non-standard control</li>
</ul>
<p>The last one is the nicest one in my opinion. You can use it as if you are not using a field renderer at all, and still get all the benefits of a fieldrenderer (use of the rendering pipeline and editable in the page editor).</p>
<p>It works by using the <a title="MSDN about Expression Trees" href="http://msdn.microsoft.com/en-us/library/bb397951.aspx">expression tree</a> of the passed-in lambda expression and reflection to determine the name of the field. It shouldn&#8217;t be too hard to create similar controls for sc:Link and sc:Image. Here&#8217;s the code:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Web;
<span style="color: #0000ff;">using</span> Sitecore.Web.UI.WebControls;
<span style="color: #0000ff;">using</span> System.Linq.Expressions;
<span style="color: #0000ff;">using</span> MyDomainModel;
<span style="color: #0000ff;">using</span> System.Text.RegularExpressions;
<span style="color: #0000ff;">using</span> System.Reflection;

<span style="color: #0000ff;">namespace</span> CompiledDomainModel.Demo.FeedReader.Controls
{
    <span style="color: #008000;">/// &lt;summary&gt;</span>
    <span style="color: #008000;">/// Fieldrenderer control that can be used with a CompiledDomainModel.</span>
    <span style="color: #008000;">/// &lt;/summary&gt;</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">CdmFieldRenderer</span> : FieldRenderer
    {
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">readonly</span> Regex CONST_NAME_REPLACE = <span style="color: #0000ff;">new</span> Regex(<span style="color: #a31515;">"([A-Z]+[a-z]+)"</span>, RegexOptions.Compiled);

        <span style="color: #008000;">/// &lt;summary&gt;</span>
        <span style="color: #008000;">/// Pass a function that returns the property value in a CompiledDomainModel object.</span>
        <span style="color: #008000;">/// This property will then attempt to set the item and field name of the Sitecore fieldrenderer.</span>
        <span style="color: #008000;">/// &lt;/summary&gt;</span>
        <span style="color: #0000ff;">public</span> System.Linq.Expressions.Expression&lt;Func&lt;<span style="color: #2b91af;">object</span>&gt;&gt; Value
        {
            <span style="color: #0000ff;">set</span>
            {
                <span style="color: #008000;">// strip unary expression if needed, like boxing conversion for value types</span>
                Expression valueExpr = <span style="color: #0000ff;">value</span>.Body;
                UnaryExpression unaryExpr = valueExpr <span style="color: #0000ff;">as</span> UnaryExpression;
                <span style="color: #0000ff;">if</span> (unaryExpr != <span style="color: #0000ff;">null</span>)
                {
                    valueExpr = unaryExpr.Operand;
                }

                MemberExpression bodyExpr = valueExpr <span style="color: #0000ff;">as</span> MemberExpression;
                <span style="color: #0000ff;">if</span> (bodyExpr != <span style="color: #0000ff;">null</span> &amp;&amp; bodyExpr.Expression != <span style="color: #0000ff;">null</span>)
                {
                    <span style="color: #008000;">// get the name of the property in the CDM class</span>
                    <span style="color: #2b91af;">string</span> propertyName = bodyExpr.Member.Name;

                    <span style="color: #008000;">// get the itemwrapper by invoking the contained expression</span>
                    var compiledExpr = Expression.Lambda(bodyExpr.Expression).Compile();
                    IItemWrapper itemWrapper = compiledExpr.DynamicInvoke() <span style="color: #0000ff;">as</span> IItemWrapper;
                    <span style="color: #0000ff;">if</span> (! <span style="color: #2b91af;">string</span>.IsNullOrEmpty(propertyName) &amp;&amp; itemWrapper != <span style="color: #0000ff;">null</span>)
                    {
                        <span style="color: #008000;">// attempt to determine the name of the constant that holds the field name</span>
                        <span style="color: #2b91af;">string</span> constantName = CONST_NAME_REPLACE.Replace(propertyName, m =&gt; (m.Value.Length &gt; 3 ? m.Value : m.Value.ToLower()) + <span style="color: #a31515;">"_"</span>);
                        constantName = <span style="color: #2b91af;">string</span>.Format(<span style="color: #a31515;">"FIELD_{0}"</span>, constantName.TrimEnd(<span style="color: #0000ff;">new</span> [] { <span style="color: #a31515;">'_'</span> }).ToUpperInvariant());
                        System.Reflection.FieldInfo constant = itemWrapper.GetType().GetField(constantName, BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
                        <span style="color: #0000ff;">if</span> (constant != <span style="color: #0000ff;">null</span>)
                        {
                            <span style="color: #008000;">// set the correct values on the control, so the field can be rendered and is compatible with the page editor</span>
                            Item = itemWrapper.Item;
                            FieldName = constant.GetValue(<span style="color: #0000ff;">null</span>) <span style="color: #0000ff;">as</span> <span style="color: #2b91af;">string</span>;
                        }
                    }
                }
            }
        }
    }
}</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://hermanussen.eu/sitecore/wordpress/2011/05/better-fieldrenderer-usage-with-cdm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Prevent nullrefs when databinding with placeholders</title>
		<link>http://hermanussen.eu/sitecore/wordpress/2011/04/prevent-nullrefs-when-databinding-with-placeholders/</link>
		<comments>http://hermanussen.eu/sitecore/wordpress/2011/04/prevent-nullrefs-when-databinding-with-placeholders/#comments</comments>
		<pubDate>Sun, 10 Apr 2011 15:21:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[code snippets]]></category>

		<guid isPermaLink="false">http://hermanussen.eu/sitecore/wordpress/?p=43</guid>
		<description><![CDATA[I love databinding. It allows me to keep view-logic in ascx/aspx files so I don&#8217;t have to read long code-behind files laden with initialization logic and page lifecycle related crap. Databinding works better with WPF and Silverlight than it does with ASP.NET. But in my humble opinion it still beats the alternative in ASP.NET. One [...]]]></description>
			<content:encoded><![CDATA[<p>I love databinding. It allows me to keep view-logic in ascx/aspx files so I don&#8217;t have to read long code-behind files laden with initialization logic and page lifecycle related crap.</p>
<p>Databinding works better with WPF and Silverlight than it does with ASP.NET. But in my humble opinion it still beats the alternative in ASP.NET.</p>
<p>One very annoying problem I&#8217;ve run into when using databinding in ASP.NET is the use of placeholders. The placeholder is a control that we use as the equivalent of an if-statement in C#. If the &#8220;Visible&#8221; property evaluates as true, only then the contents are rendered.</p>
<p>This works well in most cases. But when you use databinding it sort of breaks. For example:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1
2
3</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">        &lt;asp:PlaceHolder runat=<span style="color: #a31515;">"server"</span> Visible=<span style="color: #a31515;">"</span>&lt;%# SomeProperty != <span style="color: #0000ff;">null</span> %&gt;"&gt;
            &lt;p&gt;Normal placeholder - &lt;%# SomeProperty.Name %&gt;&lt;/p&gt;
        &lt;/asp:PlaceHolder&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>This code will work perfectly fine, unless &#8220;SomeProperty&#8221; evaluates to null, because the contents of the placeholder are always evaluated! This problem is especially annoying with Sitecore FieldRenderers, which don&#8217;t allow the &#8220;Item&#8221; property to be null. A simple fix to this problem is to repeat the null-check within the placeholder, like so:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1
2
3</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">        &lt;asp:PlaceHolder runat=<span style="color: #a31515;">"server"</span> Visible=<span style="color: #a31515;">"</span>&lt;%# SomeProperty != <span style="color: #0000ff;">null</span> %&gt;"&gt;
            &lt;p&gt;Normal placeholder - &lt;%# SomeProperty != <span style="color: #0000ff;">null</span> ? SomeProperty.Name : <span style="color: #0000ff;">null</span> %&gt;&lt;/p&gt;
        &lt;/asp:PlaceHolder&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>But if you would have a more complicated condition, many unsafe binding statements within the placeholder or nesting of several placeholders, this fix can prove to be quite cumbersome.</p>
<p>So I tried to find a good workaround for this problem and I observed the repeater control. It does not have this problem, because the contents of &#8220;ItemTemplate&#8221; will never be evaluated if the collection in the datasource is empty. This is what I came up with:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1
2
3
4
5</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">        &lt;asp:Repeater runat=<span style="color: #a31515;">"server"</span> DataSource=<span style="color: #a31515;">"</span>&lt;%# SomeProperty != <span style="color: #0000ff;">null</span> ? <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">int</span>[] { 0 } : <span style="color: #0000ff;">null</span> %&gt;"&gt;
            &lt;ItemTemplate&gt;
                &lt;p&gt;Simple workaround using repeater - &lt;%# SomeProperty.Name %&gt;&lt;/p&gt;
            &lt;/ItemTemplate&gt;
        &lt;/asp:Repeater&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>That works really well! I used the repeater as a placeholder and now, if &#8220;SomeProperty&#8221; evaluates to null, there will be no problem; the contents of &#8220;ItemTemplate&#8221; are never evaluated by the databinder.</p>
<p>Still, this is quite an ugly workaround, because it&#8217;s pretty verbose and not really intuitive to programmers. So we need a better solution.</p>
<p>And I found one! I created a custom control that derives from the PlaceHolder control. The only difference in behaviour is that the contents of the control are not evaluated by the databinder if the &#8220;Visible&#8221; property is null. Here&#8217;s the code for the control:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">using</span> System;
<span style="color: #0000ff;">using</span> System.Collections.Generic;
<span style="color: #0000ff;">using</span> System.Linq;
<span style="color: #0000ff;">using</span> System.Web;
<span style="color: #0000ff;">using</span> System.Web.UI.WebControls;

<span style="color: #0000ff;">namespace</span> Website.Controls
{
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> <span style="color: #2b91af;">DataPlaceHolder</span> : PlaceHolder
    {
        <span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">override</span> <span style="color: #0000ff;">void</span> DataBindChildren()
        {
            <span style="color: #0000ff;">if</span> (Visible)
            {
                <span style="color: #0000ff;">base</span>.DataBindChildren();
            }
        }
    }
}</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>This is a pretty simple change, but it makes life so much easier. If we import the control and use it in the following way, we no longer have to worry about nullref problems:</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;">1
2
3</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;">        &lt;cl:DataPlaceHolder runat=<span style="color: #a31515;">"server"</span> Visible=<span style="color: #a31515;">"</span>&lt;%# SomeProperty != <span style="color: #0000ff;">null</span> %&gt;"&gt;
            &lt;p&gt;Custom control that disables databinding children if invisible - &lt;%# SomeProperty.Name %&gt;&lt;/p&gt;
        &lt;/cl:DataPlaceHolder&gt;</pre>
</td>
</tr>
</tbody>
</table>
</div>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://hermanussen.eu/sitecore/wordpress/2011/04/prevent-nullrefs-when-databinding-with-placeholders/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Update CompiledDomainModel from Visual Studio</title>
		<link>http://hermanussen.eu/sitecore/wordpress/2011/04/update-compileddomainmodel-from-visual-studio/</link>
		<comments>http://hermanussen.eu/sitecore/wordpress/2011/04/update-compileddomainmodel-from-visual-studio/#comments</comments>
		<pubDate>Tue, 05 Apr 2011 21:29:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[code snippets]]></category>

		<guid isPermaLink="false">http://hermanussen.eu/sitecore/wordpress/?p=35</guid>
		<description><![CDATA[My friend and I were talking about the CompiledDomainModel module the other day. He suggested that it would be a little easier if you could update the code from Visual Studio. A few options were discussed, until we arrived at a rather nifty one. The generated code would start with a certain prefix, followed by [...]]]></description>
			<content:encoded><![CDATA[<p>My friend and I were talking about the CompiledDomainModel module the other day. He suggested that it would be a little easier if you could update the code from Visual Studio.</p>
<p>A few options were discussed, until we arrived at a rather nifty one. The generated code would start with a certain prefix, followed by a url that can be used to regenerate the code. Then, a Visual Studio plugin or macro could refresh the code by downloading it from that location.</p>
<p>Well, I&#8217;ve implemented just that! The code needed in CompiledDomainModel can be found in the current trunk version in SVN and I´ll add it to the release notes for the next release. The macro for updating generated code can be found on this page.</p>
<p>The following steps should be taken to generate code from Visual Studio (I&#8217;ve tested this with VS2010, and I&#8217;m not sure if it will work with VS2008):</p>
<ol>
<li>Make sure you have the CompiledDomainModel version from the trunk (or the release after 0.4.1.0, when it&#8217;s released)</li>
<li>Generate the code and paste it into a file in your solution in Visual Studio</li>
<li>Install the macro<br />
<em>Now, you&#8217;re all set up to use the macro, so you can skip the first 3 steps next time</em></li>
<li>Open the generated file from the Solution Explorer and make sure it is checked out of source control (if configured)</li>
<li>Run the macro</li>
<li>Choose to reload the file from the file system when asked about it</li>
</ol>
<p>You may notice a few things that are not that convenient yet:</p>
<ul>
<li>You have to actually open the file before regenerating it &#8211; This was the quickest way I could figure this out. If anyone knows how to get the selected file from the solution explorer, then please let me know!</li>
<li>You have to check out the file from source control &#8211; The file must be writable. The macro writes the generated code directly to the filesystem, because writing it in the editor turned out te be way too slow. Perhaps source control can be controlled from the macro as well, but I don&#8217;t know how to do that.</li>
<li>The module needs to be accessible to anonymous users, as the macro isn&#8217;t authenticated in Sitecore. But this is not really a problem in a development environment. This does mean that the comment always says &#8220;User &#8216;sitecore\Anonymous&#8217; generated this file.&#8221;.</li>
</ul>
<p>I&#8217;ve never coded a macro before; I&#8217;ve never even coded in VB.NET before (yes, I said the UGLY word). But even with these minor issues, the macro does seem to make things a little easier if you need to regenerate the code often.</p>
<p>Here&#8217;s the code for the macro. Have fun!</p>
<p><!-- HTML generated using hilite.me --></p>
<div style="background: white; overflow: auto; width: auto; color: black; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<table>
<tbody>
<tr>
<td>
<pre style="margin: 0; line-height: 125%;"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38</pre>
</td>
<td>
<pre style="margin: 0; line-height: 125%;"><span style="color: #0000ff;">Imports</span> System
<span style="color: #0000ff;">Imports</span> EnvDTE
<span style="color: #0000ff;">Imports</span> EnvDTE80
<span style="color: #0000ff;">Imports</span> EnvDTE90
<span style="color: #0000ff;">Imports</span> EnvDTE90a
<span style="color: #0000ff;">Imports</span> EnvDTE100
<span style="color: #0000ff;">Imports</span> System.Diagnostics
<span style="color: #0000ff;">Imports</span> System.Net
<span style="color: #0000ff;">Imports</span> System.Text
<span style="color: #0000ff;">Imports</span> System.IO

<span style="color: #0000ff;">Public</span> <span style="color: #0000ff;">Module</span> CdmHelper

    <span style="color: #0000ff;">Sub</span> CdmRegenerateCode()
        <span style="color: #0000ff;">If</span> <span style="color: #0000ff;">Not</span> DTE.ActiveDocument <span style="color: #0000ff;">Is</span> <span style="color: #0000ff;">Nothing</span> <span style="color: #0000ff;">Then</span>
            <span style="color: #0000ff;">Dim</span> fileStream <span style="color: #0000ff;">As</span> StreamReader = File.OpenText(DTE.ActiveDocument.FullName)
            <span style="color: #0000ff;">Dim</span> firstLine <span style="color: #0000ff;">As</span> <span style="color: #2b91af;">String</span> = fileStream.ReadLine()
            fileStream.Close()

            <span style="color: #0000ff;">Dim</span> prefix <span style="color: #0000ff;">As</span> <span style="color: #2b91af;">String</span> = <span style="color: #a31515;">"// Refresh from URL: "</span>
            <span style="color: #0000ff;">Dim</span> prefixSql <span style="color: #0000ff;">As</span> <span style="color: #2b91af;">String</span> = <span style="color: #a31515;">"-- Refresh from URL: "</span>

            <span style="color: #0000ff;">If</span> firstLine.StartsWith(prefix) <span style="color: #0000ff;">Or</span> firstLine.StartsWith(prefixSql) <span style="color: #0000ff;">Then</span>
                <span style="color: #0000ff;">Dim</span> URL <span style="color: #0000ff;">As</span> <span style="color: #2b91af;">String</span> = firstLine.Substring(prefix.Length)
                <span style="color: #0000ff;">Dim</span> client <span style="color: #0000ff;">As</span> WebClient = <span style="color: #0000ff;">New</span> WebClient()
                <span style="color: #0000ff;">Dim</span> objUTF8 <span style="color: #0000ff;">As</span> <span style="color: #0000ff;">New</span> UTF8Encoding()
                <span style="color: #0000ff;">Dim</span> result <span style="color: #0000ff;">As</span> <span style="color: #2b91af;">String</span> = objUTF8.GetString(client.DownloadData(URL))

                File.WriteAllText(DTE.ActiveDocument.FullName, result.TrimStart())
            <span style="color: #0000ff;">Else</span>
                MsgBox(<span style="color: #a31515;">"The selected file does not start with '"</span> + prefix + <span style="color: #a31515;">"'. You can only select a valid generated file from CompiledDomainModel."</span>)
            <span style="color: #0000ff;">End</span> <span style="color: #0000ff;">If</span>
        <span style="color: #0000ff;">Else</span>
            MsgBox(<span style="color: #a31515;">"Select a file that was generated using CompiledDomainModel first."</span>)
        <span style="color: #0000ff;">End</span> <span style="color: #0000ff;">If</span>
    <span style="color: #0000ff;">End</span> <span style="color: #0000ff;">Sub</span>
<span style="color: #0000ff;">End</span> <span style="color: #0000ff;">Module</span></pre>
</td>
</tr>
</tbody>
</table>
</div>
]]></content:encoded>
			<wfw:commentRss>http://hermanussen.eu/sitecore/wordpress/2011/04/update-compileddomainmodel-from-visual-studio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

