<?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>Thu, 19 Jan 2012 11:45:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='adeneys.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.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 =&#62; Coder =&#62; Code" />
	<atom:link rel='hub' href='http://adeneys.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Filtering ECM Dispatcher</title>
		<link>http://adeneys.wordpress.com/2012/01/19/filtering-ecm-dispatcher/</link>
		<comments>http://adeneys.wordpress.com/2012/01/19/filtering-ecm-dispatcher/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 11:45:25 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>

		<guid isPermaLink="false">https://adeneys.wordpress.com/?p=312</guid>
		<description><![CDATA[The Email Campaign Manager (ECM) for Sitecore is a great tool for sending bulk email and newsletters to your users and subscribers. I had an interesting question from a client recently about the Email Campaign Manager. “How can I send an email to a subset of the subscribers?” I’ll give you a scenario to describe [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=312&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The Email Campaign Manager (ECM) for Sitecore is a great tool for sending bulk email and newsletters to your users and subscribers. I had an interesting question from a client recently about the Email Campaign Manager.</p>
<p>“How can I send an email to a subset of the subscribers?”</p>
<p>I’ll give you a scenario to describe the request. Let’s say I have a user base of national partners, but I only want to send a newsletter to a subset of them such as only those in Victoria.</p>
<p>When an ECM mail is sent it is sent to an entire target audience which includes all users within a role. There are no options for limiting the subscribers in the target audience to which the mail is sent, other than a random selection to test the mail.</p>
<p>Using out-of-the-box tools the only way to meet my scenario above would be:</p>
<ol>
<li>Create a new target audience for my Victorian partners </li>
<li>Export all my users to a CSV file using the ECM export users tool </li>
<li>Filter the users using Excel </li>
<li>Upload the altered file back into ECM using the user import tool, adding the users to the new target audience </li>
<li>Send the mail to the new target audience. </li>
</ol>
<p>If this was just a temporary one-time email I would then need to delete the target audience and associated roles. This sounds like a lot of work to filter a subset of the users.</p>
<p>OK, so what if instead of originally uploading a single file of all my partners and adding them to a single partners target audience (and hence role) I could upload my partners by state, then create a new role which contains all the state partner roles…still sounds kind of clunky…especially if I want to segment my users more dynamically.</p>
<p>So I got to digging into ECM to work out how I could filter the users based on their custom properties. I needed to be able to assess each user as the mail was generated then abort the send if the user’s properties didn’t match the criteria for the newsletter. Luckily for me ECM uses a pipeline to process each individual email as it’s sent, so it was just a matter of tapping into the <code>SendEmail</code> pipeline to do the filtering.</p>
<p>OK, let’s put it all together.</p>
<p>First thing is it extend the user profile to accommodate any custom properties I want to filter on. Although the user object can accept any custom properties assigned through code, to have Sitecore update the UI to allow viewing and updating those properties we need to update the profile.</p>
<p>In the Sitecore desktop use the database changer to change to the <code>core</code> database, then open the content editor and navigate down to the template for the user profile being used for your subscribers. Sitecore uses the items under the <code>/sitecore/system/Settings/Security/Profiles</code> path in the core database for the custom properties shown for a user profile. By default ECM will use the <code>Subscriber</code> item in this folder, so navigate to the template this item is based on. To this template we’ll add an additional field called <code>tags</code> which we’ll use to store any kind of segmenting data for the user such as state or campaign participation.</p>
<p><img style="background-image:none;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;margin-right:auto;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://adeneys.files.wordpress.com/2012/01/image.png?w=554&#038;h=475" width="554" height="475" /></p>
<p>Next we’ll need to ensure the users in Sitecore have the required data in the tags custom property. Now that the profile has been updated the user tools such as the user editor and the ECM import tool will show the field. Luckily the ECM user import tool will match users in the file with existing users on the user’s email, so this tool can be used to update the existing users in the system.</p>
<p>Once the users have been updated we need to update the newsletter template to allow entering tags against it to filter users on. I decided to put these tags on the newsletter template rather than updating the send email dialogs to make sure that if an already dispatched newsletter is duplicated back to the drafts folder to be reused, it doesn’t accidentally get sent to the wrong users.</p>
<p>Jump back into the master database and locate the ECM newsletter template at <code>/sitecore/templates/Email Campaign/Messages/Pre-existing Page</code>. Add to this template a field called <code>User Tags</code> which will hold a comma separated list of tags a user may contain in their <code>tags</code> custom property to have the email sent to them.</p>
<p><img style="background-image:none;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;margin-right:auto;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://adeneys.files.wordpress.com/2012/01/image1.png?w=554&#038;h=419" width="554" height="419" /></p>
<p>Now when we create a newsletter we can switch to the content tab of the newsletter to see the fields directly, then enter a list of tags the user may contain in their custom profile.</p>
<p><img style="background-image:none;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;margin-right:auto;padding-top:0;border-width:0;" title="image" border="0" alt="image" src="http://adeneys.files.wordpress.com/2012/01/image2.png?w=554&#038;h=419" width="554" height="419" /></p>
<p>Now, onto the code!</p>
<p>We need to create a pipeline processor for the <code>SendMail</code> pipeline which will do the filtering of the users. The below class is one example of a processor which will do this. I’ve implemented this processor to “OR” the tags on the newsletter so the above newsletter would get sent to all my users that have the tag “victoria” OR “new south wales” OR “queensland” in their list of tags.</p>
<pre><code>using System;
using System.Linq;
using Sitecore.Modules.EmailCampaign;
using Sitecore.Modules.EmailCampaign.Core.Pipelines;

namespace FilteringDispatch
{
  public class FilterSubscribers
  {
    public void Process(SendMessageArgs args)
    {
      var message = args.ECMMessage as MessageItem;
      if (message != null)
      {
        if (!string.IsNullOrEmpty(message.InnerItem[&quot;user tags&quot;]))
        {
          var messageTags = message.InnerItem[&quot;user tags&quot;].Split(
            new char[]{','},
            StringSplitOptions.RemoveEmptyEntries);

          var userTags =
            message.PersonalizationContact.Profile.GetCustomProperty(&quot;tags&quot;).Split(
            new char[]{','},
            StringSplitOptions.RemoveEmptyEntries);

          var sendToUser = false;
          foreach(var messageTag in messageTags)
          {
            if (userTags.Contains(messageTag))
            {
              sendToUser = true;
              break;
            }
          }

          if(!sendToUser)
            args.AbortPipeline();
        }
      }
    }
  }
}</code></pre>
<p>The above code first extracts the <code>MessageItem</code> the newsletter is being sent for which is the newsletter item itself that contains the <code>user tags</code> field. First the newsletter is checked to see if any tags have been defined. If no tags were defined, then exit the processor. Next the tags from the newsletter are extracted, then the tags from the user’s custom property are extracted. The tags from the newsletter are iterated and the user tags are checked to see if any match. At the end of the processor we check to see if the user had an appropriate tag and if not the pipeline is aborted. The effect of aborting the pipeline is that any remaining processors of the pipeline don’t run.</p>
<p>This processor needs to be inserted into the <code>SendMail</code> pipeline as the first processor so if it’s aborted the send processor isn’t processed. This can be done by using the following configuration patch file.</p>
<pre><code>&lt;configuration xmlns:patch=&quot;http://www.sitecore.net/xmlconfig/&quot;&gt;
  &lt;sitecore&gt;
    &lt;pipelines&gt;
      &lt;SendEmail&gt;
        &lt;processor patch:before=&quot;processor[1]&quot;
          type=&quot;FilteringDispatch.FilterSubscribers,FilteringDispatch&quot; /&gt;
      &lt;/SendEmail&gt;
    &lt;/pipelines&gt;
  &lt;/sitecore&gt;
&lt;/configuration&gt;</code></pre>
<p>And that’s it!</p>
<p>Now when ECM sends an email the above processor will check each user to ensure they have an appropriate tag before sending them the email.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adeneys.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adeneys.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adeneys.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adeneys.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/312/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/312/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/312/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=312&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2012/01/19/filtering-ecm-dispatcher/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/2012/01/image.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2012/01/image1.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2012/01/image2.png" medium="image">
			<media:title type="html">image</media:title>
		</media:content>
	</item>
		<item>
		<title>WeBlog 2.1 Released</title>
		<link>http://adeneys.wordpress.com/2012/01/10/weblog-2-1-released/</link>
		<comments>http://adeneys.wordpress.com/2012/01/10/weblog-2-1-released/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 12:36:58 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>
		<category><![CDATA[WeBlog / EviBlog]]></category>

		<guid isPermaLink="false">https://adeneys.wordpress.com/?p=306</guid>
		<description><![CDATA[Today I have made several updates to the WeBlog module for Sitecore and published release 2.1. Go grab it now from http://trac.sitecore.net/WeBlog. Here’s a few significant changes to the module. Akismet Does your WeBlog blog get swamped with spam? Are you wasting lots of manual effort on weeding it out? Then you’ll love this new [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=306&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Today I have made several updates to the WeBlog module for Sitecore and published release 2.1. Go grab it now from <a title="http://trac.sitecore.net/WeBlog" href="http://trac.sitecore.net/WeBlog">http://trac.sitecore.net/WeBlog</a>.</p>
<p>Here’s a few significant changes to the module.</p>
<h4>Akismet</h4>
<p>Does your WeBlog blog get swamped with spam? Are you wasting lots of manual effort on weeding it out? Then you’ll love this new feature. WeBlog 2.1 introduces Akismet support. Akismet is a commercial service to detect spam from web comments. If the Akismet service identifies the submitted comment as spam the comment is put into the new <code>spam</code> state of the <code>WeBlog</code> workflow. Users can use the workbox to easily review all spam comments and remove them.</p>
<h4>Customise the Comment Creation Process</h4>
<p>To make it easier to customise the comment creation process a new pipeline has been added. The <code>weblogCreateComment</code> pipeline is run when the comment is submitted. This pipeline creates the comment item, checks if the comment is spam against Akismet and then pushes it through workflow. A developer can easily update the pipeline to adjust how comments are created and processed.</p>
<h4>Override the Manager Classes</h4>
<p>The manager classes which are responsible for most of the data and content operations in the module have all be extracted behind interfaces which allows developers to override the class. A factory class is used to create concrete instances of the managers from configuration when required. This would allow a developer to, for example, store and retrieve comments from an external DB (future blog post on that in the works).</p>
<h4>Set Publish Date Using Live Writer</h4>
<p>You can now also set the publish date of your post when using the MetaWeblog API service such as when you use Live Writer.</p>
<h4>Conclusion</h4>
<p>The WeBlog wiki has also been updated with information about the new features, so you can refer to that for more information. If you have any comments or suggestions for the module, jump onto the WeBlog forum on the SDN and let us know.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adeneys.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adeneys.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adeneys.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adeneys.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/306/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/306/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/306/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=306&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2012/01/10/weblog-2-1-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>Automated Testing in Sitecore Without an HttpContext</title>
		<link>http://adeneys.wordpress.com/2011/12/23/automated-testing-in-sitecore-without-an-httpcontext/</link>
		<comments>http://adeneys.wordpress.com/2011/12/23/automated-testing-in-sitecore-without-an-httpcontext/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 12:02:05 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">https://adeneys.wordpress.com/?p=304</guid>
		<description><![CDATA[This year was the first year that Sitecore’s Dreamcore conference was held in Australia. And I for one jumped at the opportunity to speak at it. One topic that quite interests me is unit testing, and if you’ve read my posts over the years you’d see I have come up with a variety of techniques [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=304&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This year was the first year that Sitecore’s Dreamcore conference was held in Australia. And I for one jumped at the opportunity to speak at it. One topic that quite interests me is unit testing, and if you’ve read my posts over the years you’d see I have come up with a variety of techniques for getting unit testing (or rather, integration testing) working for Sitecore projects. So what better topic to talk about at Dreamcore than automated testing techniques?</p>
<p>My session at Dreamcore covered a wide range of techniques and so I didn’t have time to go in depth with any single technique such as this one. In fact, I only had 40 minutes to speak and my rehearsal the night before I came in at 1 hour. So I’ll take this opportunity to explain the technique in depth.</p>
<p>Many years ago I tried to run my automated tests for my Sitecore project’s inside the NUnit GUI test runner…and failed. The issue with the standalone test runner is that there is no HttpContext, and as I’m sure you’re well aware, Sitecore requires one of these to work. When I ran into this hurdle all those years ago, I instead developed different techniques to get around this limitation.</p>
<p>Anyway, back to this year. A few months before Dreamcore I was thinking I had to have another look into getting my automated tests for Sitecore running without the HttpContext. And then <a href="http://blog.experimentsincode.com/" target="_blank">Mike Edwards</a> beat me to the punchline and posted a blog entry on how he got <a href="http://blog.experimentsincode.com/index.php/2010/08/30/232" target="_blank">unit testing for Sitecore working in the NUnit GUI</a>. Mike’s post proved to me that it was possible, so I followed his post and got some tests running inside the NUnit GUI test runner, calling into the Sitecore 6.5 API.</p>
<p>With Mike’s general direction in place I set about fully integrating this approach to testing into a project I was working on at the time, which would provide a bit more context for me when I was writing my Dreamcore presentation.</p>
<p>The main change I made to Mike’s approach was to copy the configuration over from an existing Sitecore project. This way if any of the Sitecore configuration changed my test project would also see that change and the code under test would be run in an environment as close as possible to production.</p>
<p>First thing’s first, create a new class library project to write the tests in and add references to the <code>nunit.framework</code> assembly. As we’ll be calling into the Sitecore API (the whole point of this exercise) we’ll also need to add a reference to the <code>Sitecore.Kernel</code> assembly from the Sitecore instance the tests will be written against. To make sure we’ve got the configuration right to use the Sitecore API we’ll also create a simple test which uses the Sitecore API. The simplest thing I can think of would be grabbing a field from the home item. The following code shows how to implement this test.</p>
<pre><code>[TestFixture]
public class ApiTest
{
  [Test]
  public void AccessFieldOnHome()
  {
    var db = Sitecore.Configuration.Factory.GetDatabase(&quot;web&quot;);
    var home = db.GetItem(&quot;/sitecore/content/home&quot;);
    var fieldValue = home[&quot;title&quot;];
    Assert.AreEqual(&quot;Sitecore&quot;, fieldValue);
  }
}</code></pre>
<p>The above code will also require a reference to <code>System.Configuration</code> due to the call to the <code>Sitecore.Configuration</code> namespace.</p>
<p>Note above how we need to retrieve the database and cannot use the Sitecore context to get the context database because the context hasn’t been populated. The Sitecore context is populated through the <code>httpRequestBegin</code> pipeline which isn’t run when we’re calling the API outside an HttpContext.</p>
<p>If we were to run the above test we would end up with that familiar “Failure: System.InvalidOperationException : Could not read Sitecore configuration.” error. Have you ever noticed how so many people lack the ability to read and interpret error messages? The above error message gives a clear description of the issue…there is no Sitecore configuration.</p>
<p>So onto the biggest hurdle, copying the Sitecore configuration over from the Sitecore project which these tests will exercise. I want to automate this process and make it part of the project build process so I get any configuration updates in the test project. This will require some MSBuild additions.</p>
<p>To edit the test project’s MSBuild unload the project in Visual Studio then right click the project and select “Edit TestProject.csproj”. Alternatively you could directly edit the project file (csproj) using a separate text editor and Visual Studio will prompt you to reload the project file when you go back into Visual Studio. However the benefit of editing the project file inside Visual Studio is that Visual Studio will provide IntelliSense as you edit the file.</p>
<p>To make maintenance easier we’ll store the path to the Sitecore instance we’ll be using the configuration from in a variable. While editing the project file add the following script to the first <code>PropertyGroup</code> element which doesn’t have any additional attributes.</p>
<pre><code>&lt;SitecorePath&gt;C:\inetpub\WeBlog-65\Website&lt;/SitecorePath&gt;</code></pre>
<p>Make sure you update the path in the variable to reference the local path on your machine. The above script defines a variable called <code>SitecorePath</code> and sets it to the path provided. This variable can then be used throughout the rest of the script.</p>
<p>Now Find the <code>AfterBuild</code> target which will be commented out. This target will be called by Visual Studio if the build was successful. This is where we’ll put our additional MSBuild configuration. Uncomment the AfterBuild target and add the following script to it.</p>
<pre><code>&lt;Copy SourceFiles=&quot;$(SitecorePath)\web.config&quot;  DestinationFiles=&quot;$(OutputPath)\$(AssemblyName).dll.config&quot; /&gt;</code></pre>
<p>The above MSBuild script will copy the <code>web.config</code> of the referenced Sitecore instance to the configuration file of the test assembly. Remember for Windows assemblies the configuration file is not named <code>web.config</code> but is instead the same name as the assembly with an additional <code>.config</code> at the end. So to provide configuration for my program <code>MyApp.exe</code> the configuration file must be named <code>MyApp.exe.config</code>. The same works for the test assemblies.</p>
<p>Sitecore configuration is actually spread over a number of additional files, so the next piece of script will grab those files and copy them over to the appropriate location as well.</p>
<pre><code>&lt;CreateItem Include=&quot;$(SitecorePath)\App_Config\**\*.*&quot;&gt;
  &lt;Output ItemName=&quot;configFiles&quot; TaskParameter=&quot;Include&quot; /&gt;
&lt;/CreateItem&gt;

&lt;!-- Copy relative external source files --&gt;
&lt;Copy SourceFiles=&quot;@(configFiles)&quot;  DestinationFolder=&quot;$(OutputPath)\App_Config\%(RecursiveDir)&quot; /&gt;</code></pre>
<p>Note how in the <code>DestinationFolder</code> attribute I’m using the <code>RecursiveDir</code> well-known metadata about the input files. This will create the same directory structure as the source files are in instead of dumping them out to a flat directory.</p>
<p>To make sure we have all the assemblies we might require we will also need to copy all the assemblies in the Sitecore bin folder to the same location as the test assembly.</p>
<pre><code>&lt;CreateItem Include=&quot;$(SitecorePath)\bin\*.dll&quot;&gt;
  &lt;Output ItemName=&quot;binaryFiles&quot; TaskParameter=&quot;Include&quot; /&gt;
&lt;/CreateItem&gt;

&lt;Copy SourceFiles=&quot;@(binaryFiles)&quot; DestinationFolder=&quot;$(OutputPath)&quot; /&gt;</code></pre>
<p>And now, the test will work!</p>
<p>Though we’re missing one important piece of configuration…configuration include files. Configuration includes files are located in the <code>\App_Config\Include</code> folder of a Sitecore instance and allow patching the Sitecore configuration. This makes it much easier to keep your project configuration separate from the Sitecore configuration. It also makes upgrading Sitecore much easier as you can simply take the entire updated <code>web.config</code> file (Sitecore section) without worry that you’re reverting some update made for your project.</p>
<p>There are 2 options for handling the configuration include files. Firstly, don’t use them. For a test project you could just make sure all the configuration required is contained in the single web.config file. But that’s going against what I’ve been talking about in terms of separating project configuration from Sitecore configuration and using a real project’s configuration to ensure the tests are run in a realistically configured environment.</p>
<p>The other option is to put the include files where they’re required to allow the configuration patching utility to find them. The script above is already taking care of copying the include files to the output folder, so what else needs to be done?</p>
<p>The configuration patch utility used by Sitecore internally contains a call to the <code>Server.MapPath()</code> method. When there is no HttpContext this method will simply pass back the path as it was passed in. Sitecore is trying to locate the folder relative to the web application root, so what’s passed to the method is <code>/App_Config/Include</code>. When trying to locate this path on a disk the leading slash will cause the OS to look from the root of the disk, so the path being located is actually <code>c:\App_Config\include</code>. To make the configuration include files work we’ll need to copy the files to a folder off the root of the disk named <code>App_Config</code>.</p>
<pre><code>&lt;Copy SourceFiles=&quot;@(configFiles)&quot;  DestinationFolder=&quot;c:\App_Config\%(RecursiveDir)&quot; /&gt;</code></pre>
<p>Now the configuration patch utility will work.</p>
<p>Some points of caution when using this technique. Some components won’t be in the correct state when you try and use them because none of the request process has been run. No ASP.NET events and no Sitecore pipelines have been run. This is why the Sitecore context is not populated. But I’ve also found some other classes such as <code>Sitecore.Globals</code> aren’t initialised. If your test uses any of the global objects (Links DB, Tasks DB) you’ll need to manually initialise them with a call to <code>Sitecore.Globals.Load();</code> before using them. I’ve recently spoken to one of the <a href="http://sitecoreug.org/" target="_blank">Sitecore Users Virtual Group</a> users who has been using this technique who had issues calling <code>Delete()</code> on an item, because of the uninitialised Tasks database.</p>
<p>Another method I’ve found which simply won’t work is the <code>WebControl.RenderAsText()</code> method. This method relies on there being an HttpContext and simply won’t work without one.</p>
<p>The above points of caution are just a few I’ve found whilst using this technique. That’s not to say there aren’t a heap of other classes which need initialising before use that I haven’t run into yet.</p>
<p>This technique is also quite heavy. The Sitecore application is actually running. A real Sitecore database it accessed. Many of the objects defined in the configuration are created and strung together. Although anecdotally comparing the speed of the test runs using this technique to my normal technique of using an embedded test runner, this technique does seem faster.</p>
<p>If you’d like a working example of this technique you can refer to <a href="http://adeneys.wordpress.com/2011/10/06/dreamcore-au-2011/" target="_blank">my materials from Dreamcore Australia 2011</a>. I was lucky enough to recently deliver the same presentation to the Sitecore Users Virtual Group, so if you’d like to see me put those pieces together then you can refer to the <a href="http://www.youtube.com/watch?v=oQ2CPvN9FAU" target="_blank">recording of my Testing Strategies for Sitecore</a> presentation on <a href="http://www.youtube.com/user/hedgehogdevelopment" target="_blank">Hedgehog’s YouTube channel</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adeneys.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adeneys.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adeneys.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adeneys.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/304/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=304&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2011/12/23/automated-testing-in-sitecore-without-an-httpcontext/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>Presenting to the Sitecore Users Virtual Group</title>
		<link>http://adeneys.wordpress.com/2011/11/15/presenting-to-the-sitecore-users-virtual-group/</link>
		<comments>http://adeneys.wordpress.com/2011/11/15/presenting-to-the-sitecore-users-virtual-group/#comments</comments>
		<pubDate>Mon, 14 Nov 2011 21:45:06 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>

		<guid isPermaLink="false">https://adeneys.wordpress.com/2011/11/15/presenting-to-the-sitecore-users-virtual-group/</guid>
		<description><![CDATA[This Thursday (well, it will be Thursday for me, Wednesday if you’re on the other side of the date line) I’ll be presenting to the Sitecore Users Virtual Group on testing strategies for Sitecore. This is the same talk I gave at Dreamcore this year, so if you missed out, here’s another opportunity to see [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=302&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This Thursday (well, it will be Thursday for me, Wednesday if you’re on the other side of the date line) I’ll be presenting to the Sitecore Users Virtual Group on testing strategies for Sitecore. This is the same talk I gave at Dreamcore this year, so if you missed out, here’s another opportunity to see me talk about some testing techniques.</p>
<p>Details can be found here: <a title="http://www.sitecoreug.org/events/Testing%20Strategies%20for%20Sitecore" href="http://www.sitecoreug.org/events/Testing%20Strategies%20for%20Sitecore">http://www.sitecoreug.org/events/Testing%20Strategies%20for%20Sitecore</a>. Make sure you check the time. It will be 7am Thursday 17 November here in Melbourne, Noon pacific Wednesday 16 November, 3pm Eastern Wednesday 16 November and 8pm UK Wednesday 16 November.</p>
<p>This presentation is for devs. I’ll be writing code during my presentation and showing various techniques I’ve used whilst unit testing my Sitecore projects. Most of the techniques I’ve already written about on this blog, but I’ve recently had another try at getting testing to work without an HttpContext and been successful! I promise I’ll write a detailed blog post on that in the future, but I’ll show attendees in the meeting how I do that as well.</p>
<p>So if that all sounds like fun, jump over to the event page above and register.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/302/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/302/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/302/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/302/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adeneys.wordpress.com/302/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adeneys.wordpress.com/302/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adeneys.wordpress.com/302/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adeneys.wordpress.com/302/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/302/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/302/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/302/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/302/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/302/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/302/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=302&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2011/11/15/presenting-to-the-sitecore-users-virtual-group/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>
	</item>
		<item>
		<title>WeBlog Summit 2011</title>
		<link>http://adeneys.wordpress.com/2011/10/07/weblog-summit-2011/</link>
		<comments>http://adeneys.wordpress.com/2011/10/07/weblog-summit-2011/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 20:00:07 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>

		<guid isPermaLink="false">https://adeneys.wordpress.com/2011/10/07/weblog-summit-2011/</guid>
		<description><![CDATA[Ealier this year in April, Sitecore’s Dreamcore US event was held in Boston. One of my WeBlog colleagues, Nick Wesselman, gave a presentation at the event on the shared source WeBlog module. There was quite a lot of buzz around the module, especially from Sitecore themselves, who saw what we were doing with the module [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=300&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Ealier this year in April, Sitecore’s Dreamcore US event was held in Boston. One of my WeBlog colleagues, <a href="http://www.techphoria414.com" target="_blank">Nick Wesselman</a>, gave a presentation at the event on the shared source WeBlog module. There was quite a lot of buzz around the module, especially from Sitecore themselves, who saw what we were doing with the module as a great example of Sitecore community.</p>
<p>One of the interesting things about this module and how it’s developed is the geographical disparity of the contributors. At Dreamcore US, someone made the comment about how it would be great if the 3 WeBlog contributors (me, <a href="http://www.markvanaalst.com" target="_blank">Mark van Aalst</a> and Nick) could get together somewhere and have a summit, to go through the current module and work out the future direction of the module.</p>
<p>And that’s exactly what is going to happen in just under two weeks. Sitecore is sponsoring each of us to travel to Sitecore HQ in Copenhagen and have this summit.</p>
<p>And it’s going to be a great event! Lars Nielsen is currently coordinating to give the WeBlog contributors access to some of the Sitecore core developers and architects at the summit. This access will allow us to really align the module with Sitecore’s future direction, and ensure we’re ready to leverage all the cool new stuff coming in Sitecore Massive (and believe me, from what I’ve seen, there is some <em>very</em> cool stuff coming).</p>
<p>I’m also hoping we can get the first official release of WeBlog out there to the greater Sitecore community.</p>
<p>So if you’d like to have a say in the future of WeBlog or you’d like to request a feature or change, head over to the <a href="http://sdn.sitecore.net" target="_blank">Sitecore Developer Network</a> and post your ideas in the <a href="http://sdn.sitecore.net/forum/ShowForum.aspx?ForumID=30" target="_blank">EviBlog/WeBlog forum</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adeneys.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adeneys.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adeneys.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adeneys.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/300/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=300&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2011/10/07/weblog-summit-2011/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>Dreamcore AU 2011</title>
		<link>http://adeneys.wordpress.com/2011/10/06/dreamcore-au-2011/</link>
		<comments>http://adeneys.wordpress.com/2011/10/06/dreamcore-au-2011/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 11:20:54 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">https://adeneys.wordpress.com/2011/10/06/dreamcore-au-2011/</guid>
		<description><![CDATA[It was my great pleasure to present at Sitecore’s Dreamcore event in Sydney, Australia this week. This was the first time the conference was held in Australia and it was fantastic with lots of great speakers and interesting people. My session was titled “Testing Strategies for Sitecore” and was run in the developer stream, so [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=298&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It was my great pleasure to present at Sitecore’s Dreamcore event in Sydney, Australia this week. This was the first time the conference was held in Australia and it was fantastic with lots of great speakers and interesting people.</p>
<p>My session was titled “Testing Strategies for Sitecore” and was run in the developer stream, so it focused on automated/unit testing. As promised for everyone who attended my session, here is the code for my demo site and test project, as well as the slides.</p>
<ul>
<li><a href="http://www.codeflood.net/files/dreamcore2011 - unit testing.zip">Source code for demo site</a></li>
<li><a href="http://www.codeflood.net/files/DC2011 Testing Presentation.pptx">Slides for Testing Strategies for Sitecore</a></li>
</ul>
<p>The test project shows a few different techniques for automated testing your Sitecore projects including:</p>
<ul>
<li>Testing pages over HTTP</li>
<li>Testing using a web browser driver (WatiN)</li>
<li>Instantiating a Sitecore control</li>
<li>Testing within the HTTP Context</li>
<li>Testing without an HTTP Context</li>
</ul>
<p>I’ve covered all of the above techniques before, except for the last one, testing without an HTTP Context. I’ll cover that technique in detail in a future post.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adeneys.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adeneys.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adeneys.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adeneys.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/298/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=298&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2011/10/06/dreamcore-au-2011/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>Solving Generic Casting Issues with Actions</title>
		<link>http://adeneys.wordpress.com/2011/08/25/solving-generic-casting-issues-with-actions/</link>
		<comments>http://adeneys.wordpress.com/2011/08/25/solving-generic-casting-issues-with-actions/#comments</comments>
		<pubDate>Thu, 25 Aug 2011 10:11:25 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">https://adeneys.wordpress.com/2011/08/25/solving-generic-casting-issues-with-actions/</guid>
		<description><![CDATA[Generics in .net are a great way to avoid having to repeat your code when all you need to do is alter a few of the types involved in the code. Recently I was retrieving some objects from a data store in several different places in my code, and just altering the return types at [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=297&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Generics in .net are a great way to avoid having to repeat your code when all you need to do is alter a few of the types involved in the code. Recently I was retrieving some objects from a data store in several different places in my code, and just altering the return types at each call. This felt like an ideal candidate for generics.</p>
<p>I didn’t want to have to cast the array of objects to the appropriate type when I called the method. Instead I wanted to have the method return the appropriate type which is passed by the calling code.</p>
<p>The complicating factor around what I was trying to do was to do with the fact that I was passing a particular type into my generic method, but casting from a different type which the generic type didn’t inherit from. Even though I had implicit operators defined to go between my base type and wrapper, the compiler for some reason couldn’t see the conversion and failed. If I had the luxury of being able to make my wrapper inherit from the base class then everything would have been alright, but the base class I was dealing with came out of another system (a <code>Sitecore.Data.Items.Item</code>).</p>
<p>Let’s explore some code.</p>
<p>Below is a custom class and a wrapper. Notice how the wrapper class contains the implicit operators to allow implicit conversion to and from my custom class.</p>
<pre><code>public class RawClass
{
  public int ID { get; set; }

  public RawClass(int id)
  {
    ID = id;
  }
}

public class Wrapper
{
  private RawClass inner = null;

  public static implicit operator Wrapper(RawClass instance)
  {
    return new Wrapper(instance);
  }

  public static implicit operator RawClass(Wrapper instance)
  {
    return instance.inner;
  }

  public Wrapper(RawClass instance)
  {
    inner = instance;
  }

  public int GetId()
  {
    return inner.ID;
  }
}</code></pre>
<p>The implicit operators let me treat an instance of <code>Wrapper</code> like an instance of <code>RawClass</code>.</p>
<pre><code>Wrapper wrap = new RawClass(3);
RawClass raw = wrap;</code></pre>
<p>I can also pass instances of <code>Wrapper</code> to methods expecting <code>RawClass</code> without an explicit cast.</p>
<pre><code>public string GetId(RawClass raw)
{
  return raw.ID.ToString();
}

var raw = new RawClass(5);
Wrapper wrap = raw;
var id = GetId(wrap);</code></pre>
<p>Note above how I didn’t cast <code>wrap</code> to <code>RawClass</code> when I passed it to the <code>GetId</code> method.</p>
<p>OK, so all of the above compiles and works. Onto my problem.</p>
<p>I was working on a method to fetch several objects of one type but I wanted to define through generics the type to return from the method. In the above example code, <code>RawClass</code> is the type of object from the data store, but I want to cast it to the generic defined type for the return. The reason I wanted to use generics was because this method was going to be called from several different places in my code, all with different return types. I wanted to be able to call the method as such:</p>
<pre><code>var items = GetItems&lt;Wrapper&gt;();
var items2 = GetItems&lt;DifferentWrapper&gt;();</code></pre>
<p>For demonstration purposes I’ll use a dummy method to return me some data. In implementation this method would be replaced with one that actually communicated with the data store.</p>
<pre><code>private IEnumerable&lt;RawClass&gt; LoadFromDataStore()
{
  // Load data from data store
  for(int i = 0; i &lt; 4; i++)
    yield return new RawClass(i);
}</code></pre>
<p>And now we can write the <code>GetItems</code> method which is the generic method that loads the data and casts it to the appropriate type.</p>
<pre><code>private T[] GetItems&lt;T&gt;() where T : class
{
  var list = new List&lt;T&gt;();
  var objects = LoadFromDataStore();

  foreach(var ob in objects)
  {
    list.Add((T)ob);
  }

  return list.ToArray();
}</code></pre>
<p>Not quite. The above code won’t compile. The compiler will give an error about converting from <code>RawClass</code> to <code>T</code>.</p>
<pre>Error    Cannot convert type 'GenericCasting.RawClass' to 'T'</pre>
<p>I could replace the cast above with a safe cast using the <code>as</code> operator, but it doesn’t really give us what we want. The safe cast will return null instead of throwing an exception when it can’t cast from one type to another. Even though the above code <em>should</em> work because we’ve defined the implicit conversion operators, it doesn’t.</p>
<p>I struggled with this code for quite some time, even getting it to a point where I got errors stating there is no conversion from <code>RawClass</code> to <code>Wrapper</code>. Are you serious? I’m even using the implicit operators in other parts of the code!</p>
<p>I knew I could cast the objects if I wasn’t dealing with a generic type, and the calling code knew what type it wanted to deal with, so I needed to pass control momentarily back to the calling code and have it do the casting. I’ve shown previously how to <a href="http://adeneys.wordpress.com/2011/04/12/calling-control/" target="_blank">pass control back to the calling code</a>, and this approach is basically the same.</p>
<p>Enter the <code>Action&lt;&gt;</code> class. Action is simply a generic delegate and an efficient way to use delegates when you don’t want to define a new delegate type. I simply pass as the type parameters the types I want my delegate to require. Let’s have a look at how I can update the previous method to use an action which would be called to pass control back to the calling code.</p>
<pre><code>private T[] GetItems&lt;T&gt;(Action&lt;List&lt;T&gt;, RawClass&gt; act) where T : class
{
  var list = new List&lt;T&gt;();
  var objects = LoadFromDataStore();

  foreach(var ob in objects)
  {
    act(list, ob);
  }

  return list.ToArray();
}</code></pre>
<p>In my Action I’ve define the parameters as being of type <code>List&lt;T&gt;</code> and <code>RawClass</code>. The calling code will need to cast the <code>RawClass</code> and add it to the list. To call this method:</p>
<pre><code>var list = GetItems&lt;Wrapper&gt;((l, ob) =&gt; { l.Add(ob); });</code></pre>
<p>Mmmm. Syntactic sugar.</p>
<p>Rather than using a traditional delegate I’m using a lambda expression. Note how I don’t even need to cast, because the implicit conversion is now working when the compiler can see what the types are.</p>
<p>And that’s it. Using this technique I’ve worked around the limitations of the compiler not seeing the conversions between classes when using generics.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/297/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/297/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/297/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/297/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adeneys.wordpress.com/297/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adeneys.wordpress.com/297/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adeneys.wordpress.com/297/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adeneys.wordpress.com/297/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/297/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/297/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/297/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/297/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/297/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/297/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=297&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2011/08/25/solving-generic-casting-issues-with-actions/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>SEFE On-Site Payment Provider</title>
		<link>http://adeneys.wordpress.com/2011/08/10/sefe-on-site-payment-provider/</link>
		<comments>http://adeneys.wordpress.com/2011/08/10/sefe-on-site-payment-provider/#comments</comments>
		<pubDate>Tue, 09 Aug 2011 21:39:22 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>
		<category><![CDATA[sefe]]></category>

		<guid isPermaLink="false">https://adeneys.wordpress.com/2011/08/10/sefe-on-site-payment-provider/</guid>
		<description><![CDATA[I’ve recently had the opportunity to get to know the Sitecore eCommerce Fundamental Edition or SEFE for short. One of our clients wanted to port their existing online shop to Sitecore which we’d used to rebuild their site. The main reason I chose SEFE was due to the fact that SEFE IS Sitecore and is [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=296&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I’ve recently had the opportunity to get to know the Sitecore eCommerce Fundamental Edition or SEFE for short. One of our clients wanted to port their existing online shop to Sitecore which we’d used to rebuild their site.</p>
<p>The main reason I chose SEFE was due to the fact that SEFE <em>IS</em> Sitecore and is built completely in Sitecore. All other eCommerce platforms I assessed were external applications and would have required a great deal of integration effort to make them work as seamlessly as SEFE felt. I should mention that SEEE (Sitecore eCommerce Enterprise Edition) had not been released at the time, so that was never a contender.</p>
<p>Before I get into the goodness of this post about the payment providers, a quick warning to any about to use SEFE. The example site is just that. An example. I would never again attempt to use the example site as part of my production site. The example site has it’s own way of doing things and it’s own markup. Perhaps my experience was marred by the fact I had to bash the example controls to work with the existing CSS. So based on my experience, my advice to you is to refer to the example site as a reference, but build your own site components.</p>
<p>So, onto payment providers. The site I was porting over to SEFE hosted a credit card payment form itself. It uses an on-site payment method where the user never leaves the site; there is no redirect to the payment providers payment page and then a redirect back to the site. I needed to replicate this in SEFE.</p>
<p>Flicking through the <a href="http://sdn.sitecore.net/upload/sdn5/products/sefe/sefe110/sefe_payment_method_reference_guide_11-a4.pdf" target="_blank">SEFE payment method reference guide</a>, which can be found on <a href="http://sdn.sitecore.net" target="_blank">SDN</a>, it seemed it didn’t quite tell me what I needed to do to host my own payment form. That document focused heavily on using a redirect to the payment providers hosted form. There were snippets about an on-site option, but not nearly enough information on this.</p>
<p>Eventually I found in the document the <code>IIntegrationalPaymentProvider</code> interface that sounded like what I needed to be able to write my own on-site payment provider…but it has not been implemented yet.</p>
<p>As it turns out, it’s not that hard to handle payments on-site but still fit within how SEFE wants to work. The trick is to create a normal <code>IOnlinePaymentProvider</code> (for an off-site payment provider) but host the payment forms yourself and have your payment provider interact with your own forms.</p>
<p>So let’s create a sample on-site payment provider using this approach. I’m going to write my sample payment provider and deploy it to the SEFE sample site. For this sample I’ll need to work against an existing Sitecore site with the latest version of SEFE installed.</p>
<p>We need to create a new class for our payment provider which extends the <code>Sitecore.Ecommerce.Payments.OnlinePaymentProvider</code> class which can be found in the <code>Sitecore.Ecommerce.Kernel</code> assembly. There are 2 methods we need to override to make our payment provider work; <code>Invoke</code> and <code>ProcessCallback</code>. <code>Invoke</code> is called when SEFE uses your payment provider to make a payment and <code>ProcessCallback</code> is called when the normally external payment provider site redirects the user back to your site.</p>
<p>For our sample on-site provider, in the <code>Invoke</code> method we simply need to redirect the user to the payment form on our site. We don&#8217;t need to send any data like we would an off-site payment provider cause we can simply retrieve that data from the payment form. The OOTB payment provider configuration in SEFE allows entering a primary and secondary URL for the provider. For our provider we’ll use the primary URL to point to our on-site payment form, and the secondary URL to point to the payment gateway service we’ll be using. The URLs are configured inside Sitecore on the payment provider item we’ll configure a but later on. SEFE passes the configured URLs into the payment provider through the <code>paymentSystem</code> parameter.</p>
<pre><code>public override void Invoke(
  Sitecore.Ecommerce.DomainModel.Payments.PaymentSystem paymentSystem,
    PaymentArgs paymentArgs)
{
  base.Invoke(paymentSystem, paymentArgs);

  // Store return page URL in transaction for use on credit card form
  var transaction = Sitecore.Ecommerce.Context.Entity.Resolve&lt;TransactionData&gt;(); 

  transaction.SavePersistentValue(paymentArgs.ShoppingCart.OrderNumber,
    &quot;returnurl&quot;, paymentArgs.PaymentUrls.ReturnPageUrl);

  HttpContext.Current.Response.Redirect(paymentSystem.PaymentUrl);
}</code></pre>
<p>Note above how I’m storing the return page URL? That URL is what we must redirect the user to after a successful payment so SEFE will process the order. I can&#8217;t retrieve that URL from the payment form by other means so I&#8217;ll store that URL in the transaction so I can retrieve it later.</p>
<p>The page we redirect the user to will handle collection of credit card information from the user, communication with the payment gateway and setting the success or failure of the payment. For this we’ll create a new sublayout containing the following markup:</p>
<pre><code>&lt;%@ Control Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot;
  CodeBehind=&quot;CreditCardForm.ascx.cs&quot;
  Inherits=&quot;SampleOnsitePaymentProvider.layouts.CreditCardForm&quot; %&gt;
  &lt;div&gt;
    &lt;strong&gt;Amount Due: &lt;/strong&gt;&lt;asp:Literal runat=&quot;server&quot;
      ID=&quot;litAmount&quot; /&gt;
  &lt;/div&gt;
  &lt;div&gt;
    Card Number: &lt;asp:TextBox runat=&quot;server&quot; ID=&quot;txtCardNumber&quot; /&gt;
  &lt;/div&gt;
  &lt;div&gt;
    Name on Card: &lt;asp:TextBox runat=&quot;server&quot; ID=&quot;txtName&quot; /&gt;
  &lt;/div&gt;
  &lt;div&gt;
    Expiry: Month: &lt;asp:TextBox runat=&quot;server&quot; ID=&quot;txtMonth&quot; /&gt;
    Year: &lt;asp:TextBox runat=&quot;server&quot; ID=&quot;txtYear&quot; /&gt;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;asp:Literal runat=&quot;server&quot; ID=&quot;litMessage&quot; /&gt;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;asp:Button runat=&quot;server&quot; ID=&quot;btnSubmit&quot; Text=&quot;Submit&quot;
      OnClick=&quot;SubmitClicked&quot; /&gt;
  &lt;/div&gt;</code></pre>
<p>Not particularly complex. The code behind of this sublayout is pretty straight forward, set the total of the order when the page loads and then process the credit card details when the form is submitted.</p>
<pre><code>using System;
using Sitecore.Ecommerce;
using Sitecore.Ecommerce.DomainModel.Carts;
using Sitecore.Ecommerce.Payments;

namespace SampleOnsitePaymentProvider.layouts
{
  public partial class CreditCardForm : System.Web.UI.UserControl
  {
    protected void Page_Load(object sender, EventArgs e)
    {
      var shoppingCart =
        Sitecore.Ecommerce.Context.Entity.GetInstance&lt;ShoppingCart&gt;();
      if (shoppingCart != null)
        litAmount.Text = shoppingCart.Totals.TotalPriceIncVat.ToString();
      else
      {
        litMessage.Text = &quot;Failed to find the shopping cart&quot;;
        btnSubmit.Enabled = false;
      }
    }

    protected void SubmitClicked(object sender, EventArgs args)
    {
      // TODO: validation
      var shoppingCart =
        Sitecore.Ecommerce.Context.Entity.GetInstance&lt;ShoppingCart&gt;();
      if (shoppingCart != null)
      {
        // Configure payment gateway client
        var client = new PaymentGateway();
        client.Url = shoppingCart.PaymentSystem.PaymentSecondaryUrl;
        client.Username = shoppingCart.PaymentSystem.Username;
        client.Password = shoppingCart.PaymentSystem.Password; 

        client.CardNumber = txtCardNumber.Text;
        client.CardName = txtName.Text;
        client.ExpireMonth = txtMonth.Text;
        client.ExpireYear = txtYear.Text;

        if (client.Process())
        {
          // Store the transaction number to indicate success
          var transaction =
            Sitecore.Ecommerce.Context.Entity.Resolve&lt;TransactionData&gt;();
          transaction.SavePersistentValue(shoppingCart.OrderNumber,
            TransactionConstants.TransactionNumber, client.TransactionNumber);

          // Get return page URL from transaction
          var url = transaction.GetPersistentValue(shoppingCart.OrderNumber,
            &quot;returnurl&quot;) as string;
          Response.Redirect(url);
        }
        else
        {
          litMessage.Text = &quot;Payment failed. Please try again.&quot;;
        }
      }
      else
      {
        litMessage.Text = &quot;Failed to find the shopping cart&quot;;
        btnSubmit.Enabled = false;
      }
    }
  }
}</code></pre>
<p>You would of course need to alter the above code to call out to your payment gateway appropriately. Note how I store the transaction number from the payment gateway into my SEFE transaction? I’m going to use this piece of data in my payment provider to determine that the payment was successful. The <code>TransactionConstants</code> class is provided by SEFE to provide keys for common pieces of data you might require.</p>
<p>I’m also using that return page URL I stored when my payment provider was invoked.</p>
<p>Now all that’s left is to process the callback in my payment provider as a result of redirecting to the return page. This method is called by SEFE.</p>
<pre><code>public override void ProcessCallback(
  Sitecore.Ecommerce.DomainModel.Payments.PaymentSystem paymentSystem,
    PaymentArgs paymentArgs)
{
  var transaction = Sitecore.Ecommerce.Context.Entity.Resolve&lt;TransactionData&gt;();
  if (!string.IsNullOrEmpty(transaction.GetPersistentValue(
    paymentArgs.ShoppingCart.OrderNumber,
    TransactionConstants.TransactionNumber) as string))
    PaymentStatus = PaymentStatus.Succeeded;
  else
    PaymentStatus = PaymentStatus.Failure;
}</code></pre>
<p>In this method I’m checking that the transaction number has been populated before setting the outcome of the payment in the <code>PaymentStatus</code> property as succcessful.</p>
<p>Now to register everything with SEFE and get this sample working in the SEFE example site.</p>
<p>SEFE stores the payment providers available for a site under the site’s business catalogue under the <code>payment options</code> item. The payment options item contains settings for all payment providers such as the payment return page and other URLs. Individual payment providers are defined as children of the <code>payment options</code> item and are based on the <code>ecommerce/business catalog/payment</code> data template.</p>
<p>One of the settings of our sample payment provider will be the URL to the credit card form, so we’d better create that first. I’m going to create this page as one of the function pages in the sample checkout.</p>
<p><img style="background-image:none;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;margin-right:auto;padding-top:0;border-width:0;" title="credit card checkout page" border="0" alt="credit card checkout page" src="http://adeneys.files.wordpress.com/2011/08/credit-card-checkout-page.png?w=504&#038;h=364" width="504" height="364" /></p>
<p>Make sure you add the credit card form sublayout we created above to the page.</p>
<p>Now we’ll register our payment provider. Create a new payment provider item in the business catalogue and populate the fields appropriately. The important fields are:</p>
<table border="0" cellspacing="0" cellpadding="2" width="552">
<tbody>
<tr>
<th valign="top" width="166">Field</th>
<th valign="top" width="235">Purpose</th>
<th valign="top" width="149">Value</th>
</tr>
<tr>
<td valign="top" width="166">Code</td>
<td valign="top" width="235">maps this provider to a provider through the Unity configuration</td>
<td valign="top" width="149">credit</td>
</tr>
<tr>
<td valign="top" width="166">Name</td>
<td valign="top" width="235">Appears on the UI</td>
<td valign="top" width="149">Credit Card</td>
</tr>
<tr>
<td valign="top" width="166">Payment Provider URL</td>
<td valign="top" width="235">The URL SEFE will redirect the user to</td>
<td valign="top" width="149">Link to the credit card form</td>
</tr>
<tr>
<td valign="top" width="166">Username</td>
<td valign="top" width="235">The username of the account to access the payment gateway</td>
<td valign="top" width="149">Your payment gateway username</td>
</tr>
<tr>
<td valign="top" width="166">Password</td>
<td valign="top" width="235">The password of the account to access the payment gateway</td>
<td valign="top" width="149">Your payment gateway password</td>
</tr>
<tr>
<td valign="top" width="166">Payment Provider Secondary URL</td>
<td valign="top" width="235">For our payment provider, this is the URL of the payment gateway service</td>
<td valign="top" width="149">Your payment gateway URL</td>
</tr>
</tbody>
</table>
<p>SEFE uses Unity to configure many parts of the module, including mapping payment providers. Open up the <code>App_Include/Unit.config</code> file and find an existing payment provider by searching for the code <code>PayByCheck</code>. This is the registration of the code and the mapping to the implementation type. Copy this element and update to use the code we defined in the payment provider item’s <code>code</code> field above, and update the <code>mapTo</code> attribute(which we’ll need to register next). Also, the <code>&lt;property name=&quot;PaymentSystem&quot; /&gt;</code> element isn’t required. The resulting updated element may look like the following:</p>
<pre><code>&lt;register type=&quot;PaymentProvider&quot;
  mapTo=&quot;CreditCardPaymentProvider&quot; name=&quot;Credit Card&quot;/&gt;</code></pre>
<p>Now search for the alias implementing the <code>PayByCheck</code> payment provider, <code>OfflinePaymentProvider</code>. This isn’t a .net type, but a Unity alias, we’re looking for the alias to real type mapping element. Copy the existing <code>OfflinePaymentProvider</code> alias and update to map the <code>CreditCardPaymentProvider</code> alias above to the payment provider we created in our project above. The resulting updated element may look like the following:</p>
<pre><code>&lt;alias alias=&quot;CreditCardPaymentProvider&quot;
  type=&quot;SampleOnsitePaymentProvider.OnsitePaymentProvider,
  SampleOnsitePaymentProvider&quot; /&gt;</code></pre>
<p>If everything worked properly then you’ll be able to test your payment provider on the sample site. Just go through the normal checkout process and select credit card as the payment option on the payment page.</p>
<p><img style="background-image:none;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;margin-right:auto;padding-top:0;border-width:0;" title="credit card payment page" border="0" alt="credit card payment page" src="http://adeneys.files.wordpress.com/2011/08/credit-card-payment-page.png?w=504&#038;h=256" width="504" height="256" /></p>
<p>And there you have it! The payment provider we’ve created in this post isn’t tied to any particular payment gateway, only the credit card page (that you configure) is. So you can use this technique to host your own payment form in SEFE without redirecting users off-site.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adeneys.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adeneys.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adeneys.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adeneys.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/296/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/296/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/296/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=296&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2011/08/10/sefe-on-site-payment-provider/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>

		<media:content url="http://adeneys.files.wordpress.com/2011/08/credit-card-checkout-page.png" medium="image">
			<media:title type="html">credit card checkout page</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2011/08/credit-card-payment-page.png" medium="image">
			<media:title type="html">credit card payment page</media:title>
		</media:content>
	</item>
		<item>
		<title>Virtual Items in Sitecore</title>
		<link>http://adeneys.wordpress.com/2011/07/01/virtual-items-in-sitecore/</link>
		<comments>http://adeneys.wordpress.com/2011/07/01/virtual-items-in-sitecore/#comments</comments>
		<pubDate>Fri, 01 Jul 2011 12:11:45 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Sitecore]]></category>

		<guid isPermaLink="false">https://adeneys.wordpress.com/2011/07/01/virtual-items-in-sitecore/</guid>
		<description><![CDATA[One of the many benefits of using a good CMS like Sitecore is the ability to reuse a single piece of content in multiple locations around your site. This ability is provided through virtual items. So what is a virtual item? A virtual item is an item that doesn’t actually exist. Why wouldn’t you want [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=293&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One of the many benefits of using a <em>good</em> CMS like Sitecore is the ability to reuse a single piece of content in multiple locations around your site. This ability is provided through virtual items.</p>
<p>So what is a virtual item? A virtual item is an item that doesn’t actually exist. Why wouldn’t you want the item to exist? One reason would be to keep your content tree clean and another would be to reduce the workload on your content authors. Often virtual items are used to provide a single source of content that can be reused throughout multiple points in your site.</p>
<p>In this post I’m going to visit a few options available inside Sitecore for using virtual items and some related options for achieving those goals mentioned above.</p>
<h4>Clone Items</h4>
<p>Clone items were introduced in Sitecore 6.4. A cloned item uses another item (source item) in the same way template standard values are used. If a cloned item’s field value is null Sitecore will get the value of that field from the clone source. This allows fields of a cloned item to be overridden without affecting the source item.</p>
<p>This option is good when you want a physical item to be shown in the content tree or when you need to allow content authors to create the cloned items themselves. It’s also a good option for when you want to share most of the fields of the source item, but allow overriding of others when the shared item is used, such as whether it would appear in the breadcrumb (if that was controlled through a field value).</p>
<p>Standard values also works with clones, so if a clone source doesn’t have a field value that field value will be read from standard values right through to the clone item itself. If the value is then overridden on the clone source, that overridden values will be read by the cloned item. The clone is an additional layer in the standard values stack.</p>
<p>Cloned items work just like any other item, cause they are actually a real item. So in that respect they’re not actually virtual. But they can help achieve that goal of having a single source for content and reusing that content throughout the website. Because clone items are real items they will have a different ID to the clone source item.</p>
<p>But if I want a single source of content, allowing users to override values on the cloned item itself goes against that. How can I stop content authors from overriding values on cloned items? Simple! The same way you would stop them from editing any piece of content, by using Sitecore security.</p>
<h4>Proxy Items</h4>
<p>If you’re using Sitecore 6.4 or lower then proxy items are what you would use instead of clone items. Proxy items were deprecated in Sitecore 6.5, so if you’re starting a new project you shouldn’t be using them. Although still present in Sitecore 6.5, being that they are deprecated Sitecore may remove this feature entirely in a future release.</p>
<p>Proxy items proxy an item (or subtree) from one part of the content tree to another. Updates to a proxy item will update the source item. This means you can’t override a source item value. Other than that, proxy items work in much the same way as clones do.</p>
<p>Unlike clone items which require a physical item in the content tree, proxy items don’t require a physical target item, so they are actually virtual.</p>
<h4>Wildcard Items</h4>
<p>A wildcard item is an item named with an asterisk (*). It will handle any item requests at a single level in the content tree if another item at the same level isn’t found.</p>
<p>So if I have a content tree as follows:</p>
<pre><code>/sitecore/content/home/a
/sitecore/content/home/c
/sitecore/content/home/*</code></pre>
<p>If I make a request for <code>/sitecore/content/home/b</code> the wildcard item will handle that request. But if I make a request for <code>/sitecore/content/home/a</code>, the <code>a</code> item will handle that.</p>
<p>Wildcard items only work for a single level. In the above example, if I make a request for <code>/sitecore/content/home/b/b</code> I’ll get an item not found error. To handle that case I would need a wildcard item under the wildcard item. So I need a wildcard item for every level I want to be able to handle all requests for.</p>
<p>Wildcard items are also real items, but they allow the requesting of virtual items at a single level of the content tree. Being real items they must exist in the content tree. Some people might think this makes the content tree look messy, particularly if you have a lot of wildcard items.</p>
<p>One way to hide the wildcard items from normal content authors is to make the wildcard item hidden. In the content editor navigate to your wildcard item, select it then in the configure tab click the <code>hide item</code> option in the <code>attributes</code> section. Now the item will only display in the content tree if the user has ticked the <code>hidden items</code> option on the view tab in the content editor.</p>
<p>If you need to have a lot of wildcard items in predictable locations or if you really don’t want them shown in the content tree you may need to consider the next option instead.</p>
<h4>Request Pipeline Processor</h4>
<p>A fairly straight forward way of handling virtual items at any level without messing up your content tree is to create your own <code>httpRequestBegin</code> processor and insert it into the pipeline. I like to do this after the existing <code>ItemResolver</code>, so in my custom processor I can check to see if the context item is null, and only process the request with my processor if it is. Every <code>httpRequestBegin</code> pipeline processor will run on every request, so you need to ensure processors in this pipeline are as efficient as possible. The simple check for a null context item is very efficient.</p>
<p>With a custom pipeline processor much more complex logic for virtual items can be implemented including checking only for specific item names or allowing any level of virtual item to be requested.</p>
<p>A real world example of this kind of option out in the wild is in the Sitecore eCommerce Fundamental Edition module (SEFE). It uses a custom item resolver after the default Sitecore item resolver to service requests for product which don’t live at the requested location, but exist in another part of the content tree.</p>
<p>I recently used this approach myself in a design. The client wanted an item to appear as a child of another item, but didn’t want that child item to actually be an item in the content tree. All the data required to render the virtual child item was pulled from it’s parent. There were several reasons for this design. Firstly, the client had strict rules around the naming of this item; it must always be called by a specific name. Secondly the virtual child item must always sort in a specific manner; at the bottom of the list of real child pages. Both of those could be achieved through other mechanisms. The biggest factor was the fact that the client didn’t want the virtual item to be edited in a different location to the rest of the data on the parent. They wanted the data for the virtual child item defined on the same item as the parent.</p>
<p>Unlike the above options, this option requires some coding. To implement your own processor, create a class which inherits from <code>HttpRequestProcessor</code> and override the <code>Process</code> method. In your method populate the Sitecore context item to whatever it should be based on the incoming request.</p>
<p>This option is good when you have predictable logic or when you don’t want to show the virtual items in the content tree.</p>
<h4>Custom Data Provider</h4>
<p>If none of the above options satisfy your exact needs you could always implement your own custom data provider to provide the virtual items. The biggest advantage of this approach is that your virtual items will appear in the content tree.</p>
<p>Defining the virtual items will be up to whatever logic you implement in the data provider. You could automatically return the virtual items based on business rules or you could infer the virtual items from data the content authors input on real items.</p>
<p>One such example of this is the <a href="http://blog.capaxsolutions.co.uk/2010/06/09/sitecore-item-mirroring-making-an-item-appear-in-more-than-one-place/" target="_blank">Item Mirror Data Provider</a> written by Steve Green. It shows how you can allow selecting items in one part of the content tree to have virtual representations of those items appear in other parts.</p>
<p>This is the most comprehensive approach to virtual items and the most difficult. Implementing a data provider is no mean feat and should not be undertaken lightly.</p>
<h4>Conclusion</h4>
<p>So there you have a few different options when designing how your virtual items should work. The biggest considerations will be whether you want content authors to define the virtual items (whether directly or indirectly), whether you want them to appear in the content tree and whether you want to use an out-of-the-box solution or write some code to achieve what you want.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adeneys.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adeneys.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adeneys.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adeneys.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/293/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=293&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2011/07/01/virtual-items-in-sitecore/feed/</wfw:commentRss>
		<slash:comments>4</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>Importing lists with Revolver</title>
		<link>http://adeneys.wordpress.com/2011/06/16/importing-lists-with-revolver/</link>
		<comments>http://adeneys.wordpress.com/2011/06/16/importing-lists-with-revolver/#comments</comments>
		<pubDate>Thu, 16 Jun 2011 09:15:09 +0000</pubDate>
		<dc:creator>Alistair Deneys</dc:creator>
				<category><![CDATA[Revolver]]></category>
		<category><![CDATA[Sitecore]]></category>

		<guid isPermaLink="false">https://adeneys.wordpress.com/2011/06/16/importing-lists-with-revolver/</guid>
		<description><![CDATA[Recently I had to create a list of reference items in Sitecore that was a few hundred items long. Doing this exercise manually would have been mind numbing and taken a few hours out of my day. Thanks goodness for Revolver! Revolver contains the split command which can be used to split larger strings up. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=292&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Recently I had to create a list of reference items in Sitecore that was a few hundred items long. Doing this exercise manually would have been mind numbing and taken a few hours out of my day. Thanks goodness for Revolver!</p>
<p>Revolver contains the <code>split</code> command which can be used to split larger strings up. Combined with the <code>echo</code> command which can be used to input text from files and I’ve got the basic building blocks required to import large amounts of items from file.</p>
<p>Let’s give ourselves a solid example to work with. A common task for a lot of people may be to create a list of all the countries in the world for selection in a form. I’ll use Revolver to create a set of reference items containing the countries which can be read and populated into the form.</p>
<p>The first thing I need to do is find a source of all the countries. A bit of googling for “list of countries” brought me to <a href="http://www.listofcountriesoftheworld.com/">http://www.listofcountriesoftheworld.com/</a>.</p>
<p><a href="http://adeneys.files.wordpress.com/2011/06/list-of-countries-site.png"><img style="background-image:none;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;margin-right:auto;padding-top:0;border-width:0;" title="list of countries site" border="0" alt="list of countries site" src="http://adeneys.files.wordpress.com/2011/06/list-of-countries-site_thumb.png?w=504&#038;h=348" width="504" height="348" /></a></p>
<p>This page is perfect for what I need to do.</p>
<p>Next, select the countries from the table and copy them. Now we’re going to use Excel to separate out that numeric identifier from the country name. One thing to note about the way Revolver works, it doesn’t assume you’re working in a vacuum. Yes, it is a command prompt, but unlike a command prompt for an OS it knows that you probably also have a mouse and can select things and copy them and such. Rather than try and replicate complex pasting behaviour into Revolver it makes more sense to use an external tool to get the data into the right format for processing.</p>
<p>So after copying the countries, paste them into Excel. Lucky for us Excel understands HTML tables and knows how to split the blob of HTML we have on the clipboard into separate cells in the spreadsheet. Now delete the number column (the first one). You should be left with a single column of country names.</p>
<p><a href="http://adeneys.files.wordpress.com/2011/06/list-of-countries-excel.png"><img style="background-image:none;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;margin-right:auto;padding-top:0;border-width:0;" title="list of countries excel" border="0" alt="list of countries excel" src="http://adeneys.files.wordpress.com/2011/06/list-of-countries-excel_thumb.png?w=504&#038;h=398" width="504" height="398" /></a></p>
<p>Now save the file as a CSV so we’re left with a text file containing the textual country names, one on each line of the file.</p>
<p>Fire up Sitecore, log in and start Revolver. I’ll first show you how to read the file using the <code>echo</code> command.</p>
<p>But first, a quick note about line endings. For some reason, when I was preparing this example the CSV file that Excel generated ended up with <code>\r</code> for line endings instead of the standard Windows \r\n</code> line endings. Although I’ve updated Revolver 1.2.1 to deal with mixed line endings if you’re using an earlier version of Revolver you’ll need to convert the line endings to normal Windows line endings <code>\r\n</code> or the UI won’t handle the <code>\r</code> from the file.</p>
<p><code>echo</code> can be used to input and output content from files using the <code>-f</code> parameter. To have the command input the file rather than output use the <code>-i</code> parameter.</p>
<pre><code>echo -i -f c:\temp\countries.csv</code></pre>
<p>This will list all the countries in the UI. We’ll need to combine this command with the <code>split</code> command to split the lines on the newline characters and execute a command against each line.</p>
<p>The <code>split</code> command contains a parameter for splitting on newline, <code>-n</code>.</p>
<pre><code>split -n &lt; (echo -i -f c:\temp\countries.csv) (echo (found line) $current$)</code></pre>
<p>Note how we pass the previous echo command (the one used to read the file in) as a sub-command? The left angle bracket &lt; causes Revolver to evaluate the next argument and pass the output of that execution into the command. The last parameter supplied to <code>split</code> is the command to execute against each line. We can make use of the special token <code>$current$</code> in that parameter which will get replaced with the current line from the file. This command will get executed for each of the lines.</p>
<p><a href="http://adeneys.files.wordpress.com/2011/06/echo-and-split.png"><img style="background-image:none;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;margin-right:auto;padding-top:0;border-width:0;" title="echo and split" border="0" alt="echo and split" src="http://adeneys.files.wordpress.com/2011/06/echo-and-split_thumb.png?w=504&#038;h=458" width="504" height="458" /></a></p>
<p>Now all we have to do is change the command being executed against each line to create an item using the current line as the name.</p>
<pre><code>split -n &lt; (echo -i -f c:\temp\countries.csv) (touch -t (sample/sample item) ($current$))</code></pre>
<p>Note how we’ve surrounded the <code>$current$</code> token in parenthesis? This is because the current line may include spaces and we need to ensure they are handled as part of the <code>name</code> parameter and not treated as the <code>path</code> parameter.</p>
<p>But don’t get ahead of yourself and execute that command just yet…if only it was that simple. If you had a look at the country list you’d see that some of the country names contain illegal Sitecore name characters such as comma (,), apostrophe (') and double quotes (&quot;). We’ll need to replace those.</p>
<p>Revolver contains the <code>replace</code> command which allows you to use regular expressions to replace matches in strings. Rather than replace each of the invalid characters, I’ll instead use a regular expression to replace any illegal character with nothing.</p>
<pre><code>split -n &lt; (echo -i -f c:\temp\countries.csv) (touch -t (sample/sample item) &lt; (replace ($current$) [^\w\s] ()))</code></pre>
<p>But I’m not quite happy with that. Although the above will create the list of reference items, I want to include the original country name in the <code>title</code> field of the reference item’s I’m creating for when the item is displayed on the website.</p>
<p>To execute multiple commands for each line, I’ll need to create a Revolver script and call that script in the <code>split</code> command. The script is going to be very simple, just create the item as we did above and set the <code>title</code> field from the original name. We’ll need to allow the original name to be passed into the script. Parameters can be passed to Revolver scripts as they are passed to commands. Inside the script I can reference the passed in parameters using a token <code>$1$</code> where the number is the 1-based index of the parameter being passed in.</p>
<p>Scripts are created in the <code>core</code> database under the <code>/sitecore/system/modules/revolver/scripts</code> item and are based on the <code>Revolver/Script</code> template. Create a new script named <code>create</code> and fill in the following as the script:</p>
<pre><code>set name &lt; (replace ($1$) [^\w\s] ())
touch -t (sample/sample item) ($name$)
sf -nv title ($1$) ($name$)
set name</code></pre>
<p>Let me explain the script above. Firstly we create an environment variable called <code>name</code> and set it as the output of the replace command we used in our original command above (stripping invalid name characters). We need to use this value multiple times so it’s easier to evaluate the value once and store it rather than continue to evaluate it. Notice the <code>$1$</code> parameter? That will be substituted with the first parameter passed to the script when it’s executed. Next we create the item using the name we’ve created. After that we set the title field to the original name passed into the script. The last parameter passed to the <code>sf</code> (set field) command is a relative path to execute the command at which is how we have the command executed for the item we just created instead of on the current context item. By default Revolver will create a new version of an item before updating any field values so the <code>-nv</code> (no version) parameter is used to not create a new version of the item before updating the field value. The last command clears the environment variable we set. This is just good housekeeping.</p>
<p>Notice all the parenthesis around the variables <code>$1$</code> and <code>$name$</code>? Those are to make sure the script works as expected when spaces have been included in those parameters.</p>
<p>To execute my script I just call it by name and pass it the unsafe name of the item to create.</p>
<pre><code>create (&quot;Bahamas, The&quot;)</code></pre>
<p>I need to pass the parameter above enclosed in parenthesis cause the parameter does in fact have a space in it. The parenthesis cause the command parser to treat this as a single parameter rather than 2 separate parameters.</p>
<p>Now I can update my <code>split</code> command to make use of this new script to create the country items and set the title fields to the original values.</p>
<pre><code>split -n &lt; (echo -i -f c:\temp\countries.csv) (create ($current$))</code></pre>
<p>And here’s the result of executing that command.</p>
<p><a href="http://adeneys.files.wordpress.com/2011/06/imported-countries.png"><img style="background-image:none;padding-left:0;padding-right:0;display:block;float:none;margin-left:auto;margin-right:auto;padding-top:0;border-width:0;" title="imported countries" border="0" alt="imported countries" src="http://adeneys.files.wordpress.com/2011/06/imported-countries_thumb.png?w=503&#038;h=368" width="503" height="368" /></a></p>
<p>Success!</p>
<p>So you can see how you can use Revolver to not only import content lists from file but also to transform the data in that file as well.</p>
<p>If you want more information on any of the commands used, keep in mind that Revolver contains built in help for all commands. All you need to do is type <code>help</code> and the name of the command to view help for the command.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/adeneys.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/adeneys.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/adeneys.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/adeneys.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/adeneys.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/adeneys.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/adeneys.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/adeneys.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/adeneys.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/adeneys.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/adeneys.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/adeneys.wordpress.com/292/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/adeneys.wordpress.com/292/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/adeneys.wordpress.com/292/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=adeneys.wordpress.com&amp;blog=3885947&amp;post=292&amp;subd=adeneys&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://adeneys.wordpress.com/2011/06/16/importing-lists-with-revolver/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/2011/06/list-of-countries-site_thumb.png" medium="image">
			<media:title type="html">list of countries site</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2011/06/list-of-countries-excel_thumb.png" medium="image">
			<media:title type="html">list of countries excel</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2011/06/echo-and-split_thumb.png" medium="image">
			<media:title type="html">echo and split</media:title>
		</media:content>

		<media:content url="http://adeneys.files.wordpress.com/2011/06/imported-countries_thumb.png" medium="image">
			<media:title type="html">imported countries</media:title>
		</media:content>
	</item>
	</channel>
</rss>
