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

<channel>
	<title>Coffee =&#62; Coder =&#62; Code</title>
	<atom:link href="http://adeneys.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://adeneys.wordpress.com</link>
	<description>My ramblings on code, Sitecore and stuff</description>
	<lastBuildDate>Mon, 01 Feb 2010 11:30:48 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='adeneys.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/c0c0b74d2147058c089fc21e8548c440?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Coffee =&#62; Coder =&#62; Code</title>
		<link>http://adeneys.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://adeneys.wordpress.com/osd.xml" title="Coffee =&gt; Coder =&gt; Code" />
		<item>
		<title>2009 Sitecore MVPs, Welcome to the club</title>
		<link>http://adeneys.wordpress.com/2010/02/01/2009-sitecore-mvps-welcome-to-the-club/</link>
		<comments>http://adeneys.wordpress.com/2010/02/01/2009-sitecore-mvps-welcome-to-the-club/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 11:30:48 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>

		<guid isPermaLink="false">http://adeneys.wordpress.com/2010/02/01/2009-sitecore-mvps-welcome-to-the-club/</guid>
		<description><![CDATA[Well, Sitecore has just announced the newest members of the MVP club. You can read all about the 2009 MVPs and the MVP programme in Sitecore’s press release which you can find here: http://www.sitecore.net/News/Press-releases/2009/Sitecore-MVPs.aspx.
I’d like to welcome to the club the following 2009 Sitecore MVPs.

Guillaume Buat-Ménard from Aqueduct 
Jason Davey from Bullseye 
Sebastian Winslow from [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=153&subd=adeneys&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>Well, Sitecore has just announced the newest members of the MVP club. You can read all about the 2009 MVPs and the MVP programme in Sitecore’s press release which you can find here: <a title="http://www.sitecore.net/News/Press-releases/2009/Sitecore-MVPs.aspx" href="http://www.sitecore.net/News/Press-releases/2009/Sitecore-MVPs.aspx">http://www.sitecore.net/News/Press-releases/2009/Sitecore-MVPs.aspx</a>.</p>
<p>I’d like to welcome to the club the following 2009 Sitecore MVPs.</p>
<ul>
<li>Guillaume Buat-Ménard from <a title="Aqueduct website" href="http://www.aqueduct.co.uk/" target="_blank">Aqueduct</a> </li>
<li><a title="Jason Davey&#39;s blog" href="http://blog.bullseye.com.au/" target="_blank">Jason Davey</a> from <a title="Bullseye website" href="http://www.bullseye.com.au/" target="_blank">Bullseye</a> </li>
<li><a title="Sebastian Winslow blog contributor" href="http://www.hockblogs.net/" target="_blank">Sebastian Winslow</a> from <a title="Codehouse website" href="http://www.codehouse.dk/" target="_blank">Codehouse</a> </li>
<li>Stefan van Dockum from <a title="Colours website" href="http://www.colours.nl/" target="_blank">Colours</a> </li>
<li>Kern Herskind Hansen </li>
<li><a title="Vincent van Middendorp&#39;s blog" href="http://tech.digisaru.com/" target="_blank">Vincent van Middendorp</a> from <a title="Evident Interactive website" href="http://www.evident.nl/" target="_blank">Evident Interactive</a> </li>
<li><a title="Sean Kearney&#39;s blog" href="http://seankearney.com/" target="_blank">Sean Kearney</a> from <a title="Hedgehog Development website" href="http://www.hhogdev.com/" target="_blank">Hedgehog Development</a> </li>
<li>Andreas Bergström from <a title="Metamatrix website" href="http://www.metamatrix.se/" target="_blank">Metamatrix</a> </li>
<li><a title="Jens Mikkelsen blog contributor" href="http://mcore.wordpress.com/" target="_blank">Jens Mikkelsen</a> from <a title="Pentia website" href="http://www.pentia.dk/" target="_blank">Pentia</a> </li>
<li><a title="Matt Hovany&#39;s website" href="http://www.matthovany.com/wiki/Matt_Hovany" target="_blank">Matt Hovany</a> from <a title="The Revere Group website" href="http://www.reveregroup.com/" target="_blank">The Revere Group</a> </li>
<li>Aren Cambre from <a title="Southern Methodist University website" href="http://www.smu.edu/" target="_blank">Southern Methodist University</a> </li>
<li>Gabriel Boys from <a title="Velir website" href="http://www.velir.com/" target="_blank">Velir</a> </li>
</ul>
<p>I did my best to collate the blogs and company websites of the 2009 MVPs. If I got any wrong please let me know so I can update the links. Especially for the non-English sites <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p><a title="Mark Cassidy&#39;s Sitecore blog" href="http://www.cassidy.dk/blog/sitecore/" target="_blank">Mark Cassidy</a> (fellow MVP) compiled a very good list of the 2008 MVPs at <a title="http://www.cassidy.dk/blog/sitecore/2009/01/sitecore-mvps-announced.html" href="http://www.cassidy.dk/blog/sitecore/2009/01/sitecore-mvps-announced.html">http://www.cassidy.dk/blog/sitecore/2009/01/sitecore-mvps-announced.html</a>. As you can see, MVP is not just for bloggers. It is an award for anyone who promotes and evangelises Sitecore and knowledge about developing with Sitecore.</p>
<p>Sitecore MVP awards last for 2 years, so all the 2008 MVPs (one of which is me) still stand. This brings the total worldwide MVP count to 27. Actually, I think it’s more like 25 cause you lose MVP status if you start working for Sitecore as the MVP award is for professionals outside of Sitecore.</p>
<p>And I’ve gotta say, given what I was shown as an MVP last year before the rest of the crowd, I’m quite excited at what I might be privy to this year.</p>
<p>Congratulations to all the 2009 Sitecore MVPs. If we manage to meet up I’ll show you the secret handshake <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/153/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/153/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/153/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/153/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/153/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/153/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/153/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/153/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/153/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/153/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=153&subd=adeneys&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2010/02/01/2009-sitecore-mvps-welcome-to-the-club/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b4591048ba49c1111162c1db646f4147?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alistair Deneys</media:title>
		</media:content>
	</item>
		<item>
		<title>Revolver 1.1 is Released!</title>
		<link>http://adeneys.wordpress.com/2010/01/15/revolver-1-1-is-released/</link>
		<comments>http://adeneys.wordpress.com/2010/01/15/revolver-1-1-is-released/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 13:08:39 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Revolver]]></category>
		<category><![CDATA[Sitecore]]></category>

		<guid isPermaLink="false">http://adeneys.wordpress.com/2010/01/15/revolver-1-1-is-released/</guid>
		<description><![CDATA[It&#8217;s been a very long ride, but the next minor version of Revolver has finally been released. If you currently hold a license for Revolver you can download the new version from the Revolver downloads page on the codeflood website. The quick start guide has also been updated.
In case you haven&#8217;t seen it yet, Revolver [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=152&subd=adeneys&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>It&#8217;s been a very long ride, but the next minor version of <a title="Revolver home page" href="http://www.codeflood.net/revolver/" target="_blank">Revolver</a> has finally been released. If you currently hold a license for Revolver you can download the new version from the <a title="Revolver downloads page" href="http://www.codeflood.net/revolver/download/" target="_blank">Revolver downloads page</a> on the <a title="codeflood website" href="http://www.codeflood.net/" target="_blank">codeflood</a> website. The <a title="Revolver quick start guide" href="http://www.codeflood.net/files/Revolver%20Quick%20Start%20Guide.pdf" target="_blank">quick start guide</a> has also been updated.</p>
<p>In case you haven&#8217;t seen it yet, Revolver is a module I wrote for Sitecore to provide a command prompt inside the Sitecore desktop. This allows the developer or administrator to interact with Sitecore in a much different way (through text) which is much better for performing certain actions like executing ad-hoc queries against the content tree or performing bulk update operations.</p>
<p>So what&#8217;s new in Revolver 1.1? There have been lots of updates. Some you&#8217;ll be able to see, some you won&#8217;t. There has been a bit of a reworking of some of the internal code to make it more consistent and easier to maintain in the future. The following is a list of the new features and commands of Revolver 1.1 in implementation order.</p>
<ol>
<li>
<p><strong>No Stats for find and query.</strong> I&#8217;ve added the <code>-ns</code> flag to pass to the <code>find</code> and <code>query</code> commands. This causes the command to not output the count of how many items were found. This will allow you to use these commands in sub commands.</p>
</li>
<li>
<p><strong>Path parameters for query.</strong> Now, this is kind of a funny one. Sitecore query already allows you to specify a path. But to remain consistent with the rest of the Revolver commands I added the ability to specify a path to run the query at.</p>
</li>
<li>
<p><strong>Slash = root.</strong> The <code>cd</code> command has been updated to allow the use of slash (/) to refer to the root item of the content tree (sitecore item).</p>
<pre>
<code>cd /</code>
</pre>
</li>
<li>
<p><strong>Added the split command.</strong> The split command allows you to split a string on a given token, newline characters or tab characters then execute a command against each element. So I could split a multilist field and display the names of each item.</p>
<pre>
<code>split -s | &lt; (gf -f multilist) (ga -a name $current$)</code>
</pre>
<p>The token <code>$current$</code> can be used in the command parameter and represents the current element from the split string. I could also do something like create a bunch of items based on a text file on the file system that contains a single name per line.</p>
<pre>
<code>split -n &lt; (echo -i -f itemnames.txt) (touch -t document $current$)</code>
</pre>
</li>
<li>
<p><strong>Added the ct command.</strong> The <code>ct</code> command allows you to change the template of an item. The command checks to ensure the target template contains the right fields so you don&#8217;t lose field data. You can force the change if you want to change to a new template which doesn&#8217;t contain all the currently used fields and you&#8217;re happy to lose that field data by using the <code>-f</code> flag.</p>
</li>
<li>
<p><strong>Case insensitive regexs</strong> The regular expressions used on the <code>ls</code> and <code>find</code> commands previously were case sensitive, but more often than not we don&#8217;t care about the case. So the regexs are now case insensitive by default and you can pass the <code>-c</code> flag to the command to make them case sensitive.</p>
</li>
<li>
<p><strong>Added the users command</strong> The <code>users</code> command can be used to list the current sessions of the Sitecore application and also to kick a session. Note though, even though the session is kicked to allow another session to start, if the owner of the kicked session makes another request before the available sessions runs out they will have a new session automatically created for them.</p>
</li>
<li>
<p><strong>Fast query support</strong> Revolver now supports Sitecore&#8217;s fast query. Simply prefix the Sitecore query you pass to the <code>query</code> command with <code>fast:</code></p>
</li>
<li>
<p><strong>Added support for branches</strong> Sitecore 6.0 did away with masters and introduced branches. Revolver now supports branches on a number of commands.</p>
</li>
<li>
<p><strong>Purge all languages</strong> The <code>rmv</code> command now supports passing an <code>-a</code> flag to indicate you want to remove versions in all languages and not just the current language.</p>
</li>
<li>
<p><strong>Comments in scripts</strong> You can now include comments in your scripts by starting the line with a hash (#) symbol.</p>
</li>
<li>
<p><strong>Help for scripts</strong> The script data template now has fields to support the help system of Revolver including adding examples.</p>
</li>
<li>
<p><strong>Added lsdb command</strong> The <code>lsdb</code> command lists all the databases of the current system.</p>
</li>
<li>
<p><strong>Added the lm command</strong> The <code>lm</code> command allows you to manipulate lists. So now you can add an ID to a multilist field and be sure it won&#8217;t add it twice.</p>
<pre>
<code>sf multilist &lt; (lm -a &lt; (gf -f multilist) | {945F96B9-5A7D-459C-8240-3A61362A0D32})</code>
</pre>
<p>Or you could remove the ID and not have to worry about where it appears in the list or having an empty element resulting in two pipes next to each other in the field.</p>
<pre>
<code>sf multilist &lt; (lm -r &lt; (gf -f multilist) | {945F96B9-5A7D-459C-8240-3A61362A0D32})</code>
</pre>
</li>
<li>
<p><strong>Added exit command</strong> You can now close a Revolver window by simply typing <code>exit</code>. Although I say it is a command, it&#8217;s not actually&#8230;</p>
</li>
<li>
<p><strong>Ajax submission</strong> The previous version of Revolver used Sitecore&#8217;s postEvent function which causes the entire form to post back to the server. That includes all the text in the command window including all the commands you&#8217;ve typed and all the responses. The new version of Revolver now uses Ajax to send only the current command to the server, then inserts the response into the textbox. Much more efficient.</p>
</li>
<li>
<p><strong>More operations in expressions</strong> Expressions (used in the <code>find</code> command) now support the following operations. Starts with ([), ends with (]) and contains (?). So I could now look for any child item of the current context that starts with &#8220;abc&#8221;.</p>
<pre>
<code>find -e (@@name [ abc) pwd</code>
</pre>
<p>Or search for items which contain &#8220;Sitecore&#8221; in the text field.</p>
<pre>
<code>find -e (@text ? sitecore) pwd</code>
</pre>
</li>
<li>
<p><strong>Added support for UNC paths to echo</strong> The <code>echo</code> command now supports files on UNC paths and not just local files.</p>
</li>
<li>
<p><strong>Ensure output folder in echo</strong> The <code>echo</code> command now also ensures folders which you&#8217;re outputting to exist before writing any output files, and if the folder doesn&#8217;t exist it will create it.</p>
</li>
<li>
<p><strong>Sorting on ls command</strong> The <code>ls</code> command now supports sorting of the content. By default the items will be displayed in Sitecore order. But they can be reversed using the <code>-d</code> flag or alphabetically using the <code>-a</code> flag.</p>
</li>
<li>
<p><strong>Output text limit</strong> Revolver now contains an <code>outputbuffer</code> environment variable which defines the maximum number of characters that can be contained in the output window.</p>
</li>
<li>
<p><strong>Input a newline in a field</strong> The Revolver UI now allows you to use shift + enter to input a newline. This can be used to enter multiple lines into a rich text or multiline text field.</p>
</li>
<li>
<p><strong>Added grep command</strong> The <code>grep</code> command works the same way as grep on a unix or linux system. grep is used to filter multiple lines and match each line against a regular expression. This allows you to search through a lot of input. So you could search through a list of sessions returned by the <code>users</code> command.</p>
<pre>
<code>grep admin &lt; users</code>
</pre>
</li>
<li>
<p><strong>Added links command</strong> The <code>links</code> command allows you to list incoming, outgoing and bad links for the context item.</p>
</li>
</ol>
<p>And remember, you can always use the <code>help</code> command to get detailed help for any command in Revolver.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/152/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/152/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/152/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/152/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/152/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/152/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/152/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/152/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/152/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/152/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=152&subd=adeneys&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2010/01/15/revolver-1-1-is-released/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b4591048ba49c1111162c1db646f4147?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alistair Deneys</media:title>
		</media:content>
	</item>
		<item>
		<title>Announcing codeflood</title>
		<link>http://adeneys.wordpress.com/2010/01/06/announcing-codeflood/</link>
		<comments>http://adeneys.wordpress.com/2010/01/06/announcing-codeflood/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 13:01:13 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://adeneys.wordpress.com/2010/01/06/announcing-codeflood/</guid>
		<description><![CDATA[It is with great pleasure I finally announce the launch of my new website, codeflood. So what is codeflood? codeflood is an attempt at a more professional web presence than my previous self indulgent website World of Al. codeflood is where I will host my projects such as Revolver for Sitecore and SashimiCMS.
Although the current [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=150&subd=adeneys&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>It is with great pleasure I finally announce the launch of my new website, <a title="codeflood website" href="http://www.codeflood.net" target="_blank">codeflood</a>. So what is codeflood? codeflood is an attempt at a more professional web presence than my previous self indulgent website <a title="World of Al website" href="http://users.tpg.com.au/adeneys/" target="_blank">World of Al</a>. codeflood is where I will host my projects such as <a title="Revolver for Sitecore" href="http://www.codeflood.net/revolver/" target="_blank">Revolver</a> for Sitecore and <a title="SashimiCMS homepage" href="http://www.codeflood.net/sashimicms/" target="_blank">SashimiCMS</a>.</p>
<p>Although the current project pages on World of Al will remain, all the new stuff and new versions will be released through codeflood. I&#8217;ll add a nice little message to the deprecated pages on World of Al to point users to codeflood.</p>
<p>I&#8217;ve gotta say, I&#8217;m quite excited to finally get this website live. I&#8217;ve been slaving over getting it live since the start of December, and interrupting my other projects such as the next version of Revolver and the Sitecore shared source Integrated Help Module. More on both of those to come&#8230;</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/150/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/150/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/150/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/150/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/150/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/150/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/150/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/150/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/150/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/150/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=150&subd=adeneys&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2010/01/06/announcing-codeflood/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b4591048ba49c1111162c1db646f4147?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alistair Deneys</media:title>
		</media:content>
	</item>
		<item>
		<title>Custom Tokens and NVelocity for Item Creation</title>
		<link>http://adeneys.wordpress.com/2009/12/29/custom-tokens-and-nvelocity-for-item-creation/</link>
		<comments>http://adeneys.wordpress.com/2009/12/29/custom-tokens-and-nvelocity-for-item-creation/#comments</comments>
		<pubDate>Mon, 28 Dec 2009 22:05:29 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>

		<guid isPermaLink="false">http://adeneys.wordpress.com/2009/12/29/custom-tokens-and-nvelocity-for-item-creation/</guid>
		<description><![CDATA[We&#8217;d all be familiar with the tokens you can use in template standard values which get replaced on item creation in Sitecore. They are a great way to set some default field values based on some other data such as the name given to the item or the current date.
The following lists the tokens available [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=149&subd=adeneys&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>We&#8217;d all be familiar with the tokens you can use in template standard values which get replaced on item creation in Sitecore. They are a great way to set some default field values based on some other data such as the name given to the item or the current date.</p>
<p>The following lists the tokens available in Sitecore 6.2.</p>
<dl>
<dt>$name</dt>
<dd>The name of the item being created</dd>
<dt>$id</dt>
<dd>The ID of the item being created</dd>
<dt>$parentid</dt>
<dd>The ID of the parent of the item being created</dd>
<dt>$parentname</dt>
<dd>The name of the parent of the item being created</dd>
<dt>$date</dt>
<dd>Date part of the current datetime in Sitecore ISO format</dd>
<dt>$time</dt>
<dd>Time part of the current datetime in Sitecore ISO format</dd>
<dt>$now</dt>
<dd>The current date in Sitecore ISO format</dd>
</dl>
<p>I remember being told during the Sitecore 5 time frame that token replacement used NVelocity. In fact, I&#8217;m sure I remember it being in the training material. Well in Sitecore 6 it doesn&#8217;t appear as if it is. The tokens look like Velocity variables, but that&#8217;s just coincidence.</p>
<p>But could I get some value from using NVelocity to process the replacements?</p>
<p>Firstly, let&#8217;s just look at adding our own token into the replacement. It&#8217;s actually quite simple. All we have to do is add a processor to the expandInitialFieldValue pipeline. So let&#8217;s go ahead and create a processor which will insert the domain for the current request (which is quite commonly the same URL used to access the public site).</p>
<pre>
<code>using Sitecore.Pipelines.ExpandInitialFieldValue;
using System.Web;

namespace CustomReplacers
{
  public class DomainReplacer : ExpandInitialFieldValueProcessor
  {
    public override void Process(ExpandInitialFieldValueArgs args)
    {
      var context = HttpContext.Current;
      if(context != null)
      {
        if (args.SourceField.Value.Contains("$domain"))
        {
          var uri = context.Request.Url;
          args.Result = args.Result.Replace("$domain", uri.Scheme +
            "://" + uri.Host);
        }
      }
    }
  }
}</code>
</pre>
<p>And add our custom processor to the expandInitialFieldValue pipeline.</p>
<pre>
<code>&lt;processor type="CustomReplacers.DomainReplacer, CustomReplacers" /&gt;</code>
</pre>
<p>Add this processor at the bottom of the pipeline below the default Sitecore processors to allow Sitecore to do it&#8217;s thing before our custom processor gets involved. As with other pipeline processors you can abort a run in a processor and the expandInitialFieldValue pipeline is no exception; note the SkipStandardValueItems processor. You don&#8217;t want your processor doing extra work it didn&#8217;t have to.</p>
<p>Inside the custom processor you&#8217;ll notice all the magic happens around the ExpandInitialFieldValueArgs parameter which is passed into the Process method. You have access to the source field through the SourceField property where you can grab the current value to process. We need to put our output into the Result property. But seeing as though our processor is not the first to run, we&#8217;ll want to process the existing Result property, not the original field value as the previous processors may have already altered the result and if we just processed the source field value again we&#8217;d lose the processed value.</p>
<p>After you&#8217;ve adding this processor in and setup a template&#8217;s standard values with the $domain token when you now create an item based on this template the token will be replaced with the current domain URL.</p>
<p>As you can see, adding your own tokens is pretty simple. But let&#8217;s explorer the idea of using NVelocity to process the fields. We&#8217;ll of course need to start with a new custom processor. This processor will use NVelocity and add the item being currently processed into the context for use.</p>
<pre>
<code>using System.IO;
using NVelocity;
using Sitecore.Pipelines.ExpandInitialFieldValue;

namespace CustomReplacers
{
  public class VelocityProcessor : ExpandInitialFieldValueProcessor
  {
    public override void Process(ExpandInitialFieldValueArgs args)
    {
      if (args.SourceField.Value.Contains("$item"))
      {
        var context = new VelocityContext();
        context.Put("item", args.TargetItem);
        NVelocity.App.Velocity.Init();
        var output = new StringWriter();
        NVelocity.App.Velocity.Evaluate(context, output,
          "VelocityProcessor", args.Result);
        args.Result = output.GetStringBuilder().ToString();
      }
    }
  }
}</code>
</pre>
<p>We&#8217;ll of course also need to add the processor to the pipeline.</p>
<pre>
<code>&lt;processor type="CustomReplacers.VelocityProcessor, CustomReplacers" /&gt;</code>
</pre>
<p>Objects you put into a velocity context are not just strings; they are real objects which you can interact with and call on their properties and methods.</p>
<p>Now we can do some pretty cool stuff using VTL (Velocity Template Language). Just add some of these into your template standard values.</p>
<dl>
<dt>The name of the item:</dt>
<dd><code>$item.Name</code></dd>
<dt>The path of the item:</dt>
<dd><code>$item.Paths.FullPath</code></dd>
<dt>The name of the item&#8217;s grandparent:</dt>
<dd><code>$item.Parent.Parent.Name</code></dd>
<dt>The ID of an ancestor whose key is &#8220;home&#8221;:</dt>
<dd><code>$item.Axes.SelectSingleItem("ancestor::*[@@key='home']").ID</code></dd>
</dl>
<p>That&#8217;s right, we can use Sitecore Query in our item creation now. This is because the Item class is a very rich class which gives access to a lot of functionality. In the above Sitecore Query example I use the Axes property of the class so I can execute a Sitecore Query using the SelectSingleItem method. I could also use the SelectItems method to return an array of items. And VTL allows me to iterate over those items.</p>
<pre>
<code>&lt;ul&gt;
#foreach($i in $item.Axes.SelectItems("
  ancestor::*[@@templatekey='sample item']"))
  &lt;li&gt;$i.Name&lt;/li&gt;
#end
&lt;/ul&gt;</code>
</pre>
<p>To learn more about VTL check out the <a title="Velocity User Guide" href="http://velocity.apache.org/engine/releases/velocity-1.6.2/user-guide.html" target="_blank">Velocity User Guide</a>. Note that VTL used by NVelocity should follow that used by Velocity (the original Java project which NVelocity is based on).</p>
<p>And I should also point out an article which I stumbled upon whilst writing this article. Looks like our man <a title="Alexey Rusakov's blog" href="http://alexeyrusakov.com/sitecoreblog" target="_blank">Alexey Rusakov</a> beat me to this idea way back in 2005. Check out his <a title="Velocity master variables replacer for Sitecore" href="http://alexeyrusakov.com/sitecoreblog/2005/10/05/Velocity+Master+Variables+Replacer.aspx" target="_blank">Velocity master variables replacer</a>.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/149/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/149/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/149/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/149/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/149/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/149/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/149/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/149/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/149/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/149/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=149&subd=adeneys&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2009/12/29/custom-tokens-and-nvelocity-for-item-creation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b4591048ba49c1111162c1db646f4147?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alistair Deneys</media:title>
		</media:content>
	</item>
		<item>
		<title>Sitecore 6.2 RSS</title>
		<link>http://adeneys.wordpress.com/2009/12/09/sitecore-6-2-rss/</link>
		<comments>http://adeneys.wordpress.com/2009/12/09/sitecore-6-2-rss/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 20:53:15 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>

		<guid isPermaLink="false">http://adeneys.wordpress.com/2009/12/09/sitecore-6-2-rss/</guid>
		<description><![CDATA[When Sitecore 6.2 was released I wrote a post about some of the new features included in the release. One of which was inbuilt RSS. I think this feature was quite underplayed on my part, so allow me to make a song and dance about it here.
The RSS capabilities of Sitecore 6.2 comes in 2 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=148&subd=adeneys&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>When Sitecore 6.2 was released I wrote a post about some of the new features included in the release. One of which was inbuilt RSS. I think this feature was quite underplayed on my part, so allow me to make a song and dance about it here.</p>
<p>The RSS capabilities of Sitecore 6.2 comes in 2 parts. The first is standard content RSS. It&#8217;s now quite easy for content authors to create RSS feeds for their content. The Shared Source RSS module always allowed us to do that but now it&#8217;s handled natively. The RSS module is also quite old and had to provide it&#8217;s own way of doing certain things that have since been added or changed in the CMS.</p>
<p>Content RSS feeds in Sitecore 6.2 are very easy to create and have been designed to allow non-developers to create and maintain them. There are 2 parts to creating a content feed. Firstly you have to define the appearance of the feed; which data fills in which RSS element. This is done using the feed designer form which sits on the presentation tab in the content editor. The feed design is saved back to the item&#8217;s template standard values so all items based on the same template will look the same. After all, you don&#8217;t want to have to go through every single item and define it&#8217;s feed presentation.</p>
<p align="center"><img alt="feed designer" src="http://adeneys.files.wordpress.com/2009/12/feed_designer.png?w=369&#038;h=426" width="369" height="426" /></p>
<p>The feed designer presents a selection of fields you can use to populate each of the RSS elements. And this would be fine for most content authors. But what if you need to create a more complex aggregation? What if you want to generate the body of the feed based on several fields, or even refer to other items as well? All the feed designer is doing is setting a presentation for the RSS device of the item&#8217;s template standard values. This is the same way in which you&#8217;d define presentation for any other kind of device. You&#8217;ll notice after you&#8217;ve designed the feed that the feed device now uses the &#8220;Feed Delivery Layout&#8221; layout and the FeedRenderer control. Being that this is standard presentation definition you could change this if you needed more flexibility in designing the feed.</p>
<p>After we&#8217;ve designed the item&#8217;s feed presentation we need to define a feed item which when requested will output the RSS. This is as simple as creating an item in the content tree which inherits from the <code>/sitecore/templates/system/feeds/rss feed</code> template. You&#8217;ll need to fill in the <code>items</code> field which points to the parent of the items you want to syndicate through the feed.</p>
<p>If we need more control over the behavior of how the feed works we can also specify a custom type in the <code>type</code> field of the feed item to override these default behaviors. This custom feed type must inherit from <code>Sitecore.Syndication.PublicFeed.</code></p>
<p>Let&#8217;s say I wanted to be able to filter based on template, so only items that are based on certain templates will be included in the feed. I would first create a new template which inherits from the <code>rss feed</code> template and add an additional field <code>Include Templates</code> of type TreeList to my new template. I could then use the following class in the type field of a feed created from that template to perform the filtering.</p>
<pre>
<code>using System.Collections.Generic;
using System.Linq;

namespace Sitecore_Custom_Feed
{
  public class CustomFeed : Sitecore.Syndication.PublicFeed
  {
    public override IEnumerable&lt;Sitecore.Data.Items.Item&gt;
      GetSourceItems()
    {
      string templateIDs = FeedItem["Include Templates"];
      var items = base.GetSourceItems();
      return items.Where(i =&gt; templateIDs.Contains(
        i.TemplateID.ToString()));
    }
  }
}</code>
</pre>
<p>Now only items which are based on any of the templates in the <code>Include Templates</code> field will be included in the feed.</p>
<p>Another handy extension to have on each page is the ability to check if an item contains a feed item as a child and provide the alternate link tags in the html head to have the browser detect the feed for this page. Firefox for example will display an RSS icon on the right-hand side of the address bar if the page contains an alternate link.</p>
<p align="center"><img alt="rss on page" src="http://adeneys.files.wordpress.com/2009/12/rss_on_page.png?w=450&#038;h=302" width="450" height="302" /></p>
<p>Some XSLT you might use to output that tag:</p>
<pre>
<code>&lt;xsl:for-each select="child::item[@template='rss feed']"&gt;
  &lt;link rel="alternate" type="application/rss+xml"
    href="{sc:path(.)}" title="RSS feed"/&gt;
&lt;/xsl:for-each&gt;</code>
</pre>
<p>Just make sure your alt link rendering is included in the head section of your HTML.</p>
<p>Content authors can also simply link to the feed item after they&#8217;ve created it in the rich text editor.</p>
<p>After publishing your changes you&#8217;ll be able to see the feed on the live website.</p>
<p align="center"><img alt="content rss feed" src="http://adeneys.files.wordpress.com/2009/12/content_rss_feed.png?w=450&#038;h=518" width="450" height="518" /></p>
<p>The second part of the new RSS capabilities in Sitecore 6.2 is Sitecore Client Feeds. Sitecore now allows you to subscribe via RSS to a workflow, workflow state or individual content item&#8217;s updates. This is really awesome cause it means content approvers no longer have to log into Sitecore each day to check their workbox. All the information they would have received from this application is available through RSS, including the ability to execute commands directly from the RSS.</p>
<p>Lars Nielsen noted in a comment on my original Sitecore 6.2 new features post that he has subscribed to workflow using Outlook. I&#8217;ve also heard other people calling this client feeds capability &#8220;Outlook integration for workflow&#8221;. This is a misnomer. Calling this feature as such is actually limiting it&#8217;s potential. RSS is more pervasive than just Outlook and Windows. With this capability I can now have native support for workflow information using any RSS program on any platform (or device <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ). I can approve articles directly from my Linux machine (Sitecore supports the content editor cross browser, so I could have already done that, but now I&#8217;m using a native application), or from my mobile phone. Anything that can support RSS.</p>
<p>I&#8217;m actually quite disappointed in the workflow RSS capability. Why you might ask? Does it lack a particular feature? Does it lack some polish? Do I not like how it works? No. None of the above. Earlier this year I achieved a very similar result using email. Actually I should say it was one of my colleagues as it was he who wrote the thing (thanks Michael!). The basic idea of the Next Digital extended workflow action was to provide an email action that can be included in workflow and provide both extended capabilities in terms of field data and provide workflow commands inside the email. This action was based on <a title="Alexey Rusakov's blog" href="http://alexeyrusakov.com/sitecoreblog/" target="_blank">Alexey Rusakov&#8217;s</a> <a title="Extended mail action for Sitecore workflow" href="http://alexeyrusakov.com/sitecoreblog/2005/09/25/Extended+Mail+Action.aspx" target="_blank">extended email action</a>. So I&#8217;m quite disappointed in the workflow RSS capability because our really cool Sitecore extension is not as unique as it once was.</p>
<p>To subscribe to a workflow feed simply log into Sitecore and open the workbox then click on any of the RSS icons in the UI. The RSS icon in the workflow title bar is of course for the entire workflow and the RSS icon in the title of each workflow state is of course just for that state.</p>
<p>Now whenever an item enters the state (for state RSS) or when it changes state (for workflow RSS) you&#8217;ll get a notification in your RSS client. You&#8217;ll get a bunch of information about the item along with the available commands you can execute against the item, taking into account your security. This means that if you don&#8217;t have the required permissions to the command, you will not see the command in the feed.</p>
<p>And just to prove it really does work outside of Outlook, here&#8217;s a few other programs and platforms.</p>
<p>Sitecore workflow RSS on an Android phone &#8211; List view.</p>
<p align="center"><img alt="sitecore workflow rss android" src="http://adeneys.files.wordpress.com/2009/12/sitecoreworkflowrssandroid.png?w=250&#038;h=497" width="250" height="497" /></p>
<p>Sitecore workflow RSS on an Android phone &#8211; Article view.</p>
<p align="center"><img alt="sitecore workflow rss android article" src="http://adeneys.files.wordpress.com/2009/12/sitecoreworkflowrssandroidarticle.png?w=250&#038;h=460" width="250" height="460" /></p>
<p>Can you imagine as a content approver being able to approve content whilst on the run straight from your mobile phone?</p>
<p>Sitecore workflow RSS in Akregator in Kubuntu (Linux).</p>
<p align="center"><img alt="Sitecore workflow RSS in Akregator" src="http://adeneys.files.wordpress.com/2009/12/sitecoreworkflowrssinakregator.png?w=450&#038;h=289" width="450" height="289" /></p>
<p>For more information on RSS feeds in Sitecore 6.2 and for full instructions on how to create them, refer to the <a title="Content Author's Reference and Cookbook" href="http://sdn.sitecore.net/upload/sitecore6/62/content_author's_cookbook_sc62_a4.pdf" target="_blank">Content Author&#8217;s Reference and Cookbook for Sitecore 6.2</a> which can be downloaded from the <a title="Sitecore Developer Network" href="http://sdn.sitecore.net" target="_blank">SDN</a>.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/148/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/148/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/148/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/148/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/148/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/148/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/148/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/148/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/148/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/148/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=148&subd=adeneys&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2009/12/09/sitecore-6-2-rss/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b4591048ba49c1111162c1db646f4147?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alistair Deneys</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/12/feed_designer.png" medium="image">
			<media:title type="html">feed designer</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/12/rss_on_page.png" medium="image">
			<media:title type="html">rss on page</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/12/content_rss_feed.png" medium="image">
			<media:title type="html">content rss feed</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/12/sitecoreworkflowrssandroid.png" medium="image">
			<media:title type="html">sitecore workflow rss android</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/12/sitecoreworkflowrssandroidarticle.png" medium="image">
			<media:title type="html">sitecore workflow rss android article</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/12/sitecoreworkflowrssinakregator.png" medium="image">
			<media:title type="html">Sitecore workflow RSS in Akregator</media:title>
		</media:content>
	</item>
		<item>
		<title>Firefox Content Editor Scrollbar Issue</title>
		<link>http://adeneys.wordpress.com/2009/12/02/firefox-content-editor-scrollbar-issue/</link>
		<comments>http://adeneys.wordpress.com/2009/12/02/firefox-content-editor-scrollbar-issue/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 10:39:42 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>

		<guid isPermaLink="false">http://adeneys.wordpress.com/2009/12/02/firefox-content-editor-scrollbar-issue/</guid>
		<description><![CDATA[It was a real shame when Sitecore removed Firefox support when they released Sitecore 5.3. In prior versions of Sitecore you still had the option to log into the desktop from the login screen when using Firefox. And even though it didn&#8217;t look quite as perfect as it did in IE, it was so much [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=141&subd=adeneys&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>It was a real shame when Sitecore removed Firefox support when they released Sitecore 5.3. In prior versions of Sitecore you still had the option to log into the desktop from the login screen when using Firefox. And even though it didn&#8217;t look quite as perfect as it did in IE, it was so much faster thanks to the faster javascript engine in Firefox.</p>
<p>But there are ways around that. Check my previous blog post on <a title="Sitecore desktop in Firefox" href="http://adeneys.wordpress.com/2008/12/23/sitecore-desktop-in-firefox-and-production-javascript-debugging/" target="_blank">how to login to the desktop using Firefox in Sitecore 6.x</a> .</p>
<p>Even though desktop support was removed you could still log into the page and content editors and edit content that way. A little while ago I had a client reporting that the scrollbars were missing in the content editor tree when they were using Firefox. This seemed quite odd, but sure enough, when I checked a Sitecore 6.0.2 site using the latest Firefox (version 3.5.5) after expanding out the content tree and clicking on an item the scrollbars disappeared. Thinking this may have been fixed in a later update I checked a 6.2 site, and the same error could be seen.</p>
<p align="center"><img alt="ff missing scrollbars" src="http://adeneys.files.wordpress.com/2009/12/ff_missing_scrollbars.png?w=450&#038;h=343" width="450" height="343" /></p>
<p>After much investigation and firebugging I finally found the issue. It lies in the /sitecore/shell/Controls/Gecko.js file. On line 495 is the following line:</p>
<pre>
<code>element.setStyle({ height: "100%" });</code>
</pre>
<p>This is the culprit. To solve the issue simply comment that line out.</p>
<p align="center"><img alt="ff scrollbar back" src="http://adeneys.files.wordpress.com/2009/12/ff_scrollbar_back.png?w=450&#038;h=346" width="450" height="346" /></p>
<p>What I believe to be happening; the content tree sits inside a table cell. When you set a style with 100% height that means the element should be 100% of the height of it&#8217;s containing element. In this case, a table row. This row also holds the fields section to the right of the content tree, which is much longer than the content tree and will push the height of the table row out. So when we set 100% height on the content tree panel, it should now be the same height as the fields section. At least that&#8217;s what I think is happening.</p>
<p>I must point out that I haven&#8217;t tested the above solution exhaustivly and this update may affect other areas of the system. I&#8217;ve also only checked the solution with the Firefox version mentioned above (3.5.5) and I suspect that this would break earlier versions on Firefox. If that were the case it wouldn&#8217;t be too difficult to update the script so instead of commenting out line 495 just detect the browser version and use that in an &#8220;if&#8221; statement.</p>
<p>I&#8217;ve already logged the issue with Sitecore support so this post is just for the interim if you really need a fix and can&#8217;t wait for another release from Sitecore. I&#8217;m also posting this to explain how I can do some of the things I do in my next post.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/141/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/141/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/141/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/141/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/141/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=141&subd=adeneys&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2009/12/02/firefox-content-editor-scrollbar-issue/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b4591048ba49c1111162c1db646f4147?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alistair Deneys</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/12/ff_missing_scrollbars.png" medium="image">
			<media:title type="html">ff missing scrollbars</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/12/ff_scrollbar_back.png" medium="image">
			<media:title type="html">ff scrollbar back</media:title>
		</media:content>
	</item>
		<item>
		<title>Extending the Control Panel</title>
		<link>http://adeneys.wordpress.com/2009/11/17/extending-the-control-panel/</link>
		<comments>http://adeneys.wordpress.com/2009/11/17/extending-the-control-panel/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 12:15:04 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>

		<guid isPermaLink="false">http://adeneys.wordpress.com/2009/11/17/extending-the-control-panel/</guid>
		<description><![CDATA[Recently I had a situation where I needed to run a lengthy process inside my Sitecore solution which needed to run some custom code. The actual process itself was to update a separate Lucene index we were using for a user search component on an intranet. I prefer to perform user search against an index [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=138&subd=adeneys&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>Recently I had a situation where I needed to run a lengthy process inside my Sitecore solution which needed to run some custom code. The actual process itself was to update a separate Lucene index we were using for a user search component on an intranet. I prefer to perform user search against an index rather than the user store itself. Primarily for performance and secondly to provide more options for the search.</p>
<p>The normal way I&#8217;ve seen a lot of this kind of thing done is someone will create a very plain looking web form (aspx) and drop it in a folder, then have the admin user hit that page directly. The problem with this approach is that the page is normally quite ugly and doesn&#8217;t feel like part of the solution. And if your process takes a while you would have to custom code the ajax calls to update your UI and provide feedback to the user.</p>
<p align="center"><img alt="ugly util page" src="http://adeneys.files.wordpress.com/2009/11/ugly_util_page-1.png?w=450&#038;h=301" width="450" height="301" /></p>
<p>Can you tell this page was designed by a developer? <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Realistically it&#8217;s a sin to burdon your users with this ugly kind of page. Especially when Sitecore is so extensible and already contains a location for these occasional utilities; the control panel.</p>
<p>It&#8217;s very easy to add your own entries into the control panel. All the categories and utilities themselves are defined under <code>/sitecore/content/Applications/Control Panel</code> in the <code>core</code> database. To add your own utility it&#8217;s as simple as adding an item under an existing category (based on the <code>/sitecore/templates/Sitecore Client/Tasks/Task page</code> template) based on the <code>/sitecore/templates/Sitecore Client/Tasks/Task option</code> template. The Header field is just the text displayed on the UI and the Click field is the Sitecore command to execute when the utility link is clicked.</p>
<p>The command is normally in the form of <code>category:command_name</code> such as <code>myproject:updateuserindex</code>. This command needs to be defined either in the <code>App_Config/Commands.config</code> file or in a configuration include file. The command definition contains both the full command name and a .net type to instantiate when the command is executed. The .net type needs to inherit from <code>Sitecore.Shell.Framework.Commands.Command</code> and override the <code>Execute</code> method.</p>
<p>If we have a short process to perform then we could perform that process from this method, then use something like the ClientResponse.Alert method to pop up a javascript alert dialog to let the user know the outcome of the process (success, failure, etc). If it&#8217;s a lengthy process you could also kick off a job here and then start a client pipeline which could make periodic requests to the server to get the status of the job and display. For my example here I&#8217;m going to launch a sheer wizard to kick off the process. Sheer UI also provides a facility to periodically update the user on the progress of the job. Another reason I chose a wizard here is because it&#8217;s what the user would expect. None of the other utilities in the control panel execute the desired process directly, they launch up either a dialog or a wizard. A wizard is also a great idea if you need to collect information from the user to execute the process.</p>
<p>To have my wizard open and display in a modal dialog, launch the dialog with the following from within the Execute method of the command.</p>
<pre>
<code>Context.ClientPage.ClientResponse.Broadcast(
  Context.ClientPage.ClientResponse.ShowModalDialog(
  "/sitecore/shell/default.aspx?xmlcontrol=RebuildUserSearchIndex"),
  "Shell");</code>
</pre>
<p>The <code>xmlcontrol</code> parameter in the url needs to refer to a sheer control. Inside our sheer layout file (XAML like file with XML extension) the control name is given as the child of the root &#8220;control&#8221; element.</p>
<pre>
<code>&lt;control xmlns:def="Definition"
  xmlns="http://schemas.sitecore.net/Visual-Studio-Intellisense"&gt;
  &lt;RebuildUserSearchIndex&gt;
  &lt;/RebuildUserSearchIndex&gt;
&lt;/control&gt;</code>
</pre>
<p>Note that because we&#8217;re not going to use this control in a presentation definition inside Sitecore, then we don&#8217;t need to register the control using the developer centre. We can just write it and as long as the XML file is in the correct location Sitecore will pick it up.</p>
<p>It&#8217;s a little funny how the sheer engine works, but it&#8217;s this element name that matters. Sheer doesn&#8217;t locate controls by filename, so it doesn&#8217;t actually matter what I call the file in which this control is defined, or even where I put it. As long as the location in which it exists is included in the controlSources element in web.config. It&#8217;s pretty safe to put your file below the <code>/sitecore/shell/controls</code> folder as this folder is required by Sitecore itself and is already included.</p>
<p>Sheer UI has built in support for wizards, so immediately inside my control name tag I can define a control of type WizardForm.</p>
<pre>
<code>&lt;WizardForm
  CodeBeside="MyProject.RebuildUserSearchIndex,MyProject"&gt;
&lt;/WizardForm&gt;</code>
</pre>
<p>Note the CodeBeside attribute in which I define the type which handles the forms behavior. Now I can fill in the pages of the wizard. A wizard form consists of a number of pages including a first page and a last page. The first page normally describes to the user what the wizard does and the last page provides a summary of the process that was executed. The first and last pages are given inside the WizardForm element with WizardFormFirstPage and WizardFormLastPage elements respectively. All the other pages will be given by WizardFormPage elements.</p>
<p>In my simple example above I will have 3 pages. The first page describing that the index will be rebuilt, a progress page to show the user the process is indeed executing, and the final page providing a summary of the operation. I&#8217;ll define my pages (and complete the rest of my XAML file) with the following which is inserted inside the WizardForm element.</p>
<pre>
<code>&lt;WizardFormFirstPage ID="FirstPage" Icon="People/32x32/User1.png"&gt;
  &lt;Border Class="scWizardWelcomeTitle"&gt;
    &lt;Literal ID="Welcome" Text="Welcome to the User Search Index Wizard."/&gt;
  &lt;/Border&gt;
  &lt;Literal Text="This wizard helps you:"/&gt;
  &lt;ul&gt;
    &lt;li class="scWizardBullet"&gt;
      &lt;Literal Text="Rebuild the user search index."/&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
  &lt;Literal Text="To begin, click the 'rebuild' button below"/&gt;
&lt;/WizardFormFirstPage&gt;

&lt;WizardFormPage ID="Rebuild" Header="Rebuilding"
  Text="This may take a few minutes." Icon="People/32x32/User1.png"&gt;
  &lt;Edit Mode="Hidden" ID="JobHandle" Width="0" Height="0"/&gt;
  &lt;GridPanel Width="100%"&gt;
    &lt;Space Height="64"/&gt;

    &lt;ThemedImage Src="People/48x48/User1.png" Width="48" Height="48"
      GridPanel.Align="center"/&gt;

    &lt;Space Height="16"/&gt;

    &lt;Border Align="center"&gt;
      &lt;ThemedImage Src="Images/progress.gif" Width="94" Height="17"/&gt;
    &lt;/Border&gt;

    &lt;Space Height="16"/&gt;

    &lt;Border Align="center" GridPanel.Align="center" GridPanel.Style="font-weight:bold"&gt;
      &lt;Literal Text="Rebuilding..."/&gt;
    &lt;/Border&gt;

    &lt;Space Height="16"/&gt;

    &lt;Border Align="center"&gt;
      &lt;Literal ID="StatusMessage"/&gt;
    &lt;/Border&gt;

  &lt;/GridPanel&gt;
&lt;/WizardFormPage&gt;

&lt;WizardFormLastPage ID="LastPage" Icon="People/32x32/User1.png"&gt;
  &lt;Border ID="SuccessMessage"&gt;
    &lt;Literal Text="The index has been rebuilt successfully."/&gt;
  &lt;/Border&gt;
  &lt;Border ID="ErrorMessage"&gt;
    &lt;Literal Text="The index rebuild failed." /&gt;
  &lt;/Border&gt;

  &lt;Border&gt;
    &lt;Literal ID="Status"/&gt;
  &lt;/Border&gt;
&lt;/WizardFormLastPage&gt;</code>
</pre>
<p>The WizardForm control provides the buttons and handling of switching pages of the wizard. You can also override the ActivePageChanged and ActivePageChanging methods to customise this behavior. By default the pages of the wizard are presented in the order in which they are defined in the XAML file. But using these method overrides you can conditionally skip certain pages. You can also cancel the transition in the ActivePageChanging method so you have opportunity to perform validation on user input.</p>
<p>If you&#8217;ve read the XAML above you&#8217;ll see that instead of having a &#8220;next&#8221; button on the welcome screen, I want to have it labelled &#8220;rebuild&#8221;. I also want to disable the navigate buttons when the index is being rebuilt. The following ActivePageChanged method will achieve this.</p>
<pre>
<code>protected override void ActivePageChanged(string page, string oldPage)
{
  base.ActivePageChanged(page, oldPage);

  NextButton.Header = "Next &gt;";

  if (page == "FirstPage")
    NextButton.Header = "Rebuild";

  if (page == "Rebuild")
  {
    BackButton.Disabled = true;
    NextButton.Disabled = true;
    StartRebuild();
  }
}</code>
</pre>
<p>Note I also kick off the rebuild process when we change to the &#8220;Rebuild&#8221; page. I&#8217;ll run the rebuild in a job which is a background thread. This way the job can run asynchronously and my request can return.</p>
<pre>
<code>private void StartRebuild()
{
  // Start job for index rebuild
  var options = new JobOptions("Rebuild User Search Index",
    "IndexRebuild", Context.Site.Name, this, "RebuildIndex");
  var job = JobManager.Start(options);
  JobHandle.Value = job.Handle.ToString();

  // Start client pipeline to check progress
  Context.ClientPage.ClientResponse.Timer("CheckStatus", 500);
}</code>
</pre>
<p>When creating a JobOptions object you can specify an object to run your process as well as the method to invoke on that object (last 2 parameters in the above call). So the rebuild will be run using this form and calling the &#8220;IndexRebuild&#8221; method on it. The Timer method call down the bottom causes the client to wait the specified time (second parameter, milliseconds) then call the method given in the first parameter. So I&#8217;ll need to define the IndexRebuild and CheckStatus methods.</p>
<p>One of the nice things about Sitecore jobs is that they provide a way to update status across threads through the job&#8217;s Status.Processed property. There are a few ways to find an existing job when the call for CheckStatus comes in but I like to use the job handle of the job returned by the JobManager. I&#8217;ll need to store the handle so I also have access to it on the call to CheckStatus. For this I&#8217;ll use a hidden field and store the handle value in that.</p>
<p>To get access to the controls of the form we have to get a little &#8220;2003 old school&#8221; and define the variables in our code file. The controls come out of the <code>Sitecore.Web.UI.HtmlControls</code> namespace, so include a reference to that namespace at the top of your file, then inside your class define the controls as protected so they can be populated on the postback.</p>
<pre>
<code>protected Edit JobHandle;
protected Literal StatusMessage;
protected Border SuccessMessage;
protected Border ErrorMessage;
protected Literal Status;</code>
</pre>
<p>I won&#8217;t actually build the index in this example, as I&#8217;m only concerned with describing how to create such an application. Instead I&#8217;ll simulate the lengthy operation so we can witness the UI updating while the background thread runs.</p>
<pre>
<code>private void RebuildIndex()
{
  // Simulate a lengthy operation so the client pipeline can execute
  Context.Job.Status.Processed = 0;
  for (int i = 0; i &lt; 20; i++)
  {
    Thread.Sleep(500);
    Context.Job.Status.Processed++;
  }
}</code>
</pre>
<p>So I update the processed count in the method above and I&#8217;ll read that status from the client pipeline server method.</p>
<pre>
<code>protected void CheckStatus()
{
  var handle = Handle.Parse(JobHandle.Value);
  if (handle != null)
  {
    var job = JobManager.GetJob(handle);
    if (job != null)
    {
      StatusMessage.Text = "Processed: " + job.Status.Processed.ToString();
    }

    if (job.IsDone)
    {
      Active = "LastPage";
      ErrorMessage.Visible = false;
      Status.Text = StatusMessage.Text;
    }
    else
      Context.ClientPage.ClientResponse.Timer("CheckStatus", 500);
  }
}</code>
</pre>
<p>This callback is also where we check on the status of the job and when complete move to the next page of the wizard by setting the &#8220;Active&#8221; property to the ID of the page you want to swap to. If the job isn&#8217;t finished we&#8217;ll tell the client to check the status in another 500 milliseconds.</p>
<p>And after you fill in the proper index creation method, you&#8217;re done! I know that may have been a little more work than the ugly util page that was whacked together above, but this wizard shows a lot of polish and enhances the user&#8217;s experience when using your solution. Not to mention the built in mechanisms for starting a background thread and having the client periodically check on the status of the running job. Once you get the hang of sheer you&#8217;ll be knocking out these wizards for those utils quicker than you can make that UX expert shake his head in dismay.</p>
<p>If you need some help with sheer, keep in mind that the XAML files are not compiled; meaning you can open up the XAML files for any of the Sitecore UI components. Especially when working with dialogs and wizards, the existing Sitecore controls are invaluable as a reference.</p>
<p>And here&#8217;s the final result in all it&#8217;s sheer glory!</p>
<p align="center"><img alt="control panel" src="http://adeneys.files.wordpress.com/2009/11/control_panel.png?w=440&#038;h=462" width="440" height="462" /></p>
<p>Control panel showing my user search index rebuild option.</p>
<p align="center"><img alt="wizard first" src="http://adeneys.files.wordpress.com/2009/11/wizard_first.png?w=450&#038;h=483" width="450" height="483" /></p>
<p>Welcome page of the wizard</p>
<p align="center"><img alt="wizard second" src="http://adeneys.files.wordpress.com/2009/11/wizard_second.png?w=450&#038;h=483" width="450" height="483" /></p>
<p>Processing page of the wizard</p>
<p align="center"><img alt="wizard last" src="http://adeneys.files.wordpress.com/2009/11/wizard_last.png?w=450&#038;h=483" width="450" height="483" /></p>
<p>Summary page of the wizard</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/138/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/138/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/138/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=138&subd=adeneys&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2009/11/17/extending-the-control-panel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b4591048ba49c1111162c1db646f4147?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alistair Deneys</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/11/ugly_util_page-1.png" medium="image">
			<media:title type="html">ugly util page</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/11/control_panel.png" medium="image">
			<media:title type="html">control panel</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/11/wizard_first.png" medium="image">
			<media:title type="html">wizard first</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/11/wizard_second.png" medium="image">
			<media:title type="html">wizard second</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/11/wizard_last.png" medium="image">
			<media:title type="html">wizard last</media:title>
		</media:content>
	</item>
		<item>
		<title>Quietest&#8230;Release&#8230;Ever</title>
		<link>http://adeneys.wordpress.com/2009/10/22/quietest-release-ever/</link>
		<comments>http://adeneys.wordpress.com/2009/10/22/quietest-release-ever/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 12:05:18 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>

		<guid isPermaLink="false">http://adeneys.wordpress.com/2009/10/22/quietest-release-ever/</guid>
		<description><![CDATA[Sitecore 6.2 was released last night in probably the quietest release Sitecore has done in a long time. Why am I saying it was a quiet release? Well I had no idea it was coming and only found out after reading John West&#8217;s blog  and finding a reference to the new version hidden in [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=132&subd=adeneys&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>Sitecore 6.2 was released last night in probably the quietest release Sitecore has done in a long time. Why am I saying it was a quiet release? Well I had no idea it was coming and only found out after reading <a title="John West's blog" href="http://sitecorejohn.spaces.live.com/Blog" target="_blank">John West&#8217;s blog </a> and finding a reference to the new version hidden in <a title="Sitecore WebDAV configuration guide announced" href="http://sitecorejohn.spaces.live.com/blog/cns!960125F1D4A59952!451.entry" target="_blank">one of his posts</a>. Normally I should get an email from Sitecore about new releases, but nothing.</p>
<p>So I&#8217;m doing my part for the publicising of Sitecore 6.2. I don&#8217;t normally post to tell you all about a release you probably already know about, but seeing as though I had no idea about 6.2 being released I&#8217;m assuming a lot of you haven&#8217;t heard yet either.</p>
<p>Anyway reading through the <a title="Sitecore 6.x release notes" href="http://sdn.sitecore.net/Products/Sitecore%20V5/Sitecore%20CMS%206/ReleaseNotes/ChangeLog.aspx" target="_blank">release notes for 6.2</a> I am filled with excitement. Some of the features I got a sneak peek at during an MVP only preview of Everest earlier this year. Let me point out a few here.</p>
<p><strong>Word field type:</strong> Sitecore 6.2 includes a brand new field type; the word field. This field uses an Active X control to allow the user to use Word 2007 to edit text fields. This means users who are familiar with word can continue to use it. One caveat of this is of course that you&#8217;ll be lumped with Word&#8217;s awful HTML generation. So if you really don&#8217;t care about compliancy, then go for it <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p><strong>WebDAV for drag and drop support of uploading media files:</strong> Sitecore 6.2 adds support for webDAV which allows users to drag media files straight from their desktop into the IE window and have those files uploaded into the media library. No more clicking around dialogs, just drag your files onto the Sitecore window.</p>
<p><strong>Zipped icon files:</strong> When copying or zipping a Sitecore install folder, what takes the most time? The icon files of course. Sitecore has included since version 5 a very comprehensive library of icon files, all in different resolutions to really provide a good looking UI. Each icon file is only small, but there are so many of them. And the number of files is what slows down those zip and copy operations. From memory a standard install of Sitecore 6.1 contained about 24,000 files. The standard install of Sitecore 6.2 contains only 7,500 files. This should really help when moving Sitecore installs around.</p>
<p><strong>Index folder default location:</strong> This is <a title="Sitecore index folder location" href="http://www.cassidy.dk/blog/sitecore/2009/02/session-state-and-integrated-pipeline.html" target="_blank">a little trick </a> I leant from <a title="Mark Cassidy's blog" href="http://www.cassidy.dk/blog/sitecore/" target="_blank">Mark Cassidy</a>. Previously in a default Sitecore install the index folder would exist below the web root. Problem was that at times when packages were being installed or publishes being run with the index updates running crazy IIS would restart the application due to too much file activity (or something like that). So to solve this issue you can add a setting named &#8220;indexFolder&#8221; which provides the location of the index folder. With the indexes outside the webroot the index updates no longer affect the stability of the IIS application. Well, Sitecore 6.2 by default has added this setting into web.config and moved the index folder below the data folder.</p>
<p>And of course there are a heap of other updates, enhancements and bug fixes. Just be careful about the breaking chances in the API (mostly to do with the analytics API, check the release notes).</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/132/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/132/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/132/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/132/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/132/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=132&subd=adeneys&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2009/10/22/quietest-release-ever/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b4591048ba49c1111162c1db646f4147?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alistair Deneys</media:title>
		</media:content>
	</item>
		<item>
		<title>Few things going on in Sitecore land?</title>
		<link>http://adeneys.wordpress.com/2009/10/16/few-things-going-on-in-sitecore-land/</link>
		<comments>http://adeneys.wordpress.com/2009/10/16/few-things-going-on-in-sitecore-land/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 09:47:28 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[Sitecore]]></category>

		<guid isPermaLink="false">http://adeneys.wordpress.com/2009/10/16/few-things-going-on-in-sitecore-land/</guid>
		<description><![CDATA[There&#8217;s a few things going on at the moment in the world of Sitecore.
Firstly the Sitecore Australian and New Zealand user group is having it&#8217;s second user group meeting, this time in Sydney Australia on 28th October 2009. Tim Ward, Solution Architect for Sitecore Australia will be taking attendees through some of the new features [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=131&subd=adeneys&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>There&#8217;s a few things going on at the moment in the world of Sitecore.</p>
<p>Firstly the Sitecore Australian and New Zealand user group is having it&#8217;s second user group meeting, this time in Sydney Australia on 28th October 2009. <a title="Tim Ward's blog" href="http://cid-ca8badb48d36b219.spaces.live.com/blog/" target="_blank">Tim Ward</a>, Solution Architect for Sitecore Australia will be taking attendees through some of the new features of Sitecore 6.1 and some of the up coming features of Sitecore 6.2. Mark Stanton from Gruden will also be speaking to the group. Everyone is welcome to attend this event, you just need to RSVP to Tim at <a href="mailto:tiw@sitecore.net">tiw@sitecore.net</a> so he can make sure he has enough beer. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  You can view the invitation online at <a href="http://img36.imageshack.us/img36/3907/usergroupinvite2.jpg">http://img36.imageshack.us/img36/3907/usergroupinvite2.jpg</a> .</p>
<p>Kind of in conjunction with the user group meeting, we&#8217;re also holding a Sitecore module competition. So if you&#8217;re in Australia or New Zealand and you have an awesome module you&#8217;d like to share with the world (and score a cool prize for it too) then make sure you get your entries in before 28th October 2009 to either Tim or myself.</p>
<p>And something that will interest more than just Sitecore devs in Australia and New Zealand, do you remember the <a title="Html Agility Pack page on CodePlex" href="http://www.codeplex.com/htmlagilitypack" target="_blank">Html Agility Pack</a>? Sitecore bundles this library and I&#8217;ve spoken previously about how to use this library to <a title="Testing with Html Agility Pack" href="http://adeneys.wordpress.com/2008/10/15/automated-testing-and-sitecore-part-5/" target="_blank">aid in testing static behavior controls</a> in Sitecore. Some of you may have looked for info on this module or found it&#8217;s CodePlex page and been turned off due to it&#8217;s lack of recent activity. Well, those days are now over.</p>
<p><a title="Jeff Klawiter's Blog" href="http://blog.j-maxx.net/" target="_blank">Jeff Klawiter</a> has picked up Html Agility Pack and started working on it again to fix bugs and add features which have been requested. So it is no longer an abandoned project. You can help Jeff out by telling him about how you use this library and if you&#8217;ve found any bugs, nuances or have feature requests. Kudos to Jeff for picking this project up. I look forward to seeing how it evolves.</p>
<p>So, just a little recap of why you should use Html Agility Pack for your testing. It allows you to easily load in HTML and treat it as XML, no matter what HTML standard it was written to. The earlier standards such as HTML 4.01 allowed you to leave off closing tags in some circumstances like on a paragraph. You can&#8217;t load HTML 4.01 into an XML document for testing as it&#8217;s not valid XML. But Html Agility Pack hides all that from you and just allows you to treat it as if it were XML.</p>
<p>But wouldn&#8217;t you want to know if your HTML was badly formed? Shouldn&#8217;t you be testing every single character of your control&#8217;s output? Well, that depends on how pedantic you want to get, and can even come down to which .net controls you may have used for your build. I would recommend against testing every single character as it doesn&#8217;t matter for (X)HTML. (X)HTML doesn&#8217;t care if you have a newline between a closing and separate opening tag, or you indented that tag too much. And how much time do you really have to spend on getting the output &#8220;character perfect&#8221;?</p>
<p>Instead I would suggest you treat any validation of control output as a separate activity in your test. You can use Html Agility Pack to test the markup as the browser would treat it and then you can test the conformity of the output to standards using something like <a title="HtmlTidy homepage" href="http://tidy.sourceforge.net/" target="_blank">HtmlTidy</a> or the <a title="W3C Html Validator" href="http://validator.w3.org/" target="_blank">W3C validator</a> .</p>
<p>And before you go jumping into vast string manipulation to verify your output, remember that it is much easier to navigate the structure of the document as XML. Especially when it comes to checking the value of an attribute on a tag. Rather than Substring and IndexOf I can just use XPath to find the attribute value.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/131/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=131&subd=adeneys&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2009/10/16/few-things-going-on-in-sitecore-land/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b4591048ba49c1111162c1db646f4147?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alistair Deneys</media:title>
		</media:content>
	</item>
		<item>
		<title>Copy and Paste Items Server to Server</title>
		<link>http://adeneys.wordpress.com/2009/09/22/copy-and-paste-items-server-to-server/</link>
		<comments>http://adeneys.wordpress.com/2009/09/22/copy-and-paste-items-server-to-server/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 12:43:03 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>

		<guid isPermaLink="false">http://adeneys.wordpress.com/2009/09/22/copy-and-paste-items-server-to-server/</guid>
		<description><![CDATA[Sitecore has done a very good job of making item management in Sitecore very much like file management in your OS. Operations such as moving items, ordering items, copying and pasting items is as simple as a drag or a click. All this works quite well, but only for the current server you&#8217;re on.
If you [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=130&subd=adeneys&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<br /><p>Sitecore has done a very good job of making item management in Sitecore very much like file management in your OS. Operations such as moving items, ordering items, copying and pasting items is as simple as a drag or a click. All this works quite well, but only for the current server you&#8217;re on.</p>
<p>If you have a look at the data on the clipboard after a copy command has run you&#8217;ll see it contains the ID of the item you wish to copy along with some meta data about the action to perform.</p>
<pre>
<code>sitecore:copy:{39F265B4-1FF0-4DA2-BCA6-A3056D5BCCFE}</code>
</pre>
<p>But often I find myself wanting to be able to copy an item from one server and paste it onto another. This normally happens when I want to pull specific content back from a QA or production server and paste it onto dev. Sitecore already provides a mechanism to do this; packages. But a package feels like a lot of effort when all I want is a single item (or tree).</p>
<p>So I got to working on a way in which to do this. My first thought was to alter the copy command to also place the URL of the server into the clipboard. Then provide a WCF service on the source server that the paste command could call to pull the data back. But after a little more consideration I worked out how to avoid the WCF service as well.</p>
<p>The <code>Item</code> class in Sitecore provides the ability to copy an item&#8217;s XML data, and create new items based on this XML through the <code>GetOuterXml(bool)</code> and <code>Paste(string, bool, PasteMode)</code> methods respectively. So if I could get the item&#8217;s entire data onto the clipboard, there would be no need for a WCF service.</p>
<p>First things first. Let&#8217;s create our custom copy command which will copy the item&#8217;s XML onto the clipboard. Our CopyItemXml command will extend <code>Sitecore.Shell.Framework.Commands.ClipboardComman</code> as we&#8217;ll be using the clipboard. We&#8217;ll also override the <code>Execute</code> and <code>QueryState</code> methods. The heavy lifting of the <code>Execute</code> method will be done in another method to allow us to run client pipelines to prompt and receive input from the user.</p>
<pre>
<code>public override CommandState QueryState(CommandContext context)
{
  if (!ClipboardCommand.IsSupported(false))
    return CommandState.Hidden;

  if (context.Items == null || context.Items.Length == 0)
    return CommandState.Disabled;

  if (!context.Items[0].Access.CanRead())
    return CommandState.Disabled;

  return base.QueryState(context);
}</code>
</pre>
<p>The <code>QueryState</code> method is called by Sitecore to determine what state to give the command in the UI such as hidden, disable or enabled.</p>
<pre>
<code>public override void Execute(CommandContext context)
{
  if (ClipboardCommand.IsSupported(true) &amp;&amp;
    context.Items != null &amp;&amp; context.Items.Length &gt;= 1)
  {
    var parameters = new NameValueCollection();
    parameters.Add("id", context.Items[0].ID.ToString());
    parameters.Add("dbname", context.Items[0].Database.Name);
    parameters.Add("initialCall", "1");
    Context.ClientPage.Start(this, "Run", parameters);
  }
}</code>
</pre>
<p>The Execute method does a few checks to ensure this command is supported by the browser (clipboard access) and then starts the client pipeline with the appropriate parameters.</p>
<pre>
<code>protected void Run(ClientPipelineArgs args)
{
  if (args.Parameters["initialCall"] == "1")
  {
    args.Parameters["initialCall"] = "0";
    Context.ClientPage.ClientResponse.YesNoCancel(
      "Do you want to copy the children as well?", "200", "100");
    args.WaitForPostBack();
  }
  else
  {
    if (args.Result == "yes" || args.Result == "no")
    {
      var includeChildren = args.Result == "yes";
      var db = Sitecore.Configuration.Factory.GetDatabase(
        args.Parameters["dbname"]);

      if (db == null)
      {
        SheerResponse.Alert("Failed to locate target database");
        return;
      }

      var item = db.GetItem(args.Parameters["id"]);
      if (item == null)
      {
        SheerResponse.Alert("Failed to locate source item");
        return;
      }

      var data = item.GetOuterXml(includeChildren);
      data = data.Replace("\\", "<a>\\\\</a>");
      data = data.Replace("\"", "<a>\\\</a>"");
      data = EscapeEscapables(data);

      SheerResponse.Eval(
        "window.clipboardData.setData(\"Text\", \"" + data + "\")");
    }
  }
}</code>
</pre>
<p>The Run method first checks to see if this is the first call to the method as a result of starting the client pipeline. If it is it sets into the response to prompt the user if they wish to also copy the children of the current item. If this is not the initial call then we grab the parameters, perform some error checking then find the source item and copy it&#8217;s XML data onto the clipboard. Note the formatting calls on the data variable towards the end of that method which will help escape the XML data to be shot back down to the browser in the response and executed in javascript. And here&#8217;s the EscapeEscapables util method which is also used.</p>
<pre>
<code>private string EscapeEscapables(string input)
{
  var builder = new StringBuilder();
  builder.Append(input);
  builder.Replace("\r", "\\r");
  builder.Replace("\t", "\\t");
  builder.Replace("\n", "\\n");
  return builder.ToString();
}</code>
</pre>
<p>Now we need to bind this command into the UI so we can execute it from the content editor. I&#8217;ll add this new command to the context menu. You could also add it to a ribbon if you liked.</p>
<p>Log into the Sitecore desktop and swap over to the core database. Next, open a content editor and navigate down to /sitecore/content/Applications/Content Editor/Context Menus/Default item. Here you can either create a new menu item definition, or copy the existing copy menu item definition. Either way the most important fields to fill in of the menu item are as follows:</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Value</th>
</tr>
</thead>
<tr>
<td>Display Name</td>
<td>Copy XML</td>
</tr>
<tr>
<td>Icon</td>
<td>Applications/16&#215;16/copy.png</td>
</tr>
<tr>
<td>Message</td>
<td>item:copyXMLtoclipboard(id=$Target)</td>
</tr>
</table>
<p>The Message field specifies a command to execute when this menu item is clicked. This command name needs to map to our custom copy class above in the App_Config/commands.config file. Open that file and scroll down until you find the existing item:copy command, then copy that line and adjust it as follows:</p>
<pre>
<code>&lt;command name="item:copyXMLtoclipboard"
  type="CustomCommands.CopyItemXML,CustomCommands" /&gt;</code>
</pre>
<p>That&#8217;s the first half done. We now have a custom command on the content editor context menu which can be used to copy an item&#8217;s XML data onto the clipboard.</p>
<p align="center"><img alt="copyitemxml" src="http://adeneys.files.wordpress.com/2009/09/copyitemxml.png?w=450&#038;h=377" width="450" height="377" /></p>
<p>Now we have the data on the clipboard we need to create the paste menu item to handle pasting the item data onto a different server. But rather than creating a brand new menu item, command and command class, why not just extend the existing paste command to be able to deal with item XML data as well?</p>
<pre>
<code>public class ExtendedItemPaste :
  Sitecore.Shell.Framework.Commands.PasteFromClipboard</code>
</pre>
<p>I know the normal paste command above is structured very similarly to the copy command we created. So I can leave the QueryState method and Execute method alone and just override the Run method which is invoked as a result of the Execute method running a client pipeline.</p>
<pre>
<code>protected new void Run(ClientPipelineArgs args)
{
  if (args.Parameters["fetched"] == "0")
  {
    args.Parameters["fetched"] = "1";
    Context.ClientPage.ClientResponse.Eval(
      "window.clipboardData.getData(\"Text\")").Attributes["response"] = "1";
    args.WaitForPostBack();
  }
  else
  {
    if (args.Result.StartsWith("&lt;item "))
    {
      var db = Sitecore.Configuration.Factory.GetDatabase(
        args.Parameters["database"]);

      if (db == null)
      {
        SheerResponse.Alert("Failed to locate target database");
        return;
      }

      var parent = db.GetItem(args.Parameters["id"]);
      if (parent == null)
      {
        SheerResponse.Alert("Failed to locate parent item");
        return;
      }

      parent.Paste(args.Result, false, PasteMode.Merge);
    }
    else
      base.Run(args);
  }
}</code>
</pre>
<p>In the paste method we need to use the <code>ClientResponse.Eval</code> method in conjunction with the <code>ClientPipelineArgs.WaitForPostBack</code> method to pull the data off the clipboard in javascript and return the result to our method. Next we check to see if the data from the clipboard is item XML or not. If it is we will handle it, otherwise let the default paste class handle it.</p>
<p>Now I have to override the existing command to use my new command class. Open the App_Config/commands.config file and find the command definition with name item:pastefromclipboard. Replace the type attribute with our ExtendedItemPaste command from above.</p>
<pre>
<code>&lt;command name="item:pastefromclipboard"
  type="CustomCommands.ExtendedItemPaste,CustomCommands" /&gt;</code>
</pre>
<p>Now when we paste, the paste command will recognise the item XML and create new items based on that. To get the most out of this you&#8217;ll want to set up another server with these custom commands so you can copy from one server and paste to the other. If you paste onto the same server you&#8217;ll notice that no new item is created. This is because of the second parameter we&#8217;re passing to the <code>Item.Paste</code> method, <code>changeIDs</code>. If this parameter were true then the IDs in the XML would be replaced with new IDs and new items would be created. By not changing the IDs the existing item will have it&#8217;s data and fields updated from the XML. I left this parameter as false as the issue I am trying to solve with this solution is to be able to copy items from one server to another. I retain the original ID incase something else references this item by ID rather than name or path.</p>
<p>But if you really wanted new IDs you could change the paste code to set changeIDs to true, or even better, prompt the user using the same technique as used in the copy command to ask if they want new items or update existing (if found).</p>
<p>So my original issue is solved right? Well&#8230;if you&#8217;ve tried this technique using 2 separate and different servers you may have noticed 1 significant issue. If the template which the item is based on does not exist on the target server then my new item will not contain any fields.</p>
<p align="center"><img alt="missing template" src="http://adeneys.files.wordpress.com/2009/09/missing_template.png?w=450&#038;h=260" width="450" height="260" /></p>
<p>So to have a full solution I should really grab the item&#8217;s template too. What about the template&#8217;s base template (and there could be multiple of those)? What about any references the item might use such as droplists or link fields to internal items? What about the presentation components used by the item (renderings, layouts, sublayouts, etc)? What about media? &#8230;</p>
<p>As you can see, once you start down the dependency paths you realise how big the graph can be. The easiest thing is to draw some definite boundries around what you will include in a copy and what you won&#8217;t. Below is a quick list of things that you might want to include and whether you easily can include them onto the clipboard as text.</p>
<table>
<thead>
<tr>
<th>Dependency</th>
<th>Easily include as text?</th>
</tr>
</thead>
<tr>
<td>Item&#8217;s template</td>
<td>Yes</td>
</tr>
<tr>
<td>Item&#8217;s template&#8217;s base templates</td>
<td>Yes</td>
</tr>
<tr>
<td>Linked items (references)</td>
<td>Yes</td>
</tr>
<tr>
<td>Linked item&#8217;s templates</td>
<td>Yes</td>
</tr>
<tr>
<td>Linked media library items</td>
<td>No</td>
</tr>
<tr>
<td>Presentation definition items</td>
<td>Yes</td>
</tr>
<tr>
<td>XSLT code</td>
<td>Yes</td>
</tr>
<tr>
<td>Markup files (aspx, ascx)</td>
<td>Yes</td>
</tr>
<tr>
<td>Code behind</td>
<td>No</td>
</tr>
</table>
<p>For my solution I&#8217;ll draw the following boundaries. I&#8217;ll copy the item (and children if required), the template hierarchies of the items and any item references. Basically just the data required to support my copied item.</p>
<p>The following shows my completed CopyItemXML command class.</p>
<pre>
<code>using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Shell.Framework.Commands;
using Sitecore.Web.UI.Sheer;

namespace CustomCommands
{
  public class CopyItemXML : ClipboardCommand
  {
    public override void Execute(CommandContext context)
    {
      if (ClipboardCommand.IsSupported(true) &amp;&amp;
        context.Items != null &amp;&amp; context.Items.Length &gt;= 1)
      {

        var parameters = new NameValueCollection();
        parameters.Add("id", context.Items[0].ID.ToString());
        parameters.Add("dbname", context.Items[0].Database.Name);
        parameters.Add("initialCall", "1");
        Context.ClientPage.Start(this, "Run", parameters);
      }
    }

    public override CommandState QueryState(CommandContext context)
    {
      if (!ClipboardCommand.IsSupported(false))
        return CommandState.Hidden;

      if (context.Items == null || context.Items.Length == 0)
        return CommandState.Disabled;

      if (!context.Items[0].Access.CanRead())
        return CommandState.Disabled;

      return base.QueryState(context);
    }

    protected void Run(ClientPipelineArgs args)
    {
      if (args.Parameters["initialCall"] == "1")
      {
        args.Parameters["initialCall"] = "0";
        Context.ClientPage.ClientResponse.YesNoCancel(
          "Do you want to copy the children as well?", "200", "100");
        args.WaitForPostBack();
      }
      else
      {
        if (args.Result == "yes" || args.Result == "no")
        {
          var includeChildren = args.Result == "yes";
          var db = Sitecore.Configuration.Factory.GetDatabase(
            args.Parameters["dbname"]);
          if (db == null)
          {
            SheerResponse.Alert("Failed to locate target database");
            return;
          }

          var item = db.GetItem(args.Parameters["id"]);
          if (item == null)
          {
            SheerResponse.Alert("Failed to locate source item");
            return;
          }

          var items = new List&lt;Item&gt;();
          var templates = new List&lt;Item&gt;();
          AddItems(item, includeChildren, true, items, templates);

          var data = GetXMLData(items, templates, item);
          data = data.Replace("\\", "<a>\\\\</a>");
          data = data.Replace("\"", "<a>\\\</a>"");
          data = EscapeEscapables(data);

          SheerResponse.Eval(
            "window.clipboardData.setData(\"Text\", \"" + data + "\")");
        }
      }
    }

    private void AddItems(Item item, bool includeChildren,
      bool includeReferences, List&lt;Item&gt; items, List&lt;Item&gt; templates)
    {
      // Add the item itself
      if (!ListContainsItem(items, item))
        items.Add(item);

      // Add any children (if required)
      if (includeChildren)
      {
        var children = item.GetChildren();
        for (int i = 0; i &lt; children.Count; i++)
        {
          AddItems(children[i], includeChildren, false,
            items, templates);
        }
      }

      // Add references
      var links = item.Links.GetValidLinks();
      for (int i = 0; i &lt; links.Length; i++)
      {
        var linkItem = links[i].SourceItemID == item.ID ?
          links[i].GetTargetItem() : links[i].GetSourceItem();

        var path = linkItem.Paths.FullPath.ToLower();
        if (!ListContainsItem(items, linkItem) &amp;&amp; (
          path.StartsWith("/sitecore/content") ||
          path.StartsWith("/sitecore/templates")))
        {
          if (path.StartsWith("/sitecore/templates"))
            AddTemplateHeirarchy(linkItem, templates);
          else
            items.Add(linkItem);
        }
      }
    }

    private void AddTemplateHeirarchy(Item template, List&lt;Item&gt; items)
    {
      items.Add(template);
      items.AddRange(template.Axes.GetDescendants());
      var templateItem = (TemplateItem)template;
      for (int i = 0; i &lt; templateItem.BaseTemplates.Length; i++)
        {
          if (templateItem.BaseTemplates[i].ID !=
            Sitecore.TemplateIDs.StandardTemplate &amp;&amp;
            !ListContainsItem(items, templateItem.BaseTemplates[i]))
            AddTemplateHeirarchy(templateItem.BaseTemplates[i], items);
        }
      }

    private bool ListContainsItem(List&lt;Item&gt; items,
      Item itemToFind)
    {
      return items.Exists(item =&gt; item.ID == itemToFind.ID);
    }

    private string GetXMLData(List&lt;Item&gt; items,
      List&lt;Item&gt; templates, Item rootItem)
    {
      var builder = new StringBuilder();
      builder.Append("&lt;itemData&gt;");
      builder.Append("&lt;items&gt;");

      for (int i = 0; i &lt; items.Count; i++)
      {
        builder.Append("&lt;itemData&gt;");
        builder.Append("&lt;path&gt;");
        if (items[i].ID != rootItem.ID &amp;&amp;
          !items[i].Axes.IsDescendantOf(rootItem))
          builder.Append(items[i].Paths.FullPath);

        builder.Append("&lt;/path&gt;");
        builder.Append(items[i].GetOuterXml(false));
        builder.Append("&lt;/itemData&gt;");
      }

      builder.Append("&lt;/items&gt;");
      builder.Append("&lt;templates&gt;");

      for (int i = 0; i &lt; templates.Count; i++)
      {
        builder.Append("&lt;itemData&gt;");
        builder.Append("&lt;path&gt;");
        builder.Append(templates[i].Paths.FullPath);
        builder.Append("&lt;/path&gt;");
        builder.Append(templates[i].GetOuterXml(false));
        builder.Append("&lt;/itemData&gt;");
      }

      builder.Append("&lt;/templates&gt;");
      builder.Append("&lt;/itemData&gt;");
      return builder.ToString();
    }

    private string EscapeEscapables(string input)
    {
      var builder = new StringBuilder();
      builder.Append(input);

      builder.Replace("\r", "\\r");
      builder.Replace("\t", "\\t");
      builder.Replace("\n", "\\n");
      return builder.ToString();
    }
  }
}</code>
</pre>
<p>You&#8217;ll see from above that I recursively (if required) collect the selected item and it&#8217;s descendants then on each item in the AddItems method I add any references as found in the links property of the item. For a good introduction to using the links database have a look at Mark Cassidy&#8217;s post <a title="Related Articles from the LinkDatabase" href="http://www.cassidy.dk/blog/sitecore/2009/05/listing-related-articles-with-sitecore.html" target="_blank">Listing Related Articles with Sitecore using the LinkDatabase</a>. Note how I&#8217;m only adding links under the content and templates sections of the content tree. The AddTemplateHeirarchy method adds the template hierarchy of the given item. When I construct the XML data I need to add the original path of any items not under the direct item being copied. Things like the templates and the references items need to be place in an appropriate location. I&#8217;ll use the path element in the paste command.</p>
<p>The following paste command is used to create items from this extended XML data block.</p>
<pre>
<code>using System;
using System.Xml;
using Sitecore;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Web.UI.Sheer;

namespace CustomCommands
{
  public class ExtendedItemPaste :
    Sitecore.Shell.Framework.Commands.PasteFromClipboard
  {
    protected new void Run(ClientPipelineArgs args)
    {
      if (args.Parameters["fetched"] == "0")
      {
        args.Parameters["fetched"] = "1";
        Context.ClientPage.ClientResponse.Eval(
"window.clipboardData.getData(\"Text\")").Attributes["response"] = "1";
        args.WaitForPostBack();
      }
      else
      {
        if (args.Result.StartsWith("&lt;itemData&gt;"))
        {
          var db = Sitecore.Configuration.Factory.GetDatabase(
            args.Parameters["database"]);
          if (db == null)
          {
            SheerResponse.Alert("Failed to locate target database");
            return;
          }

          var parent = db.GetItem(args.Parameters["id"]);
          if (parent == null)
          {
            SheerResponse.Alert("Failed to locate parent item");
            return;
          }

          var doc = new XmlDocument();
          doc.LoadXml(args.Result);
          CreateTemplates(doc, db);
          CreateItems(doc, parent);
        }
        else
          base.Run(args);
      }
    }

    private void CreateTemplates(XmlDocument doc, Database database)
    {
      var templateNodes = doc.SelectNodes(
        "/itemData/templates/itemData");
      for (int i = 0; i &lt; templateNodes.Count; i++)
      {
        var pathNode = templateNodes[i].SelectSingleNode("path");
        if (pathNode != null)
        {
          var path = pathNode.InnerText;
          var parent = GetParent(path, database);
          var itemNode = templateNodes[i].SelectSingleNode("item");

          if (itemNode != null)
            parent.Paste(itemNode.OuterXml, false, PasteMode.Merge);
        }
      }
    }

    private void CreateItems(XmlDocument doc, Item parent)
    {
      var itemNodes = doc.SelectNodes("/itemData/items/itemData");
      for (int i = 0; i &lt; itemNodes.Count; i++)
      {
        var pathNode = itemNodes[i].SelectSingleNode("path");
        if (pathNode != null)
        {
          var path = pathNode.InnerText;
          var target = parent;
          var itemNode = itemNodes[i].SelectSingleNode("item");

          if (path != string.Empty)
            target = GetParent(path, parent.Database);
          else
          {
            if (itemNode != null)
            {
              var itemParent = parent.Database.GetItem(
                itemNode.Attributes["parentid"].Value);
              if (itemParent != null)
                target = itemParent;
            }
          }

          if (itemNode != null)
            target.Paste(itemNode.OuterXml, false, PasteMode.Merge);
        }
      }
    }

    private Item GetParent(string itemPath, Database database)
    {
      var parts = itemPath.Split(new string[]{"/"},
        StringSplitOptions.RemoveEmptyEntries);
      Item item = null;
      for (int i = 0; i &lt; parts.Length - 1; i++) // Don't include last item
      {
        if (item == null)
          item = database.GetRootItem();
        else
        {
          var next = item.Axes.GetChild(parts[i]);
          if (next != null)
            item = next;
          else
            item = item.Add(parts[i],
              new TemplateID(Sitecore.TemplateIDs.Folder));
        }
      }

      return item;
    }
  }
}</code>
</pre>
<p>In the Run method I load up the XML as an XML document which allows me to select the appropriate items out of the document for each operation. I also create the templates through the CreateTemplates method before I create the items which use the templates in the CreateItems method.</p>
<p>And there we have a slightly more robust solution.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/130/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/130/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/130/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&blog=3885947&post=130&subd=adeneys&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2009/09/22/copy-and-paste-items-server-to-server/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b4591048ba49c1111162c1db646f4147?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Alistair Deneys</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/09/copyitemxml.png" medium="image">
			<media:title type="html">copyitemxml</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2009/09/missing_template.png" medium="image">
			<media:title type="html">missing template</media:title>
		</media:content>
	</item>
	</channel>
</rss>