<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><language>en</language><title>Blog posts by Cristian Libardo</title> <link>https://world.optimizely.com/blogs/Cristian-Libardo/</link><description></description><ttl>60</ttl><generator>Optimizely World</generator><item> <title>Spark View Engine on WebForms</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/11/Spark-View-Engine-on-WebForms/</link>            <description>&lt;p&gt;&lt;a href=&quot;http://sparkviewengine.com/&quot;&gt;Spark view engine&lt;/a&gt; is a neat little web utility that allows you to write code like this:&lt;/p&gt;
&lt;div id=&quot;scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:a7b8b8bf-f8e3-49e0-bd53-dfd43c21db04&quot; class=&quot;wlWriterEditableSmartContent&quot; style=&quot;margin: 0px; display: inline; float: none; padding: 0px;&quot;&gt;
&lt;pre style=&quot;background-color: white; overflow: auto;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;viewdata &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;products&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;=&quot;IEnumerable[[Product]]&quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;ul &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;=&quot;products.Any()&quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
  &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;li &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;=&quot;var p in products&quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;${p.Name}&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;ul&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
  &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;No products available&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;If your eye skipped over it because it looks just like html I wouldn’t blame you. But look again. Loops and conditions are nicely embedded in html. Spark really does let the html dominate (which can be a good thing). These are but a few of all the nice features. If you have them, spend a couple of minutes browsing the spark documentation to learn what’s more.&lt;/p&gt;
&lt;p&gt;To learn a bit about the inner workings of this wonderful tool I set out to add WebForms support. The spark codebase has a very testable design and can be coerced to help out in a WebForms control without modification. The end result look like this:&lt;/p&gt;
&lt;div id=&quot;scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:de3d5118-8694-4023-b244-a9e960e955d9&quot; class=&quot;wlWriterEditableSmartContent&quot; style=&quot;margin: 0px; display: inline; float: none; padding: 0px;&quot;&gt;
&lt;pre style=&quot;background-color: #ffffff; overflow: auto;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;spark:View &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;runat&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;=&quot;server&quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
  &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;ul &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;=&quot;Container.GetProducts().Any()&quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;li &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;=&quot;var p in Container.GetProducts()&quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;${p.Name}&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
  &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;ul&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
  &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;No products available&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
  &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;spark:View&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;Download and usage&lt;/h2&gt;
&lt;p&gt;To use it download&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div id=&quot;scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:42a48c15-202d-4920-965f-60ea171b6608&quot; class=&quot;wlWriterEditableSmartContent&quot; style=&quot;margin: 0px; display: inline; float: none; padding: 0px;&quot;&gt;&lt;a href=&quot;/link/a5f83d078b7946568209cf2090864a7a.zip&quot;&gt;Spark.Web.Forms.zip&lt;/a&gt;&amp;nbsp;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and unzip into your bin folder.&lt;/p&gt;
&lt;p&gt;Register the control in web.config:&lt;/p&gt;
&lt;div id=&quot;scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:e6d426a0-855a-4715-ba9f-e4ffb39770e0&quot; class=&quot;wlWriterEditableSmartContent&quot; style=&quot;margin: 0px; display: inline; float: none; padding: 0px;&quot;&gt;
&lt;pre style=&quot;background-color: #ffffff; overflow: auto;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;pages&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
  &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;controls&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;add &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;tagPrefix&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;=&quot;spark&quot;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; namespace&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;=&quot;Spark.Web.Forms&quot;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt; assembly&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;=&quot;Spark.Web.Forms&quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;Add something useful to iterate over to your page or user control:&lt;/p&gt;
&lt;div id=&quot;scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:a2429eab-ed32-4483-8361-6f62080f3df1&quot; class=&quot;wlWriterEditableSmartContent&quot; style=&quot;margin: 0px; display: inline; float: none; padding: 0px;&quot;&gt;
&lt;pre style=&quot;background-color: #ffffff; overflow: auto;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[] Values;
&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;protected&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; Page_Load(&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;object&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; sender, EventArgs e)
{
  Values &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[] { &lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;Simple&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;As&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;Pancake&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; };
}
&lt;/span&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;And add the spark control:&lt;/p&gt;
&lt;div id=&quot;scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:9023e169-c2c0-4959-91f1-ca72fa8d6ea8&quot; class=&quot;wlWriterEditableSmartContent&quot; style=&quot;margin: 0px; display: inline; float: none; padding: 0px;&quot;&gt;
&lt;pre style=&quot;background-color: #ffffff; overflow: auto;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;spark:View &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;runat&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;=&quot;server&quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
  &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;ul&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
    &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;li &lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;each&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;=&quot;var c in Page.Values&quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;${c}&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
  &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;ul&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;
&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;spark:View&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn&#39;s Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;h2&gt;Future&amp;nbsp;improvement ideas&lt;/h2&gt;
&lt;p&gt;Some features are definitely missing (and they might require modification of the spark code itself):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Spool content from a spark view controls placed later in the control tree&lt;/li&gt;
&lt;li&gt;Cache the compiled views&lt;/li&gt;
&lt;li&gt;Support the spark cache element&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;a href=&quot;http://github.com/libardo/spark&quot;&gt;code&lt;/a&gt; is over here.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/11/Spark-View-Engine-on-WebForms/</guid>            <pubDate>Tue, 16 Nov 2010 21:39:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>Testing templates without creating a page using TemplateMock</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/9/Testing-templates-without-creating-a-page-using-TemplateMock/</link>            <description>&lt;p&gt;Sometimes it’s useful to test your code before committing it. When possible unit tests make for a nice way to do this. Template code, however, is not always the most easy to test as a unit. This is when a UI testing framework such as &lt;a href=&quot;http://seleniumhq.org/&quot;&gt;Selenium&lt;/a&gt; can come in handy. Unfortunately creating the pages to test can be a bit cumbersome and this is where &lt;strong&gt;TemplateMock&lt;/strong&gt; helps out.&lt;/p&gt;  &lt;h2&gt;Usage&lt;/h2&gt;  &lt;p&gt;TemplateMock allows you to access a page type without creating it in edit mode from a known URL. After adding templateMock to your site you can render a standard page using an alternative url:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;/link/33d90f70db0f4b97b057712060e8153a.png&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;/link/20a27df7d37246bb84f19e794d2c4a89.png&quot; width=&quot;244&quot; height=&quot;198&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;em&gt;/TemplateMock.ashx?scenario=[Public]+Standard+page&lt;/em&gt;&lt;/p&gt;  &lt;h2&gt;Configuration&lt;/h2&gt;  &lt;p&gt;When navigating to TemplateMock without query parameters you can choose which template to execute:&lt;/p&gt;  &lt;p&gt;&lt;a href=&quot;/link/c838543cf56f485a806c7fa435e7940e.png&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;/link/cd0a6027c1134271bc478b496d818639.png&quot; width=&quot;210&quot; height=&quot;244&quot; /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Optionally you can add query parameters to configure it:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;randomize&lt;/strong&gt; (true/false): Wheter the content on the page is deterministic (doesn’t change every time)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;numberOfChildren&lt;/strong&gt; (0-n): How many children this page appears to have&lt;/p&gt;  &lt;p&gt;For example “&lt;em&gt;/TemplateMock.ashx?scenario=[Public]+Standard+page&amp;amp;randomize=false&amp;amp;numberOfChildren=100&lt;/em&gt;” will render a standard page with 100 child pages without randomizing it’s content.&lt;/p&gt;  &lt;p&gt;It’s also possible to tweak other aspects from code. This is left as an excercise to the reader.&lt;/p&gt;  &lt;h2&gt;Download &amp;amp; installation&lt;/h2&gt;  &lt;p&gt;Be aware that TemplateMock broadcasts unsupported pirate signals to hack into the CMS core and should never be used in production. &lt;/p&gt;  &lt;p&gt;   &lt;/p&gt;&lt;div style=&quot;padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px&quot; id=&quot;scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:c83719e7-4b96-453b-8423-95071bd0f5d5&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;&lt;p&gt; &lt;a href=&quot;/link/434ca82eadd440639f9430cf3d3739c5.zip&quot;&gt;TemplateMock.zip&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;   &lt;p&gt;To install it just unzip in your site’s root directory and navigate to TemplateMock.ashx.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/9/Testing-templates-without-creating-a-page-using-TemplateMock/</guid>            <pubDate>Thu, 23 Sep 2010 17:02:42 GMT</pubDate>           <category>Blog post</category></item><item> <title>Don’t even try using MVC2 on CMS6</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/9/Dont-even-try-using-MVC2-on-CMS6/</link>            <description>&lt;p&gt;...yet. Unfortunately it’s not possible to use ASP.NET MVC 2 on CMS6 (without running into a lot of trouble). The reason is that parts of EPiServer uses MVC1 and there are breaking changes between MVC1 and MVC2 preventing a simple assembly redirect.&lt;/p&gt;
&lt;h2&gt;The offending changes&lt;/h2&gt;
&lt;p&gt;The particlar changes that cause problems in this case are these:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Http GET and return Json needs to be explicitly allowed in code return Json(…, JsonRequestBehavior.AllowGet);&lt;/li&gt;
&lt;li&gt;Change of return type to MvcHtmlString on html helpers&lt;/li&gt;
&lt;li&gt;Async controllers feature introduces a new way of calling the controller factory&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Future upgrades of ASP.MVC&lt;/h2&gt;
&lt;p&gt;Now, if you’re using MVC1 please be aware that we’re planning to update ASP.NET MVC to version 2 and that you might be affected by changes above, or any of &lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?FamilyID=c9ba1fe1-3ba8-439a-9e21-def90a8615a9&amp;amp;displaylang=en&quot;&gt;the other changes described in the ASP.NET MVC 2 RTM release notes&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I’ve heard several requests to use MVC the second. If you feel this upgrade might be a problem don’t hesitate to add your comment below.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/9/Dont-even-try-using-MVC2-on-CMS6/</guid>            <pubDate>Wed, 08 Sep 2010 16:52:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>Shell Playground</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/3/Shell-Playground/</link>            <description>&lt;p&gt;Sometimes it’s okay to have fun. A while back we had fun trying things in OnlineCenter and the result is the Playground. For designers this is a catalog of styles available on the dashboard. For developers it’s an insight into the OnlineCenter API.&lt;/p&gt;
&lt;h2&gt;In the playground project you will find examples of…&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;/link/2f56dca54c0f44ce9b91fa92d4be449a.png&quot;&gt;&lt;img style=&quot;BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px&quot; title=&quot;Elements&quot; border=&quot;0&quot; alt=&quot;Elements&quot; src=&quot;/link/a388022493344a50a0dae7b05c1349a6.png&quot; width=&quot;244&quot; height=&quot;137&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;…CSS classes and element styles&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href=&quot;/link/9ce77ee799ca4d9a949dace814227787.png&quot;&gt;&lt;img style=&quot;BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px&quot; title=&quot;FormAjax&quot; border=&quot;0&quot; alt=&quot;FormAjax&quot; src=&quot;/link/1ef8d2ccea874f49b4bdd7ad90bb2be2.png&quot; width=&quot;244&quot; height=&quot;164&quot; /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;em&gt;…server side ajax helpers&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/31e09616e36743bcafa669a34869f649.png&quot;&gt;&lt;img style=&quot;BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px&quot; title=&quot;FormElements&quot; border=&quot;0&quot; alt=&quot;FormElements&quot; src=&quot;/link/236f16ffcf5b473bad17c0e7192cdfb9.png&quot; width=&quot;244&quot; height=&quot;198&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;…form element styles&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href=&quot;/link/0dd337f186c44d4b94117297bc02a160.png&quot;&gt;&lt;img style=&quot;BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px&quot; title=&quot;JsonTemplate&quot; border=&quot;0&quot; alt=&quot;JsonTemplate&quot; src=&quot;/link/13f24ae0f6414068a99b4344cac013b3.png&quot; width=&quot;234&quot; height=&quot;134&quot; /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;em&gt;…an example using jTemplates and json&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/9c9ab4ba8c4f4932a045a6e101054f5a.png&quot;&gt;&lt;img style=&quot;BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px&quot; title=&quot;ViewFail&quot; border=&quot;0&quot; alt=&quot;ViewFail&quot; src=&quot;/link/fe65ccf746c649c9a491100b8766d962.png&quot; width=&quot;244&quot; height=&quot;61&quot; /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;em&gt;…how we deal with errors&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/06da930f72724824af50ea27994b7567.png&quot;&gt;&lt;img style=&quot;BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px&quot; title=&quot;Navigation&quot; border=&quot;0&quot; alt=&quot;Navigation&quot; src=&quot;/link/63402d7b02e14bc7968c3da6ad307615.png&quot; width=&quot;244&quot; height=&quot;119&quot; /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;em&gt;…adding interfaces to the menu system&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/8a4a80a4a2914b49bb672b03b14ef748.png&quot;&gt;&lt;img style=&quot;BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px&quot; title=&quot;SearchProviders&quot; border=&quot;0&quot; alt=&quot;SearchProviders&quot; src=&quot;/link/a1e9fd08a2344e6a8f0a1e6542004015.png&quot; width=&quot;244&quot; height=&quot;126&quot; /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;em&gt;…the AppDomain search provider&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As well as a few other things. Keep in mind that this isn&#39;t best practice. It&#39;s just code.&lt;/p&gt;
&lt;h2&gt;Download&lt;/h2&gt;

&lt;div style=&quot;PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px&quot; id=&quot;scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:21f9d2ca-dd39-43f3-b814-5f7c9f8d8152&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;
&lt;p&gt;&lt;a href=&quot;/link/b70856224c5a45f7864d30e6460f0d4c.zip&quot;&gt;And finally, the actual download&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;To try this out you will need to build and &lt;a href=&quot;http://world.episerver.com/Documentation/Items/Tech-Notes/EPiServer-CMS-6/EPiServer-CMS-60/OnlineCenter-Developer-Documentation/#ShellModules&quot;&gt;configure&lt;/a&gt; the project in web.config.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/3/Shell-Playground/</guid>            <pubDate>Thu, 25 Mar 2010 10:37:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>Legacy redirect in CMS 6</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/3/Legacy-redirect-in-CMS-6/</link>            <description>&lt;p&gt;Fredrik wrote a very interesting and informative &lt;a href=&quot;http://blog.fredrikhaglund.se/blog/2010/03/10/configuration-management-and-episerver-cms-6/&quot;&gt;post&lt;/a&gt; about changes to the configuration files.&amp;nbsp;The post&amp;nbsp;also brings a whole new meaning to the term configuration management.&lt;/p&gt;
&lt;p&gt;An issue brounght up are changes of the URL to the edit and admin interfaces which causes existing bookmarks to break. This can be fixed using the downloads below. The module redirects requests to files that exist in edit/admin from the old to the new path. &lt;/p&gt;
&lt;p&gt;We decided to pull this from the release since we didn’t have time to fully analyze the consequences of including it. There are two different downloads due to breaking changes to the initialization between RC and RTM.&lt;/p&gt;
&lt;div style=&quot;PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px&quot; id=&quot;scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:6639ad9f-0d44-42a7-bb98-9745cdab8ea3&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;
&lt;p&gt;&lt;a href=&quot;/link/db104daa1e404afe8478990e7e9ff9bf.zip&quot;&gt;Download EPiServer.LegacyRedirect for CMS 6 RC&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div style=&quot;PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px&quot; id=&quot;scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:60f367e4-09df-4c84-9b99-36d197e05a3b&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;
&lt;p&gt;&lt;a href=&quot;/link/cfd34d9613a44d8695ab78e90eb652cf.zip&quot;&gt;Download EPiServer.LegacyRedirect for CMS 6 RTM (not yet released at the time of writing)&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/3/Legacy-redirect-in-CMS-6/</guid>            <pubDate>Tue, 16 Mar 2010 13:23:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>What and why is epiJQuery?</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/2/What-and-why-is-epiJQuery/</link>            <description>&lt;p&gt;A feature in EPiServer CMS 6 that might catch your eye is a dashboard. An interesting technical aspect of it is that it’s largely a client based solution. As such anyone planning to do their magic on it might have the good fortune to enter the wonderful world of client side scripting (but you can do a lot of things server only if you prefer that).&lt;/p&gt;
&lt;p&gt;So, what is epiJQuery? It’s jQuery 1.3.2, with one tiny addtition:&lt;/p&gt;&lt;pre&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;window&lt;/span&gt;.epiJQuery = jQuery;&lt;/pre&gt;
&lt;p&gt;Why is this useful? Consider this seemingly innocuous line anyone could add to the dashboard at any time.&lt;/p&gt;&lt;pre&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;script&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;type&lt;/span&gt;=&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&quot;text/javascript&quot;&lt;/span&gt; &lt;span style=&quot;COLOR: #ff0000&quot;&gt;src&lt;/span&gt;=&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js&quot;&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;COLOR: #800000&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;COLOR: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The additional variable epiJQuery ensure that any scripts running after the script include above will find the same jquery version and plugins as the ones running before the script include.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/2/What-and-why-is-epiJQuery/</guid>            <pubDate>Fri, 12 Feb 2010 17:14:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>Quick intro to ASP.NET MVC for the WebForm developer</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/1/Quick-intro-to-ASPNET-MVC-for-the-WebForm-developer/</link>            <description>&lt;p&gt;To prepare for future discussions around dashboard gadgets I thought it was a good idea to introduce the ASP.NET MVC framework. &lt;/p&gt;  &lt;p&gt;The main buidling blocks of the ASP.NET MVC framework is routing, controllers, views and the model support. There are also multiple hooks in and around these blocks to bend the behaviour to your wim. &lt;/p&gt;  &lt;h2&gt;Routes &lt;/h2&gt;  &lt;p&gt;Routes are registered to handle an incoming URL pattern and map it to your code along with parameters, and back from parameters to an URL.&amp;#160; A route registration typically is a piece of code in Application_Start that may look like this: &lt;/p&gt;  &lt;pre&gt;routes.MapRoute(
  &amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;Default&lt;/span&gt;&amp;quot;, &lt;span style=&quot;color: #008000&quot;&gt;// Route name&lt;/span&gt;
  &amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;{controller}/{action}/{id}&lt;/span&gt;&amp;quot;,&lt;span style=&quot;color: #008000&quot;&gt;// URL pattern with parameters&lt;/span&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;  new&lt;/span&gt; { controller = &amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;Home&lt;/span&gt;&amp;quot;, action = &amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;Index&lt;/span&gt;&amp;quot;, id = &amp;quot;&amp;quot; } &lt;span style=&quot;color: #008000&quot;&gt;// Defaults parameters&lt;/span&gt;
); &lt;/pre&gt;

&lt;p&gt;This will register a route that accepts anything from 0 to 3 segments and matches each segments to the corresponding parameter or the default. &lt;/p&gt;

&lt;p&gt;E.g. URL = &amp;quot;/hello/world/1&amp;quot; is matched to controller = &amp;quot;hello&amp;quot;, action = &amp;quot;world&amp;quot; and id = &amp;quot;1&amp;quot;&lt;/p&gt;

&lt;p&gt;The default parameters mean that the URL = &amp;quot;/&amp;quot; would be matched to controller = &amp;quot;Home&amp;quot;, action = &amp;quot;Index&amp;quot; and id = &amp;quot;&amp;quot; &lt;/p&gt;

&lt;p&gt;Such routes can be configured to handle a lot of scenarios and more. Keep in mind that routes are organized in a table which is evaluated from fist to last, the first to match is used. &lt;/p&gt;

&lt;h2&gt;Controllers&lt;/h2&gt;

&lt;p&gt;This is the handler for a piece of functionality. By way of routing a method is invoked in which you decide what action to take. The action may be rendering one view or another, redirecting to somewhere else, or returning a JSON string that is easily interpreted on the client. &lt;/p&gt;

&lt;p&gt;A controller may look like this: &lt;/p&gt;

&lt;pre&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;class&lt;/span&gt; HomeController : Controller
{&lt;br /&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;  public&lt;/span&gt; ActionResult Index()
  {
&lt;span style=&quot;color: #0000ff&quot;&gt;    return&lt;/span&gt; View();
  }
} &lt;/pre&gt;

&lt;p&gt;This is a controller that given the route above responds to everything from &amp;quot;/&amp;quot; to &amp;quot;/home/index/whatever&amp;quot;. An interesting aspect of route parameters that they are used to call the action method, e.g.: &lt;/p&gt;

&lt;pre&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;public&lt;/span&gt; ActionResult Index(&lt;span style=&quot;color: #0000ff&quot;&gt;int&lt;/span&gt; id)
{
&lt;span style=&quot;color: #0000ff&quot;&gt;  return&lt;/span&gt; View();
} &lt;/pre&gt;

&lt;p&gt;This will convert the {id} parameters into an integer or throw an exception if this isn&#39;t possible. Also the query string, and form values are also fitted into the method arguments when possible. The view model may be any kind class (e.g. a list of persons or an address object) and it&#39;s used on the view to render HTML. Very worth mentioninng is that the controller logic is (unit) testable. &lt;/p&gt;

&lt;h2&gt;Views &lt;/h2&gt;

&lt;p&gt;By default views are ASPX pages inheriting from a base class that provides useful properties. Rather than using the control hierarchy and the page lifecycle to construct the interface plain html and extension methods (html helpers) are preferred. A fundamental difference is that controls needn&#39;t reconstruct their state on postback. Instead, plain old HTTP POST/GETs target a controller action and posted data doesn&#39;t pass through a server control. &lt;/p&gt;

&lt;p&gt;E.g. WebForms: 
  &lt;br /&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #c71585&quot;&gt;asp&lt;/span&gt;:&lt;span style=&quot;color: #800000&quot;&gt;TextBox&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;ID&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;Name&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;runat&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;/&amp;gt;&lt;/span&gt; &lt;/p&gt;

&lt;p&gt;MVC: 
  &lt;br /&gt;&lt;span style=&quot;background-color: #ffff00; color: black&quot;&gt;&amp;lt;%&lt;/span&gt;= Html.TextBox(&amp;quot;Name&amp;quot;) &lt;span style=&quot;background-color: #ffff00; color: black&quot;&gt;%&amp;gt;&lt;/span&gt; &lt;/p&gt;

&lt;p&gt;One of the appealing aspects of this model is that AJAX interaction becomes very easy as the HTML can live on the client and interact with a controller without the need to keep the server control model up to date.&lt;/p&gt;

&lt;h2&gt;Model&lt;/h2&gt;

&lt;p&gt;The model are simply classes that reflect the problem the application tries to solve. These classes can be used and tested separately from the presentation. ASP.NET MVC doesn&#39;t propose any particular database tooling. Most of the time you would use an O/R mapper to get a class instance, update it and pass it along to a view. What the framework will do is to give a lot of support in updating, and working with any class within controllers and views. &lt;/p&gt;

&lt;p&gt;E.g. consider the following actions: &lt;/p&gt;

&lt;pre&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;public&lt;/span&gt; ActionResult Index()
{
&lt;span style=&quot;color: #0000ff&quot;&gt;  return&lt;/span&gt; View(&lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; Person { Name = &amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;Fill me up scotty&lt;/span&gt;&amp;quot; });
} 
&lt;span style=&quot;color: #0000ff&quot;&gt;public&lt;/span&gt; ActionResult Update(Person person)
{
  Store.Save(person);
  View(&amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;Index&lt;/span&gt;&amp;quot;, person);
} &lt;/pre&gt;

&lt;p&gt;And this view code: &lt;/p&gt;

&lt;pre&gt;&lt;span style=&quot;background-color: #ffff00; color: black&quot;&gt;&amp;lt;%&lt;/span&gt; using(Html.BeginForm(&amp;quot;Update&amp;quot;, &amp;quot;Home&amp;quot;)) { &lt;span style=&quot;background-color: #ffff00; color: black&quot;&gt;%&amp;gt;&lt;/span&gt;
&lt;span style=&quot;background-color: #ffff00; color: black&quot;&gt;&lt;br /&gt;&lt;/span&gt;  &lt;span style=&quot;background-color: #ffff00; color: black&quot;&gt;&amp;lt;%&lt;/span&gt;= Html.TextBox(&amp;quot;Name&amp;quot;) &lt;span style=&quot;background-color: #ffff00; color: black&quot;&gt;%&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #0000ff&quot;&gt;&lt;br /&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;input&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;type&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;submit&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;background-color: #ffff00; color: black&quot;&gt;&amp;lt;%&lt;/span&gt; } &lt;span style=&quot;background-color: #ffff00; color: black&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;Not only will the MVC framework popuplate the input box with the name of the person. It will also repopuplate a person object in the Update method when the form is posted. Other nice features include validation support, the possibility to post to any action on any controller and an abundance of options that might better fit your fancy. &lt;/p&gt;

&lt;h2&gt;Summary and some pitfalls&lt;/h2&gt;

&lt;p&gt;As you may have noticed this model brings you much closer to the web. While MVC does a lot of handholding a web application developer is faced with other responsibilities and options. Anyone without a strong investment in web forms will probably find themselves at home.&lt;/p&gt;

&lt;p&gt;A controller doesn’t have a specific URL. This is the concern of a route.&lt;/p&gt;

&lt;p&gt;The web control developer entering this world will probably start looking for new forms of code reuse.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/1/Quick-intro-to-ASPNET-MVC-for-the-WebForm-developer/</guid>            <pubDate>Tue, 19 Jan 2010 14:25:32 GMT</pubDate>           <category>Blog post</category></item><item> <title>Enabling gadget development quickly</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/1/Enabling-gadget-development-quickly/</link>            <description>&lt;p&gt;Preparing your project for gadget development is as simple as tweaking a few xml files. In fact, it’s so easy even a machine can do it if you download and execute the following file through Deployment Center:&lt;/p&gt;
&lt;div style=&quot;PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px&quot; id=&quot;scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:2a2d5965-ab44-4b15-9018-78cd335a3f46&quot; class=&quot;wlWriterEditableSmartContent&quot;&gt;
&lt;p&gt;&lt;a href=&quot;/link/72b9e3cda3a24e409f6e949c84a349e9.epimodule&quot;&gt;Add MVC Gadgets to PublicTemplates.epimodule&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;What does it this do?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1. It alters PublicTemplates.csproj: &lt;br /&gt;* Adds references to System.Web.Mvc.dll and EPiServer.Shell.dll (these contain classes you need doing gadgets) &lt;br /&gt;* Adds the ASP.NET MVC project type guid (this enables the Visual Studio tooling) &lt;br /&gt;* Alters the project to include gadget example&lt;/p&gt;
&lt;p&gt;2. It copies a simple gadget example to the project folder.&lt;/p&gt;
&lt;p&gt;3. It modifies web.config registering EPiServer.Templates.Public as a public module.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What doesn’t it do?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It doesn’t install &lt;a href=&quot;http://www.asp.net/mvc/download/&quot;&gt;ASP.NET MVC&lt;/a&gt; (this needs to be installed separately)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What if something goes wrong?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Squeak here below and I’ll try to help.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where can I get it?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/72b9e3cda3a24e409f6e949c84a349e9.epimodule&quot;&gt;Here (download)&lt;/a&gt;&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2010/1/Enabling-gadget-development-quickly/</guid>            <pubDate>Mon, 18 Jan 2010 15:07:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>Breaking changes between EPIServer 6 CTP2 and Release Candidate</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2009/12/Breaking-changes-between-EPIServer-6-CTP2-and-Release-Candidate/</link>            <description>&lt;p&gt;Rather than enumerating every change between preview 2 and the release candidate we downloaded a few of the winning gadgets and made the required changes to make them work on the RC version. &lt;/p&gt;
&lt;p&gt;This is the list of changes. Please feel invited to share any other breaking change that isn&#39;t listed here.&lt;/p&gt;
&lt;h2&gt;1. On the client, the gadget instance is passed directly instead of gadgetContext which has been removed&lt;/h2&gt;&lt;code&gt;// from&lt;br /&gt;function fcsm_initialize(e, gadgetContext) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fcsm_gadgetInstance = gadgetContext.instance;&lt;br /&gt;// to&lt;br /&gt;function fcsm_initialize(e, gadget) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fcsm_gadgetInstance = gadget;&lt;/code&gt; 
&lt;h2&gt;2. The extensions in Shell Extensions now lives somewhere else&lt;/h2&gt;&lt;code&gt;// from&lt;br /&gt;&amp;lt;%@ Import Namespace=&quot;EPiServer.Shell.Extensions&quot; %&amp;gt;&lt;br /&gt;// to&lt;br /&gt;&amp;lt;%@ Import Namespace=&quot;EPiServer.Shell.Web.Mvc.Html&quot; %&amp;gt;&lt;/code&gt; 
&lt;h2&gt;3. The dynamic data store has gained a factory&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;// from&lt;br /&gt;DynamicDataStore&amp;lt;ReportSettings&amp;gt; store =&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DynamicDataStore&amp;lt;ReportSettings&amp;gt;.CreateStore(&quot;AnalyticsGadgetStore&quot;, false);&lt;br /&gt;// to&lt;br /&gt;DynamicDataStore store = &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DynamicDataStoreFactory.Instance.GetStore(&quot;AnalyticsGadgetStore&quot;) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ?? DynamicDataStoreFactory.Instance.CreateStore(&quot;AnalyticsGadgetStore&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; typeof(ReportSettings));&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;4. The dynamic data store “Find” has changed&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;// from&lt;br /&gt;store.Find(&quot;GadgetId&quot;, gadgetId).FirstOrDefault&amp;lt;ReportSettings&amp;gt;();&lt;br /&gt;// to&lt;br /&gt;store.Find&amp;lt;ReportSettings&amp;gt;(&quot;GadgetId&quot;, gadgetId).FirstOrDefault();&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;5. The dynamic data store LINQ has changed&lt;/h2&gt;&lt;code&gt;// from&lt;br /&gt;from alertCollection in store&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where …&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select alertCollection;&lt;br /&gt;// to&lt;br /&gt;from alertCollection in store.Items&amp;lt;AlertMethodCollection&amp;gt;()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where …&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select alertCollection&lt;/code&gt; 
&lt;h2&gt;6. The gadget contracts namespace has moved&lt;br /&gt;&lt;/h2&gt;&lt;code&gt;// from&lt;br /&gt;using EPiServer.Shell.Gadgets.Contracts;&lt;br /&gt;// to&lt;br /&gt;using EPiServer.Shell.Gadgets;&lt;/code&gt; 
&lt;h2&gt;7. Some resource texts have been moved&lt;br /&gt;&lt;/h2&gt;&lt;code&gt;// from&lt;br /&gt;[GadgetAction(ActionType.Menu, TextResourceKey = &quot;Edit&quot;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ResourceType = typeof(EPiServer.Shell.UI.Views.Shared.SharedResources))]&lt;br /&gt;// to&lt;br /&gt;[GadgetAction(TextResourceKey = &quot;Edit&quot;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ResourceType = typeof(EPiServer.Shell.Resources.Texts))]&amp;nbsp;&lt;/code&gt;
&lt;h2&gt;8. The configuration has changed to reflect that we now split modules by protected and public (added december 30)&lt;/h2&gt;&lt;code&gt;// from&lt;br /&gt;&amp;lt;episerver.shell&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;siteSettings rootPath=&quot;~/U/&quot; /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;modules autoDiscovery=&quot;Minimal&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name=&quot;DdsExplorer&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;assemblies&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add assembly=&quot;DdsExplorer&quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/assemblies&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/add&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/modules&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;frameworkModules&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name=&quot;Shell&quot;&amp;gt;...&amp;lt;/add&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name=&quot;CMS&quot;&amp;gt;...&amp;lt;/add&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/frameworkModules&amp;gt;&lt;br /&gt;&amp;lt;/episerver.shell&amp;gt;&lt;/code&gt;&lt;code&gt;// to&lt;br /&gt;&amp;lt;episerver.shell&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;protectedModules rootPath=&quot;~/U/&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name=&quot;Shell&quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name=&quot;CMS&quot; /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/protectedModules&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;publicModules rootPath=&quot;~/public/&quot; autoDiscovery=&quot;Minimal&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add name=&quot;DdsExplorer&quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;assemblies&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add assembly=&quot;DdsExplorer&quot; /&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/assemblies&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/add&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/publicModules&amp;gt;&lt;br /&gt;&amp;lt;/episerver.shell&amp;gt;&lt;/code&gt;
&lt;h2&gt;9. Some style classes have a different name (added december 30)&lt;/h2&gt;&lt;code&gt;//from&lt;br /&gt;&amp;lt;div class=&quot;epi-defaultPadding&quot;&amp;gt;&lt;br /&gt;&amp;lt;div class=&quot;epi-smallPadding&quot;&amp;gt;&lt;/code&gt;&lt;code&gt;//to&lt;br /&gt;&amp;lt;div class=&quot;epi-padding&quot;&amp;gt;&lt;br /&gt;&amp;lt;div class=&quot;epi-padding-small&quot;&amp;gt;&lt;/code&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I also took the liberty of uploading the changes&amp;nbsp;to codeplex. I take no responsibility&amp;nbsp;for the quality of any gadget or any introduced errors. All&amp;nbsp;credits goes to the original author. These are the gadgets that were updated:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://episervergadgets.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=37873&quot;&gt;Google Analytics Gadget&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://episervergadgets.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=37874&quot;&gt;Automated Web Testing Gadget&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://episervergadgets.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=37876&quot;&gt;Social Media Gadget&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://episervergadgets.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=37877&quot;&gt;System Monitor Gadget&amp;nbsp;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://episervergadgets.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=37878&quot;&gt;Test Site Gadget&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Let me know right away if a gadget needs to be removed or if you need access to change a release.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2009/12/Breaking-changes-between-EPIServer-6-CTP2-and-Release-Candidate/</guid>            <pubDate>Mon, 28 Dec 2009 17:26:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>Exploring the data lair</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2009/11/Exploring-the-data-lair/</link>            <description>&lt;p&gt;Arm yourself with the DDS Explorer and venture into the dark bowels of your EPiServer CMS 6 site.&lt;/p&gt;
&lt;p&gt;Find what stores there are.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;/link/ea8414801dd34aeba1f85b1f5f5a7c58.PNG&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Learn the kinds and sizes of shelves in the store&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;/link/f19b86e314a14189bcd4f95f6e3e0a26.PNG&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Take a peek at what lies in store for you.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;/link/6e826acaac0945798f76dca34da8bf24.PNG&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And change it!&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;/link/10c5685aef6d48c4a84ee55b50f9e988.PNG&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://episervergadgets.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=36207&quot;&gt;Download DDS Explorer&lt;/a&gt;&amp;nbsp;(Take care not to do anything nasty with this)&lt;/p&gt;
&lt;h3&gt;In summary&lt;/h3&gt;
&lt;p&gt;The dynamic data store is a great new feature. The setup cost is almost zero and using it is so easy you almost forget you&#39;re using a database. The (almost) fixed schema operation also promises a nice deployment scenario.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2009/11/Exploring-the-data-lair/</guid>            <pubDate>Sat, 21 Nov 2009 10:55:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>Tic Tac Gadget</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2009/11/Tic-Tac-Gadget/</link>            <description>&lt;p&gt;This is totally cool gadget. Who can resist a multi (well 2) player game? &lt;/p&gt;
&lt;p&gt;It&#39;s also totally useful. Instead of procrastinating web editors, business owners and developers alike can spend hours competing among themselves on the dashboard. On a 1 to 10 scale the business value of this gadget is negative. &lt;/p&gt;
&lt;p&gt;The technical quality is totally over the top. The gadget features the most snazzy silverlight interface imaginable (you know, rich internet applications) and a super-cool duplex WCF service connection for instant feedback and the quickiest of games. &lt;/p&gt;
&lt;p&gt;To make things even better it&#39;s all totally open. The code is completely exposed&lt;strike&gt; in the most embarassing of ways&lt;/strike&gt; over at &lt;a href=&quot;http://episervergadgets.codeplex.com/SourceControl/ListDownloadableCommits.aspx&quot;&gt;codeplex&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Obviously, the gadget is totally in time for the market. A gadget is never late, nor is it early, it arrives exactly when it was meant to. &lt;/p&gt;
&lt;p&gt;You will find the &lt;a href=&quot;http://episervergadgets.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=35621&quot;&gt;&lt;strong&gt;download&lt;/strong&gt;&lt;/a&gt; along with installation instructions over &lt;a href=&quot;http://episervergadgets.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=35621&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Happy playing!&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2009/11/Tic-Tac-Gadget/</guid>            <pubDate>Sun, 08 Nov 2009 18:48:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>CTP2 gazing upon the world</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2009/10/CTP2-gazing-upon-the-world/</link>            <description>&lt;p&gt;Not yet a day old CTP2 gazes upon the world with misty eyes.&lt;/p&gt;
&lt;p&gt;Looking upon herself she sees a &lt;a href=&quot;http://world.episerver.com/Articles/Items/EPiServer-CMS-6-CTP-2-is-here/&quot;&gt;new shiny surface&lt;/a&gt; on top, and &lt;a href=&quot;http://world.episerver.com/Blogs/Paul-Smith/Dates1/2009/10/Introducing-The-Dynamic-Data-Store/&quot;&gt;things underneath&lt;/a&gt;&amp;nbsp;that will bring her far.&lt;/p&gt;
&lt;p&gt;She soon discovers that she can be &lt;a href=&quot;http://labs.dropit.se/blogs/post/2009/10/19/EPiServer-Site-Center-Gadgets-MVC-oh-mye280a6.aspx&quot;&gt;beautified&lt;/a&gt; with the help from others and already &lt;a href=&quot;http://tednyberg.com/post/How-to-create-gadgets-for-EPiServer-6-using-ASPNET-MVC.aspx&quot;&gt;some&lt;/a&gt; and &lt;a href=&quot;http://world.episerver.com/Documentation/Items/Tech-Notes/EPiServer-CMS-6/EPiServer-CMS-6-CTP2/Introduction-to-gadgets/&quot;&gt;others&lt;/a&gt; have written tales about it. &lt;/p&gt;
&lt;p&gt;This is all very exciting and she can&#39;t wait to see what people &lt;a href=&quot;http://world.episerver.com/Download/EPiServer-CMS-6-Gadget-Contest-2009/&quot;&gt;are competing&lt;/a&gt; about.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2009/10/CTP2-gazing-upon-the-world/</guid>            <pubDate>Tue, 20 Oct 2009 10:49:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>Jumping on the page type bandwagon</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2009/7/Jumping-on-the-page-type-bandwagon/</link>            <description>&lt;p&gt;With the sun shining and the thermometer approaching body temperature I thought it was god&amp;nbsp;time to have some fun. Quick from thought to action I fired up my trusty black warrior to explore another white spot on the map.&lt;/p&gt;
&lt;p&gt;My objective for the day was to get to get aquainted with the &lt;a href=&quot;http://labs.episerver.com/en/Blogs/Joel-Abrahamsson/Dates2/2009/6/Page-Type-Builder-07---Wrapping-and-enabling-mocking-of-DataFactory/&quot;&gt;page type builder&lt;/a&gt;. One of those really neat features your manager never will understand.&lt;/p&gt;
&lt;p&gt;I was pleased from the first moment to notice that after including it in my solution and adding my page type it worked right away. It&#39;s just like magic, and I cannot but love the firm presence of a piece of text sitting in my source code repository.&lt;/p&gt;
&lt;p&gt;The natural next step was learning about the inner workings. Living on the practical side of the fence I tend to learn best by using, exploring and finding interesting aspects to change. With the using already under my belt I ventured into the exploration phase. &lt;/p&gt;
&lt;p&gt;Some mental mapping revealed some logical roles:&lt;br /&gt;&amp;nbsp;* An API to map code to episerver page types and the discovery thereof&lt;br /&gt;&amp;nbsp;* Synchronization between code and database&amp;nbsp;for page type settings and properties&lt;br /&gt;&amp;nbsp;* A data factory wrapper to access the typed pages&lt;/p&gt;
&lt;p&gt;Looking for interesting aspects to change I first took aim at the startup process. The page type builder uses a very cleverly constructed plugin attribute to trigger the build up and synchronization the page types. Beeing slightly paranoid I wanted this a bit more explicit. At the price of a tiny bit of extra code comes a cosier feeling of control.&lt;/p&gt;&lt;code&gt;&lt;pre&gt;&amp;nbsp;protected void Application_Start(Object sender, EventArgs e)&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PageTypeBuilder.Initializer.Startup(PageTypeBuilder.InitializerOptions.CallProperties);&lt;br /&gt;&amp;nbsp;}&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;The actual initializer then waits until the opportune moment (EPiServer is initialized during the first request) and then synchronizes:&lt;/p&gt;&lt;code&gt;&lt;pre&gt;&amp;nbsp;public static void Startup(InitializerOptions options)&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;EPiServer.Web.InitializationModule.FirstBeginRequest += InitializationModule_FirstBeginRequest;&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;static void InitializationModule_FirstBeginRequest(object sender, EventArgs e)&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;PageTypeBuilder.Synchronization.PageTypeBuilder.UpdatePageTypes();&lt;br /&gt;&amp;nbsp;}&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;The next change is about pushing typed page data objects into the EPiServer APIs. One particular aspect I like about the page type builder is the way it fits with the existing model. Re-tailoring for an even tighter fit I latched onto the data factory event system to push the typed pages down the stack and into EPiServer. &lt;/p&gt;&lt;code&gt;&lt;pre&gt;&amp;nbsp;public static void Startup(InitializerOptions options)&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;//...&lt;br /&gt;&amp;nbsp;&amp;nbsp;EPiServer.DataFactory.Instance.LoadedPage += DataFactoryInstance_LoadedPage;&lt;br /&gt;&amp;nbsp;}
&lt;p&gt;&amp;nbsp;static void DataFactoryInstance_LoadedPage(object sender, EPiServer.PageEventArgs e)&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;Type type = TypeResolver.GetTypeForPageType(e.Page.PageTypeID);&lt;br /&gt;&amp;nbsp;&amp;nbsp;//...&lt;br /&gt;&amp;nbsp;&amp;nbsp;e.Page = Activator.CreateAndPopulateInstance(e.Page, type);&lt;br /&gt;&amp;nbsp;}&lt;/p&gt;&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;The final and most fun change is related to the property usage. This is how strongly typed properties can be constructed:&lt;/p&gt;&lt;code&gt;&lt;pre&gt;&amp;nbsp;[PageTypeBuilder.PageTypeProperty]&lt;br /&gt;&amp;nbsp;public string SecondaryBody &lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;get { return GetPropertyValue&amp;lt;TextPage, string&amp;gt;(p =&amp;gt; p.SecondaryBody); } &lt;br /&gt;&amp;nbsp;&amp;nbsp;set { SetPropertyValue&amp;lt;TextPage, string&amp;gt;(p =&amp;gt; p.SecondaryBody, value); }&lt;br /&gt;&amp;nbsp;}&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;This approach while very pragmatic is not the most readable. The property getters and setters are responsible for using the correct property data and the lambdas provides some nice refactoring support. Inspired by one of my colleagues I decided to extend this using one of my favorite toys: DynamicProxy2. After introducing a dynamic activator the code in the page type would look like this:&lt;/p&gt;&lt;code&gt;&lt;pre&gt;&amp;nbsp;[PageTypeBuilder.PageTypeProperty]&lt;br /&gt;&amp;nbsp;public virtual string MainBody { get; set; }&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;Slightly less, isn&#39;t it? Of course the code for the activator itself is a bit longer, but not that long. Instead of creating a regular page data instance it uses DynamicProxy2 to create a special instance with a method call interceptor (it overrides and intercepts the getting and setting of properties). The interceptor then analyzes calls to the page data objects and uses GetValue/SetValue instead of calling the actual properties.&lt;/p&gt;
&lt;p&gt;Update (20 july): Krzysztof pointed out a more elegant solution using proxy generation hooks&amp;nbsp;and the code has been updated.&amp;nbsp;&lt;/p&gt;&lt;code&gt;&lt;pre&gt;    protected override TypedPageData CreateInstance(Type typedType)
    {
        (TypedPageData)generator.CreateClassProxy(typedType, options, interceptors);
    }&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;Creating the page proxy will allow for this interceptor to be called instead of the reguar property.&lt;/p&gt;&lt;code&gt;&lt;pre&gt;    internal class PageTypePropertyInterceptor : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            string propertyName = invocation.Method.GetPropertyName();
            if (invocation.Method.IsGetter())
                invocation.ReturnValue = page.GetValue(propertyName);
            else
                page.SetValue(propertyName, invocation.Arguments[0]);
        }
    }&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;The generator hook allows us to select which properties should be intercepted.&lt;/p&gt;&lt;code&gt;&lt;pre&gt;    internal class PageTypePropertiesOnlyProxyGenerationHook : IProxyGenerationHook
    {
        public bool ShouldInterceptMethod(Type type, System.Reflection.MethodInfo memberInfo)
        {
            return memberInfo.IsGetterOrSetterForPropertyWithAttribute(typeof(PageTypePropertyAttribute))
                &amp;amp;&amp;amp; memberInfo.IsCompilerGenerated();
        }
        //...
    }&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;Boy, that was fun! And educative. Hope I didn&#39;t overdo it and that some of this (thoroughly untested) experimentation can be of&amp;nbsp;any use. Oh, and here&#39;s &lt;a href=&quot;/link/c1393d281d744f24849922c5498532e2.zip&quot;&gt;the code&lt;/a&gt; in case anyone is interested.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2009/7/Jumping-on-the-page-type-bandwagon/</guid>            <pubDate>Fri, 17 Jul 2009 22:51:00 GMT</pubDate>           <category>Blog post</category></item><item> <title>Zip Installer</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2009/1/Zip-Installer/</link>            <description>&lt;p&gt;The upcoming SP1 release of EPiServer CMS R2 will be accompanied by a long lost friend. The Zip Installer. &lt;/p&gt;  &lt;p&gt;Since many of her pals have been missing her and wondered about her well-beeing we thought to invite her back to join our new home. &lt;/p&gt;  &lt;p&gt;She did change her name, along with another few things. One must wonder what she has been doing all this time. Better not ask. What matters is that she looks healthy and in good shape. &lt;/p&gt;  &lt;p&gt;Welcome back old friend.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2009/1/Zip-Installer/</guid>            <pubDate>Wed, 14 Jan 2009 17:11:35 GMT</pubDate>           <category>Blog post</category></item><item> <title>R2 and unit testing</title>            <link>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2008/10/R2-and-unit-testing/</link>            <description>&lt;p&gt;I&#39;ve been exploring the unit testing story in the latest EPiServer release and so far I&#39;ve been pleasantly surprised. R2 brings some improvements in this respect. Most of the time I can execute my tests without chatting with the database or faking the http context.&lt;/p&gt;
&lt;p&gt;The key to this is the page provider. I&#39;ll briefly cover the basics of setting up a test with a fake page provider and offer tools to help you along. &lt;/p&gt;
&lt;p&gt;Why unit test? A healthy set of unit tests has saved my butt more than a few times and if you&#39;re at least half-serious about software development you should be looking after yours. &lt;/p&gt;
&lt;h2&gt;How to do it &lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Step 0:&lt;/strong&gt; envision the business requirements &lt;/p&gt;
&lt;p&gt;&lt;em&gt;&quot;As a user I can submit a suggestion so that a support representative can review it and publish it for everyone to vote&quot;&lt;/em&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; write a test &lt;/p&gt;
&lt;p&gt;For the purpose of this example I&#39;m choosing NUnit because of the nice fluent syntax helpers. The test creates a suggestion and submits it to the suggestion box. Then we assert that the suggestion can be retrieved.&lt;/p&gt;
&lt;p&gt;&lt;font size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [TestFixture] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class SubmittingSuggestions &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Test] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void WhenSuggestionIsMade_ItsAddedToTheBacklog() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SuggestionBox box = new SuggestionBox(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Suggestion original = new Suggestion(&quot;Make it stop&quot;, &quot;I see no end to the possibilities&quot;); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; box.Submit(original); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Suggestion retrieved = box.Dequeue(); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.That(retrieved.Title, Is.EqualTo(original.Title)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.That(retrieved.Body, Is.EqualTo(original.Body)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; make it pass &lt;/p&gt;
&lt;p&gt;A simple suggestion box implementation:&lt;/p&gt;
&lt;p&gt;&lt;font size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class Suggestion &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Suggestion(string questionTitle, string questionBody) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Title = questionTitle; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Body = questionBody; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string Title { get; set; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string Body { get; set; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class SuggestionBox &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Queue&amp;lt;Suggestion&amp;gt; questions = new Queue&amp;lt;Suggestion&amp;gt;(); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Submit(Suggestion suggestion) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; questions.Enqueue(suggestion); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Suggestion Dequeue() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return questions.Dequeue(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;: refactor &lt;/p&gt;
&lt;p&gt;The test passes but it&#39;s not a terribly permanent way to store our suggestions. For the purpose of a real application this is just a fancy way of creating heat. We need to go back to the test and think again. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;: think again&lt;/p&gt;
&lt;p&gt;We change the test to assume we store the questions as a page in an episerverp age container. Doing so is nice since it allows the support representative to review and publish the suggestion from within the edit interface. &lt;/p&gt;
&lt;p&gt;&lt;font size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private PageReference boxLink; &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [SetUp] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void SetUp() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PageData box = DataFactory.Instance.GetDefaultPageData(PageReference.StartPage, SuggestionBoxPageTypeID); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; box.PageName = &quot;Suggestion box&quot;; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; boxLink = DataFactory.Instance.Save(box, SaveAction.Publish, AccessLevel.NoAccess); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Test] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void WhenSuggestionIsMade_ItsAdded_ToTheSuggestionBoxContainer() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SuggestionBox box = new SuggestionBox(boxLink, DataFactory.Instance); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Suggestion original = new Suggestion(&quot;Make it stop&quot;, &quot;I see no end to the possibilities&quot;); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; box.Submit(original); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PageDataCollection stored = DataFactory.Instance.GetChildren(boxLink); &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.That(stored[0].PageName, Is.EqualTo(original.Title)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.That(stored[0][&quot;MainBody&quot;], Is.EqualTo(original.Body)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; make it pass &lt;/p&gt;
&lt;p&gt;Now the fun begins. We&#39;ve already introduced a reference to EPiServer but we need to initialize it. For this purpose I&#39;ve created a little helper that creates a fake page provider that doesn&#39;t use the database. I won&#39;t go over the details but the can be downloaded at the end of the article. For now we just reference EPiSugar.Utilities and tweak the test (sorry kent): &lt;/p&gt;
&lt;p&gt;&lt;font size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [SetUp] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void SetUp() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EPiSugar.UnitTesting.Fakes.Initialize(new FakeStructureBuilder(1, 0)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/font&gt; &lt;/p&gt;
&lt;p&gt;As you would soon discover, we need a few more things: &lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A license.config whose properties is set to &quot;Copy to Output Directory&quot;: &quot;Copy if newer&quot; &lt;/li&gt;
&lt;li&gt;And an app configuration: for this I&#39;m just using the contents of my web.config and adding connectionStrings.config &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;This is how the new and improved implementation looks like:&lt;/p&gt;
&lt;p&gt;&lt;font face=&quot;cou&quot; size=&quot;1&quot;&gt;public class SuggestionBox &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private const int SuggestionPageTypeID = 11; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private readonly PageReference containerLink; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private readonly DataFactory dataFactory; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public SuggestionBox(PageReference containerLink, DataFactory dataFactory) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.containerLink = containerLink; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.dataFactory = dataFactory; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face=&quot;cou&quot; size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Submit(Suggestion suggestion) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PageData page = dataFactory.GetDefaultPageData(containerLink, SuggestionPageTypeID); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; page.PageName = suggestion.Title; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; page[&quot;MainBody&quot;] = suggestion.Body; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dataFactory.Save(page, SaveAction.Publish, AccessLevel.NoAccess); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face=&quot;cou&quot; size=&quot;1&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Suggestion Dequeue() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new NotImplementedException(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Time to run some tests... Wohoo!: 1 passed, 0 failed, 0 skipped &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; left as an excercise to the reader &lt;/p&gt;
&lt;h2&gt;Conclusion &lt;/h2&gt;
&lt;p&gt;Don&#39;t let the simplistic example put you off. One simple test at the time we can achieve great feats. I can&#39;t say such tests arn&#39;t ideal for UI testing in my experience. Would you have any experiences to share in this area? &lt;/p&gt;
&lt;p&gt;Using a faked page provider can really help speed up the tests and smoothe the pain of setting up test data. The great thing is that we don&#39;t need to modify the database state. EPiserver has reached a long way in terms of testability. It&#39;s far from perfect, but the road never ends. Doesn&#39;t it? &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/db23e98da4524bdbbbb17e742ce09dfe.zip&quot;&gt;Download the example test + the EPiSugar utility&lt;/a&gt;. You can also get it directly from the &lt;a href=&quot;http://www.codeplex.com/episerver/SourceControl/ListDownloadableCommits.aspx&quot;&gt;source code repository&lt;/a&gt;. Hope this can be useful to you.&lt;/p&gt;</description>            <guid>https://world.optimizely.com/blogs/Cristian-Libardo/Dates/2008/10/R2-and-unit-testing/</guid>            <pubDate>Thu, 16 Oct 2008 08:34:00 GMT</pubDate>           <category>Blog post</category></item></channel>
</rss>