<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Codality &#187; Downloadable</title>
	<atom:link href="http://blog.najmanowicz.com/category/software-development/downloadable/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.najmanowicz.com</link>
	<description>Code and Effect - solving problem with just enough amount of code - by Adam Najmanowicz</description>
	<lastBuildDate>Mon, 08 Feb 2010 12:01:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Easy Enum property for EPiServer</title>
		<link>http://blog.najmanowicz.com/2009/12/26/easy-enum-property-for-episerver/</link>
		<comments>http://blog.najmanowicz.com/2009/12/26/easy-enum-property-for-episerver/#comments</comments>
		<pubDate>Sat, 26 Dec 2009 19:29:55 +0000</pubDate>
		<dc:creator>Adam Najmanowicz</dc:creator>
				<category><![CDATA[.Net Framework]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[Downloadable]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Solution]]></category>
		<category><![CDATA[Web applications]]></category>

		<guid isPermaLink="false">http://blog.najmanowicz.com/?p=160</guid>
		<description><![CDATA[One of the most frequently and eagerly used programming constructs of the Microsoft.Net Framework is Enum. There are several interesting features that make it very compelling to use to for all kinds of dropdowns and checklists:

The bounds factor – proper use of Enum type guarantee that the selected value will fall within the constraints of [...]]]></description>
			<content:encoded><![CDATA[<p>One of the most frequently and eagerly used programming constructs of the Microsoft.Net Framework is Enum. There are several interesting features that make it very compelling to use to for all kinds of dropdowns and checklists:</p>
<ul>
<li>The bounds factor – proper use of Enum type guarantee that the selected value will fall within the constraints of the allowed value set.</li>
<li>The ability to treat Enums as flags (and compound them into flag sets) as well as a one-of selector. </li>
<li>The ease of use and potentially complete separation of the “Enum value” from the underlying machine type representation that ensures the most efficient memory usage. </li>
</ul>
<p>Surprisingly enough EPiServer as it stands right now does not have an easy facility to turn Enums into properties. To give credit where credit is due, the EPiServer framework provides a nice surrogate that mimic that behaviour to a degree. The relevant property types are:</p>
<ul>
<li><b><a href="http://sdk.episerver.com/library/cms5/html/T_EPiServer_SpecializedProperties_PropertyAppSettingsMultiple.htm">PropertyAppSettingsMultiple</a></b>&#160; &#8211; which “creates check boxes with options that are defined in the AppSettings section in web.config. The name of the property should match the key for the app setting.” </li>
<li><b><a href="http://sdk.episerver.com/library/cms5/html/T_EPiServer_SpecializedProperties_PropertyAppSettings.htm">PropertyAppSettings</a></b>&#160; &#8211; which “creates a drop down list with options that are defined in the AppSettings section in web.config. The name of the property should match the key for the app setting.”</li>
</ul>
<p>You quickly realize though that the properties have some limitations that makes their use a bit less compelling:</p>
<ul>
<li>The properties are not strongly typed </li>
<li>The property entry in AppSettings section has to have the name that matches the property name on the page. </li>
<li>It’s rather poorly documented, Other than relating to this blog entry or <a href="http://antecknat.se/blog/2008/04/18/new-appsettings-and-appsettingsmultiple-in-episerver-cms-5/">Erik’s post documenting</a> it I could not find any other examples on how to use them. (but then again, who needs docs really when we have <a href="http://reflector.red-gate.com/">Reflector</a>) </li>
<li>You cannot have the very same property duplicated on the page since you can only have a single property of a given name per page. So you need to have multiple entries in AppSettings that match the name of each of those properties on your pages. I know… semantics but still… </li>
<li>You are working on strings rather than enums (Did i mention it’s not type safe?) </li>
<li>The values in the AppSettings are stored in a somewhat DLS-y manner (consecutive options are separated from each other with the ‘|’ character, the name and the value are separated with a ‘;’, for example: &lt;add key = &quot;RegionId&quot; value=&quot;First Option;Option1|Default Option;Option2|Disabled Option;Option3&quot; /&gt; ) and I have had on an occasion entered a string there that caused the server to crash.</li>
<li>The values are not translatable, or at least I could not find how to do it and any Reflector digging rendered no results either. </li>
</ul>
<p> <span id="more-160"></span>
</p>
<h2>The solution to the problem:</h2>
<p>The solution that the blog post describes is:</p>
<ul>
<li>Type safe </li>
<li>Supports UI localization </li>
<li>Easy to use in your custom implementation </li>
<li>Flexible in allowing you to switch between the Enum being multi-choice or a single choice solution </li>
<li>fully defined in the code – no need to modify web,config. </li>
</ul>
<p>All you need to do to create your own custom Enum property is declare it.</p>
<pre style="background: white">
<div style="font-family: courier new; background: white; color: black; font-size: 8pt">
<span style="color: blue">using</span> Cognifide.EPiserverControls.EnumDropDown;

[<span style="color: #2b91af">PageDefinitionTypePlugIn</span>(DisplayName = <span style="color: #a31515">&quot;Sample Enum Property&quot;</span>)]
<span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">SampleProperty</span> : <span style="color: #2b91af">PropertyEnumSelector</span>&lt;<span style="color: #2b91af">MySampleEnum</span>&gt;
{
}
</div>
</pre>
<p>That’s it, really!</p>
<p>Now if you want to customize it; obviously you need to provide the information for the property to work with. But let’s stop for a while and think, where does that information belong? </p>
<ul>
<li>The property should worry about the mechanics of editing and the tediousness of persistence of the edited value, it clearly is not the place to specify the link between the Enum type and its human friendly drop down text. </li>
<li>Web.config is for settings, not for describing content types and definitely not to enforce the property names. </li>
<li>So where should the metadata around your Enum type be? How about we put it around the Enum type itself?</li>
</ul>
<pre style="background: white">
<div style="font-family: courier new; background: white; color: black; font-size: 8pt">[<span style="color: #2b91af">Flags</span>]
<span style="color: blue">public</span> <span style="color: blue">enum</span> <span style="color: #2b91af">MySampleEnum</span>
{
  [<span style="color: #2b91af">ValueVisualisation</span>(Name=<span style="color: #a31515">&quot;First Option&quot;</span>, LanguageKey=<span style="color: #a31515">&quot;/enum/first&quot;</span>)]
  Option1,</div>
<div style="font-family: courier new; background: white; color: black; font-size: 8pt">
  [<span style="color: #2b91af">ValueVisualisation</span>(Name=<span style="color: #a31515">&quot;Default Option&quot;</span>, Selected=<span style="color: blue">true</span>, LanguageKey=<span style="color: #a31515">&quot;/enum/second&quot;</span>)]
  Option2,</div>
<div style="font-family: courier new; background: white; color: black; font-size: 8pt">
  [<span style="color: #2b91af">ValueVisualisation</span>(Name=<span style="color: #a31515">&quot;Disabled Option&quot;</span>, Enabled=<span style="color: blue">false</span>, LanguageKey=<span style="color: #a31515">&quot;/enum/disabled&quot;</span>)]
  Option3,</div>
<div style="font-family: courier new; background: white; color: black; font-size: 8pt">
  [<span style="color: #2b91af">ValueVisualisation</span>(Name=<span style="color: #a31515">&quot;Hidden Option&quot;</span>, Hide=<span style="color: blue">true</span>, LanguageKey=<span style="color: #a31515">&quot;/enum/hidden&quot;</span>)]
  Option4,</div>
<div style="font-family: courier new; background: white; color: black; font-size: 8pt">
  [<span style="color: #2b91af">ValueVisualisation</span>(Name=<span style="color: #a31515">&quot;Fifth Option&quot;</span>, LanguageKey=<span style="color: #a31515">&quot;/enum/fifth&quot;</span>)]
  Option5,</div>
<div style="font-family: courier new; background: white; color: black; font-size: 8pt">
}</div>
</pre>
<h2>What does all that do?</h2>
<p>The property using an Enum described this way will look the following way in EPiServer:</p>
<p align="center"><a href="http://blog.najmanowicz.com/wp-content/uploads/2009/12/SampleEnumPropertyFlags.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="SampleEnumPropertyFlags" border="0" alt="SampleEnumPropertyFlags" src="http://blog.najmanowicz.com/wp-content/uploads/2009/12/SampleEnumPropertyFlags_thumb.png" width="517" height="357" /></a></p>
<p>Let’s get into the what’s happened here as there’s more than catches the eye.</p>
<p>As you can see the enum values are named like they are in the attributes describing them, Default option is selected just like you could have expected by looking at the Selected=<span style="color: blue">true</span> in its attribute. The Enabled=<span style="color: blue">false</span> in the Disabled option results in an option that cannot be changed. The unchangeable option can be both unselected or selected by default. You may want to disable some deprecated options but still show them in the UI as a legacy but for some reason you might not want users to be able to change their value. Option4 is clearly missing, which is intended and specified by the Hide=<span style="color: blue">true</span>, as you might want to hide options that have been removed form the UI and on the same time you don’t want to loose compatibility with a legacy API that uses the option.</p>
<p>Also There is one thing about the first option on the list – <strong>it’s translated!</strong> The mechanism to specify the translation is based on the standard EPiServer localization files that you can find in the “lang” folder in your typical EPiServer installation. The Translation for the property looks like the following</p>
<pre style="background: white">
<div style="font-family: courier new; background: white; color: black; font-size: 8pt"><span style="color: blue">&lt;?</span><span style="color: #a31515">xml</span><span style="color: blue"> </span><span style="color: red">version</span><span style="color: blue">=</span>&quot;<span style="color: blue">1.0</span>&quot;<span style="color: blue"> </span><span style="color: red">encoding</span><span style="color: blue">=</span>&quot;<span style="color: blue">utf-8</span>&quot;<span style="color: blue"> </span><span style="color: red">standalone</span><span style="color: blue">=</span>&quot;<span style="color: blue">yes</span>&quot;<span style="color: blue">?&gt;</span>
<span style="color: blue">&lt;</span><span style="color: #a31515">languages</span><span style="color: blue">&gt;</span>
<span style="color: blue">  &lt;</span><span style="color: #a31515">language</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">English</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">en</span>&quot;<span style="color: blue">&gt;</span>
<span style="color: blue">    &lt;</span><span style="color: #a31515">enum</span><span style="color: blue">&gt;</span>
<span style="color: blue">      &lt;</span><span style="color: #a31515">first</span><span style="color: blue">&gt;</span>First Option Translated EN<span style="color: blue">&lt;/</span><span style="color: #a31515">first</span><span style="color: blue">&gt;</span>
<span style="color: blue">    &lt;/</span><span style="color: #a31515">enum</span><span style="color: blue">&gt;</span>
<span style="color: blue">  &lt;/</span><span style="color: #a31515">language</span><span style="color: blue">&gt;    </span>
<span style="color: blue">&lt;/</span><span style="color: #a31515">languages</span><span style="color: blue">&gt;</span></div>
</pre>
<p>so you see the value will take its translation key from the LanguageKey=<span style="color: #a31515">&quot;/enum/first&quot;</span>. </p>
<p>Ok, so we have the <b><a href="http://sdk.episerver.com/library/cms5/html/T_EPiServer_SpecializedProperties_PropertyAppSettingsMultiple.htm">PropertyAppSettingsMultiple</a></b> replacement, but what about <b><a href="http://sdk.episerver.com/library/cms5/html/T_EPiServer_SpecializedProperties_PropertyAppSettings.htm">PropertyAppSettings</a></b>?</p>
<p>So here I reach the place where I am not 100% certain whether I took the proper path but I am sure I will hear about it if I didn’t :) The place where the property determines if it’s supposed to allow for multi selection or not is whether the Enum is marked with the [<span style="color: #2b91af">Flags</span>] attribute. Obviously Flags mean that the property is a form of a bit flag and should be able to allow the user to flip the bits independently rather than being the “one-of” type. So once you remove the [<span style="color: #2b91af">Flags</span>] form your enum you’re going to see it rendered the following way:</p>
<p><a href="http://blog.najmanowicz.com/wp-content/uploads/2009/12/SampleEnumPropertyNoFlags.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="SampleEnumPropertyNoFlags" border="0" alt="SampleEnumPropertyNoFlags" src="http://blog.najmanowicz.com/wp-content/uploads/2009/12/SampleEnumPropertyNoFlags_thumb.png" width="517" height="357" /></a></p>
<p>But hey, it’s not a one way trip, if you decide that you want the enum rendered in another type of property and force the opposite behaviour you can always override it in the derived property like follows:</p>
<pre style="background: white">
<div style="font-family: courier new; background: white; color: black; font-size: 8pt">    [<span style="color: #2b91af">PageDefinitionTypePlugIn</span>(DisplayName = <span style="color: #a31515">&quot;Sample Enum Property Checklist&quot;</span>)]
    <span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">SamplePropertyChecklist</span> : <span style="color: #2b91af">PropertyEnumSelector</span>&lt;<span style="color: #2b91af">MySampleEnum</span>&gt;
    {
        <span style="color: blue">static</span> SamplePropertyChecklist()
        {
            MultiSelectEnum = <span style="color: blue">true</span>;
        }
    }</div>
</pre>
<p>so even if you think my usage of [<span style="color: #2b91af">Flags</span>] is faulty, the damage can be undone :)</p>
<p>Ok, but what about the enums that we have no control over – like enums form libraries. Obviously cannot retrofit attributes into them. Well, true but we still can have all of the control over the property.</p>
<p>Let’s assume for a moment that this is our legacy enum:</p>
<pre style="background: white">
<div style="font-family: courier new; background: white; color: black; font-size: 8pt"><span style="color: blue">public</span> <span style="color: blue">enum</span> <span style="color: #2b91af">MySampleLegacyEnum</span>
{
  Option1,
  Option2,
  Option3,
  Option4,
  Option5,
}</div>
</pre>
<p>You can just do nothing and simply use it in the property but the UI will display the not so nice Option1… names. That can be easily fixed – Again, specifying translation is the easiest way of achieving that goal. An xml for that enum would look like follows:</p>
<pre style="background: white">
<div style="font-family: courier new; background: white; color: black; font-size: 8pt"><span style="color: blue">&lt;?</span><span style="color: #a31515">xml</span><span style="color: blue"> </span><span style="color: red">version</span><span style="color: blue">=</span>&quot;<span style="color: blue">1.0</span>&quot;<span style="color: blue"> </span><span style="color: red">encoding</span><span style="color: blue">=</span>&quot;<span style="color: blue">utf-8</span>&quot;<span style="color: blue"> </span><span style="color: red">standalone</span><span style="color: blue">=</span>&quot;<span style="color: blue">yes</span>&quot;<span style="color: blue">?&gt;</span>
<span style="color: blue">&lt;</span><span style="color: #a31515">languages</span><span style="color: blue">&gt;</span>
<span style="color: blue">  &lt;</span><span style="color: #a31515">language</span><span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">English</span>&quot;<span style="color: blue"> </span><span style="color: red">id</span><span style="color: blue">=</span>&quot;<span style="color: blue">en</span>&quot;<span style="color: blue">&gt;</span>
<span style="color: blue">    &lt;</span><span style="color: #a31515">MySampleLegacyEnum</span><span style="color: blue">&gt;</span>
<span style="color: blue">      &lt;</span><span style="color: #a31515">Option1</span><span style="color: blue">&gt;</span>First Option<span style="color: blue">&lt;/</span><span style="color: #a31515">Option1</span><span style="color: blue">&gt;</span>
<span style="color: blue">      &lt;</span><span style="color: #a31515">Option2</span><span style="color: blue">&gt;</span>Default Option<span style="color: blue">&lt;/</span><span style="color: #a31515">Option2</span><span style="color: blue">&gt;</span>
<span style="color: blue">      &lt;</span><span style="color: #a31515">Option3</span><span style="color: blue">&gt;</span>Disabled Option<span style="color: blue">&lt;/</span><span style="color: #a31515">Option3</span><span style="color: blue">&gt;</span>
<span style="color: blue">      &lt;</span><span style="color: #a31515">Option4</span><span style="color: blue">&gt;</span>Hidden Option<span style="color: blue">&lt;/</span><span style="color: #a31515">Option4</span><span style="color: blue">&gt;</span>
<span style="color: blue">      &lt;</span><span style="color: #a31515">Option5</span><span style="color: blue">&gt;</span>Fifth Option<span style="color: blue">&lt;/</span><span style="color: #a31515">Option5</span><span style="color: blue">&gt;</span>
<span style="color: blue">    &lt;/</span><span style="color: #a31515">MySampleLegacyEnum</span><span style="color: blue">&gt;</span>
<span style="color: blue">  &lt;/</span><span style="color: #a31515">language</span><span style="color: blue">&gt;  </span>
<span style="color: blue">&lt;/</span><span style="color: #a31515">languages</span><span style="color: blue">&gt;</span></div>
</pre>
<p>The default values can be added by retrofitting the “DefaultValues” list with the elements that you want selected in the scenario where the property is first displayed for editing. You can also modify the inherited AvailableItems list to set the rest of the properties otherwise adjustable by the attributes. </p>
<p>Following is a sample of such retrofitted rules to match our original attribute-defined-enum.</p>
<pre style="background: white">
<div style="font-family: courier new; background: white; color: black; font-size: 8pt">[<span style="color: #2b91af">PageDefinitionTypePlugIn</span>(DisplayName = <span style="color: #a31515">&quot;Sample Legacy Enum Property&quot;</span>)]
<span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">SampleProperty</span> : <span style="color: #2b91af">PropertyEnumSelector</span>&lt;<span style="color: #2b91af">MySampleLegacyEnum</span>&gt;
{
    <span style="color: blue">static</span> SampleProperty()
    {
        MultiSelectEnum = <span style="color: blue">true</span>;

        <span style="color: green">// Make Option2 a default selected value</span>
        DefaultValues.Add(<span style="color: #2b91af">MySampleLegacyEnum</span>.Option2.ToString());
        AvailableItems.Where(p =&gt; p.Value == <span style="color: #2b91af">MySampleLegacyEnum</span>.Option2.ToString()).First().Selected = <span style="color: blue">true</span>;

        <span style="color: green">//Disable selection of Option3</span>
        AvailableItems.Where(p =&gt; p.Value == <span style="color: #2b91af">MySampleLegacyEnum</span>.Option3.ToString()).First().Enabled = <span style="color: blue">false</span>;

        <span style="color: green">//Remove hidden Option4</span>
        AvailableItems.RemoveAll(p =&gt; p.Value == <span style="color: #2b91af">MySampleLegacyEnum</span>.Option4.ToString());
    }
}</div>
</pre>
<p>The [<a href="http://www.najmanowicz.com/blog_bin/Cognifide.EPiserverControls.EnumDropDown.zip">code for the EnumProperty</a>] as well as [<a href="http://www.najmanowicz.com/blog_bin/Cognifide.EPiserverControls.EnumDropDown.Assembly.zip">the compiled binaries</a>] are available as Open Source and you can incorporate it in your projects as long as the Cognifide namespace is used for the code.</p>
<p>What do you think? Is that going to be useful for you?</p>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=160&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2009/12/26/easy-enum-property-for-episerver/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SoakIE &#8211; a Web Server Stress Tool with a twist</title>
		<link>http://blog.najmanowicz.com/2009/05/10/soakie-a-web-server-stress-tool-with-a-twist/</link>
		<comments>http://blog.najmanowicz.com/2009/05/10/soakie-a-web-server-stress-tool-with-a-twist/#comments</comments>
		<pubDate>Sun, 10 May 2009 14:27:06 +0000</pubDate>
		<dc:creator>Adam Najmanowicz</dc:creator>
				<category><![CDATA[.Net Framework]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Downloadable]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Solution]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[Web applications]]></category>

		<guid isPermaLink="false">http://blog.najmanowicz.com/2009/05/10/soakie-a-web-server-stress-tool-with-a-twist/</guid>
		<description><![CDATA[Last week or so ago a couple of friends in another project in Cognifide has run into a wall while trying to load test their website. the problem was as follows: The website is highly AJAX based – the page merely loads a stub in the initial request but then loads the rest of its [...]]]></description>
			<content:encoded><![CDATA[<p>Last week or so ago a couple of friends in another project in Cognifide has run into a wall while trying to load test their website. the problem was as follows: The website is highly AJAX based – the page merely loads a stub in the initial request but then loads the rest of its data in a dynamic matter therefore a traditional web testing tools are fairly useless. What they tried was to setup a number of Selenium clients to pound the server, but that turned out to be fairly challenging to the machine doing the testing. It was not possible to set up more than 10 clients on a fairly strong machine.</p>
<p>Also there are other limitations like time to wait for the server to timeout and time between clicks, which I am not sure the tool allowed them to adjust. Talking to them I recalled <a href="http://blog.najmanowicz.com/2006/11/17/how-to-get-website-thumbnail-in-c/">a tool for grabbing website thumbnails</a> long time ago. one way for them would be to to make a batch file with it. The tool would grab the sites’ thumbnail and stress it, but they would still have to setup a number of clients. Also it creates and tears down an instance of IE every time, making it’s not optimal for that task.</p>
<p>So a couple of evenings later (and a few back-s and forth-s during the testing sessions) out comes SoakIE:</p>
<p align="center"><a href="http://blog.najmanowicz.com/wp-content/uploads/2009/05/soakietest.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="SoakIETest" border="0" alt="SoakIETest" src="http://blog.najmanowicz.com/wp-content/uploads/2009/05/soakietest-thumb.png" width="429" height="387" /></a> </p>
<p> <span id="more-140"></span>
<p align="left">The app uses pretty much the same trick as the <a href="http://blog.najmanowicz.com/2006/11/17/how-to-get-website-thumbnail-in-c/">tool for grabbing website thumbnails</a> but it does so in a nice UI and allows for some rudimentary settings for profiling the traffic:</p>
<p><a href="http://blog.najmanowicz.com/wp-content/uploads/2009/05/soakiesetup.png"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="SoakIESetup" border="0" alt="SoakIESetup" src="http://blog.najmanowicz.com/wp-content/uploads/2009/05/soakiesetup-thumb.png" width="429" height="387" /></a> </p>
<p>You can select the number of IE instances that will do the clicking, you can select a minimum time between clicks – that is how often any IE instance can click (if it already finished with the previous request). this allows you to simulate clients that will stay a minute on your site and only click after they’ve read the page. Additionally if your application can on an occasion encounter a deadlock or a hang, it allows you to specify the maximum time to live of each request. If the request takes longer than the specified time, the application will “Stop” the request.</p>
<p>One thing that we’ve noticed though is that after a long time of soak tests the IE instances get mighty fat and start to slow down dramatically. Therefore I’ve added a maximum number of clicks an IE instance can perform after which the client will no longer recycle it for more click but will tear it down and create a new IE instance to continue testing.</p>
<p>Naturally the application needs to know what to test. This is specified in the “Test setup&quot; tab in the “URLs to stress:&quot; text box. The URLs will be picked in a round-robin fashion. The first browser will get the first url, the next one will get the second and so on, if the list will get exhausted the browsers will get fed it from beginning. You can theoretically put them in the box with some other text (like pasting it from a Skype window without stripping the message decoration around them) – SoakIE should be smart enough to parse the text and get the URLs out of it.</p>
<p>You can download <a href="http://www.najmanowicz.com/blog_bin/SoakIE.zip">SoakIE here</a></p>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=140&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2009/05/10/soakie-a-web-server-stress-tool-with-a-twist/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Advanced Language Manipulation Tool for EPiServer</title>
		<link>http://blog.najmanowicz.com/2009/04/06/advanced-language-manipulation-tool-for-episerver/</link>
		<comments>http://blog.najmanowicz.com/2009/04/06/advanced-language-manipulation-tool-for-episerver/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 15:49:11 +0000</pubDate>
		<dc:creator>Adam Najmanowicz</dc:creator>
				<category><![CDATA[.Net Framework]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[Downloadable]]></category>
		<category><![CDATA[EPiCode]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[Microsoft SqlServer]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Solution]]></category>
		<category><![CDATA[Web applications]]></category>

		<guid isPermaLink="false">http://blog.najmanowicz.com/2009/04/06/advanced-language-manipulation-tool-for-episerver/</guid>
		<description><![CDATA[Have you ever (or have your customers) created and edited a page in one language only to realize that their selected locale was wrong? Have you ever wished you could delete a master language branch of a page&#160; after creating its localized counterpart but you could only delete the newly created slave language instead? Have [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever (or have your customers) created and edited a page in one language only to realize that their selected locale was wrong? Have you ever wished you could delete a master language branch of a page&#160; after creating its localized counterpart but you could only delete the newly created slave language instead? Have a customer ever requested that they could copy a whole branch and you convert it to another language so that they could then translate in-place?</p>
<p>Well I have… and I’m sure I will. And so did Fredrikj on the our #epicode IRC channel ;).</p>
<p>Basically I had the tool that would convert from one language to another, but Fredrikj requested something that would switch master language of a page from one to another. Since I’ve already had some of the work done, I’ve updated the stored procedure I’ve written some time ago and slapped a nice GUI up on it. Here’s the result:</p>
<p>&#160;</p>
<p align="center"><a href="http://blog.najmanowicz.com/wp-content/uploads/2009/04/andvancedlanguagetool.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="AndvancedLanguageTool" border="0" alt="AndvancedLanguageTool" src="http://blog.najmanowicz.com/wp-content/uploads/2009/04/andvancedlanguagetool-thumb.png" width="480" height="484" /></a> </p>
<p>What the tool allows you to do is perform either language conversion or master branch switching on a selected page and all of its children (if you choose so).</p>
<p>The stored procedure have been updated to work on CMS5 R2 (will no longer work on R1 – but if you need that functionality, comment here or give me a shout and I’ll create a compatible version for you).</p>
<p>A word of caution though – I take no guarantee whatsoever about its operation. Especially, if you wreck your client’s database with it. I did what I could to prevent some of the obvious problems (like <strong><em>switching</em></strong> to a non existing master or <strong><em>converting</em></strong> to an existing one) but I will not be responsible if it won’t work for you. make a database backup and experiment there before you do any changes on the real data. That said – it works for me, so I think it should also work for you.</p>
<p>You can download the <a title="Episerver Advanced Language Tools" href="http://www.najmanowicz.com/blog_bin/EPiServerLanguageTools.zip" rel="enclosure">archive containing the tool here</a>. unzip it to your EPiServer web application folder keeping the folder structure or the plugin reference will be wrong. Include the *.aspx and the *.cs files in your project and apply the SQL file to your database (The manipulation is performed by a stored procedure located in the file).</p>
<p>Also if you’re performing the change in a load balanced environment, you may need to restart the other servers once you do the changes. I reset the DataFactory cache, but I am not sure it propagates through to other servers.</p>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=124&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2009/04/06/advanced-language-manipulation-tool-for-episerver/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>WebParts based Sidebar for EPiServer &#8211; how to use it?</title>
		<link>http://blog.najmanowicz.com/2009/01/08/webparts-based-sidebar-for-episerver-how-to-use-it/</link>
		<comments>http://blog.najmanowicz.com/2009/01/08/webparts-based-sidebar-for-episerver-how-to-use-it/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 17:06:47 +0000</pubDate>
		<dc:creator>Adam Najmanowicz</dc:creator>
				<category><![CDATA[.Net Framework]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Downloadable]]></category>
		<category><![CDATA[EPiCode]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[Internet Information Services]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web applications]]></category>
		<category><![CDATA[WebParts]]></category>

		<guid isPermaLink="false">http://blog.najmanowicz.com/2009/01/08/webparts-based-sidebar-for-episerver-how-to-use-it/</guid>
		<description><![CDATA[Once you’ll update the framework to the extended one, you will immediately notice that… nothing has changed. Hmm… did something go wrong? 
Well, not really. By default the framework will be run in the “legacy mode”. Thanks to an old article by our own Marek Blotny, I’ve learned how to build Plugin settings which are [...]]]></description>
			<content:encoded><![CDATA[<p>Once you’ll update the framework to the extended one, you will immediately notice that… nothing has changed. Hmm… did something go wrong? </p>
<p>Well, not really. By default the framework will be run in the “legacy mode”. Thanks to <a href="http://marekblotny.blogspot.com/2008/07/plugins-and-datafactory-event-handlers.html">an old article by our own Marek Blotny</a>, I’ve learned how to build Plugin settings which are just perfect for the purpose!</p>
<p align="left">So to configure and enable the new features you need to open your admin UI and in the “Config” click on the “Plugin Manager” item and select our framework plugin as shown in the picture</p>
<p align="center"><a href="http://blog.najmanowicz.com/wp-content/uploads/2009/01/webpartframeworkpluginsettings1.png"><img title="WebPartFrameworkPluginSettings1" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="164" alt="WebPartFrameworkPluginSettings1" src="http://blog.najmanowicz.com/wp-content/uploads/2009/01/webpartframeworkpluginsettings1-thumb.png" width="244" border="0" /></a></p>
<p>The available options are:</p>
<p><span id="more-110"></span><br />
<table cellspacing="0" cellpadding="2" border="0">
<tbody>
<tr>
<td><b>Setting Name</b></td>
<td><b>Meaning</b></td>
<td><b>Sample</b></td>
</tr>
<tr>
<td><b><i>Default WebParts Path Pattern</i></b></td>
<td>The pattern to be used when no pattern is defined for a page.</td>
<td>%inherit%</td>
</tr>
<tr>
<td><b><i>WebParts Path Patterns</i></b></td>
<td>The semicolon separated pairs of pattern;pattern name;          <br />This is the part you will want to customize most.</td>
<td>%template%|%pageid%%legacyregion%;Legacy regionalized;%template%|%pageid%;Legacy globalized;page|%pageid%|%region%;Page/region;pagetype|%pagetypeid%;Page Type</td>
</tr>
<tr>
<td><b><i>Cache WebParts in Memory</i></b></td>
<td>Determines whether the WebParts are to be cached&#160; between usages (this is useful for a small set of WebParts (like a number of sidebars) but rather discouraged if you use the legacy mode as there can be a lot of those in such case.</td>
<td>unchecked by default (check to improve performance in sidebar mode)</td>
</tr>
<tr>
<td><b><i>Legacy WebParts Support (per-page only)</i></b></td>
<td>If checked, disables the extensions described by this blog.</td>
<td>checked by default (uncheck to enable the sidebar extensions)</td>
</tr>
</tbody>
</table>
<p>&#160;</p>
<p>As shown here:</p>
<p><a href="http://blog.najmanowicz.com/wp-content/uploads/2009/01/webpartframeworkpluginsettings2.png"><img title="WebPartFrameworkPluginSettings2" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="179" alt="WebPartFrameworkPluginSettings2" src="http://blog.najmanowicz.com/wp-content/uploads/2009/01/webpartframeworkpluginsettings2-thumb.png" width="244" border="0" /></a> </p>
<p>&#160;</p>
<p>Once you fill in the settings as they are suggested in the above table the context menu (or adjust to your needs) will show you the new options:</p>
<p align="center"><a href="http://blog.najmanowicz.com/wp-content/uploads/2009/01/webpartframeworkpluginsettings3.png"><img title="WebPartFrameworkPluginSettings3" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="173" alt="WebPartFrameworkPluginSettings3" src="http://blog.najmanowicz.com/wp-content/uploads/2009/01/webpartframeworkpluginsettings3-thumb.png" width="244" border="0" /></a> </p>
</p>
<p>The new sub menu will allow you to change the pattern by which the WebParts are selected, while “Edit Web Parts” option will enable you to edit the WebParts for the current effective WebPart set.</p>
<p><font color="#ff0000"><strong>First of all – if you want to select a pattern on a page you need a means of storing it. At this moment The framework does it in a property. Which means &#8211; for every page type that wants to redefine the web parts rather than using the default pattern (in our case %inherited%) you need to add String property with a “WebPartsPath” name (I may actually add some routines to add the property definition automatically if there will be enough demand for that).</strong></font></p>
<h1>What does “Effective WebPart Set” mean?</h1>
<p>Assuming (which is the most interesting scenario) that %inherit% is the default pattern the following is true: </p>
<p>&#160;</p>
<table border="1">
<tbody>
<tr>
<td><b>Page</b></td>
<td><b>WebPartsPath</b></td>
<td><b>Effective path</b></td>
<td><b>Description</b></td>
</tr>
<tr>
<td>Start</td>
<td>&#160;</td>
<td>%root%</td>
<td>Since it&#8217;s a start page and it does not define path %root% is used.</td>
</tr>
<tr>
<td>+ News</td>
<td>&#160;</td>
<td>%root%</td>
<td>inherits from start page which does not define path but inherits from %root%.</td>
</tr>
<tr>
<td>+ Events</td>
<td>page|%pageid%</td>
<td>page|5</td>
<td>directly implements its own pattern.</td>
</tr>
<tr>
<td>| + Partner Day</td>
<td>%inherit%</td>
<td>page|5</td>
<td>Inherits after its parent page.</td>
</tr>
<tr>
<td>+ International</td>
<td>page|%pageid%|%region%</td>
<td>page|6|en, page|6|se</td>
<td>Defines separate WebParts for every language that the page is created for.</td>
</tr>
<tr>
<td>| + Sweden</td>
<td>%inherit%</td>
<td>page|6|se</td>
<td>Inherits after its parent page in its own language.</td>
</tr>
<tr>
<td>| + England</td>
<td>%inherit%</td>
<td>page|6|en</td>
<td>Inherits after its parent page in its own language.</td>
</tr>
</tbody>
</table>
<p>Once you select the effective web parts for the page or just agree with the WebParts pre-selected for you based on the default path you can edit them just like previously. Mind that when you edit WebParts on a page all the pages that have the same “effective path” are going to change as well. (which was our intention in the first place).</p>
<p>&#160;</p>
<p>The library extension is going to be posted on Epicode as soon as I get a hold of Steve to approve the changes :)</p>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=110&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2009/01/08/webparts-based-sidebar-for-episerver-how-to-use-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WebParts based Sidebar for EPiServer &#8211; the motivation and specification</title>
		<link>http://blog.najmanowicz.com/2009/01/08/webparts-based-sidebar-for-episerver-the-motivation-and-specification/</link>
		<comments>http://blog.najmanowicz.com/2009/01/08/webparts-based-sidebar-for-episerver-the-motivation-and-specification/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 14:04:12 +0000</pubDate>
		<dc:creator>Adam Najmanowicz</dc:creator>
				<category><![CDATA[.Net Framework]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Downloadable]]></category>
		<category><![CDATA[EPiCode]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[Internet Information Services]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web applications]]></category>
		<category><![CDATA[WebParts]]></category>

		<guid isPermaLink="false">http://blog.najmanowicz.com/2009/01/08/webparts-based-sidebar-for-episerver-the-motivation-and-specification/</guid>
		<description><![CDATA[Back in the day when we started designing our last project we’ve been presented with a following problem – a big number of templates with slightly different sidebars.
Hmm… 
Is sidebar a part of content? No, rather not. We don’t want the editors to have to setup the sidebar for every article they write (and the [...]]]></description>
			<content:encoded><![CDATA[<p>Back in the day when we started designing our last project we’ve been presented with a following problem – a big number of templates with slightly different sidebars.</p>
<p>Hmm… </p>
<p>Is sidebar a part of content? No, rather not. We don’t want the editors to have to setup the sidebar for every article they write (and the site has a few dozens of articles created on it every day).</p>
<p>Is sidebar more of a template thing? Well… more like it, but still… we have articles all over the site with different sidebar elements when the articles are in different parts of the site (ok so we could add rules what controls display in which part of the site). <strong>But wait! There’s more!</strong> The sidebar will be different for every language (region). Now we’re talking a dozen of templates or a rules engine just to make the sidebar different. Customising the template with properties isn’t ideal either as it makes EPiServer UI very cluttered. Additionally we want to change sidebars across many templates so the whole branch/section of the site will be able to share the same sidebar.</p>
<p>To a degree this is an academic discussion as we’ve been through it with the previous version of the site and we already knew that integrating this stuff into templates just won’t work and we will be in a world of pain just changing the templates over and over adding little tweaks and changes while the customer ads promotions and performs ad campaigns. Well, we can do it, of course, but it’s not a work a programmer will enjoy, and we all want to do new and more exciting things, don’t we?</p>
<p>We have an internally developed&#160; module to make something like that, that is fully home-grown by another internal team (we now have 3 “squads” capable or making incredible things with EPiServer and we tend to share a lot of technologies and try to rotate people around to adopt the good habits and experiences) and I was (and still am) VERY impressed by it. The technology uses EPiServer pages for defining every module (which are located somewhere outside the site root branch. and then you can mix and match them either declaratively in the code) or by handpicking them in the UI. It’s really cool, though, during the discussions it turned out that we might have to add big chunks of functionality and might end up with separate branches of module-pages for different languages/regions, but… frankly… about that time <a href="http://labs.episerver.com/en/Blogs/Ted-Nyberg/Dates/112276/8/Using-web-parts-in-EPiServer/">an article by Ted Nyberg</a> reminded me about a technology I have read about quite a while ago in <a href="http://labs.episerver.com/en/Blogs/Stein-Viggo-Grenersen/Dates/112262/2/EPiServer-on-steroids/">an article by Stein-Viggo Grenersen</a> and ooohhhhhh… I got seduced. I really wanted to try if for a long time and Ted’s article made it a snap to try and get convinced, and more important… convince Stu ;) that it’s the right way to explore.</p>
<h2>So I started to dig.</h2>
<p><span id="more-103"></span></p>
<h2></h2>
<p><a href="http://labs.episerver.com/en/Blogs/Stein-Viggo-Grenersen/Dates/112262/2/EPiServer-on-steroids/"><img style="display: inline; margin: 0px 10px 0px 0px" src="http://www.najmanowicz.com/blog_images/DragDropWebPartsmaller.gif" align="left" /></a>Talked with <a href="http://stevecelius.spaces.live.com/">Steve</a> (the original creator of the Framework) a bit and learned that I can “customize a path rewriter” to suit my needs. Great! I just hoped I won’t have to deal with some nasty GUID’s matching, but no! Turns out, all it takes to identify a WebPart set is to have any unique string naming it.</p>
<p>So basically what we needed was a manager to deal with the naming templates and a way to determine the WebParts set to be used per page.</p>
<p>Till now the framework used template file name followed by the page ID, followed by an eventual language/region if a page was not the master branch, for example:</p>
<blockquote><p>~/templates/Demo/WebPartPage.aspx|26    <br />~/templates/Demo/WebPartPage.aspx|26|en-us </p></blockquote>
<p>which makes them unique per page, which is not as appealing when you use EPiServer as it for a big part duplicates its functionality. Also a bit of a caveat here for agile programming methodology which promotes an often and early refactoring – if you move your page around or change its name – you lose the WebParts for all pages using it.</p>
<p>What we needed is a flexible and extensible scheme for reusing “WebParts sets” and that’s what our extension allows for.</p>
<p>Also since we’re very performance sensitive, and we operate in a multi server scenarios a lot we’ve added web parts blobs caching. Meaning that the site does not have to reach to the database every time a page is rendered.</p>
<p>The very appealing side of the framework is that it can be extended form the bottom (persistence) from the top (editors, controls, webparts), as well as being pluggable with custom plumbing.</p>
<h2>The Sidebar Extensions for WebParts Framework</h2>
<p>So to put all the requirements together, we needed the sidebars to be:</p>
<ul>
<li>customizable (out of the box) </li>
<li>easy to use for both developers and editors (out of the box) Wow Steve, I can’t really appreciate enough how cool it is to code for it and how nice it is for the users! </li>
<li>localizable </li>
<li>reusable </li>
<li>inheritable for site branches </li>
</ul>
<h2>WebParts path patterns</h2>
<p>The main idea was to free the path names from the restriction they had – being hardcoded for a page. So to do it without hard-coding them I’ve introduced path patterns. </p>
<h3>What is a pattern?</h3>
<p>Basically a pattern is a way the framework is supposed to encode the WebParts&#160; id for the system to identify. Your site can have any number of “named patterns” and the framework gives you means of switching between them. Pattern allow for almost any string to be a part of it although some tokens have special meaning:</p>
<table cellspacing="0" cellpadding="2" width="680" border="0">
<tbody>
<tr>
<td valign="top" width="200"><strong>Token</strong></td>
<td valign="top" width="478"><strong>Replacemnt Value</strong></td>
</tr>
<tr>
<td valign="top" width="200">%pageid%</td>
<td valign="top" width="478">id of the page the path is formed for</td>
</tr>
<tr>
<td valign="top" width="200">%region%</td>
<td valign="top" width="478">language/region of the WebParts</td>
</tr>
<tr>
<td valign="top" width="200">%pagetypeid%</td>
<td valign="top" width="478">type of the page</td>
</tr>
<tr>
<td valign="top" width="200">%template%</td>
<td valign="top" width="478">legacy token to make it possible to use template names as part of path.          <br />This is just for compatibility so you can have some of the pages using an old scheme.</td>
</tr>
<tr>
<td valign="top" width="200">%legacyregion%</td>
<td valign="top" width="478">legacy token for regionalizable pages (usage described later)</td>
</tr>
<tr>
<td valign="top" width="200">%inherited%</td>
<td valign="top" width="478">states that a page shoud inherit its WebParts from its parent in the page hierarchy (this can only be used as a complete pattern – cannot be a part of a larger pattern)</td>
</tr>
<tr>
<td valign="top" width="200">%root%</td>
<td valign="top" width="478">(again whole pattern) the %root% token is used when the inheritance based on hierarchy does not resolve into another token while reaching the root page.</td>
</tr>
</tbody>
</table>
<h3>Some sample patterns</h3>
<table cellspacing="0" cellpadding="2" width="600" border="1">
<tbody>
<tr>
<td valign="top" width="100"><strong>Name</strong></td>
<td valign="top" width="100"><strong>Pattern</strong></td>
<td valign="top" width="150"><strong>Sample Instance</strong> <strong>of the Pattern</strong></td>
<td valign="top" width="200"><strong>Description</strong></td>
</tr>
<tr>
<td valign="top" width="100">Root pattern</td>
<td valign="top" width="100">%root%</td>
<td valign="top" width="150">%root%</td>
<td valign="top" width="200">The pattern that all inheritance automatically falls back to</td>
</tr>
<tr>
<td valign="top" width="100">Inherited</td>
<td valign="top" width="100">%inherit%</td>
<td valign="top" width="150">anything parent defines</td>
<td valign="top" width="200">Tells the page to use the web parts its parent is using – the inheritance is possible all the way up in the hierarchy to the %root% pattern, meaning – if my parent inherits its WebParts from its parent, so will I.</td>
</tr>
<tr>
<td valign="top" width="100">Legacy regionalized</td>
<td valign="top" width="100">%template%|%pageid%%legacyregion%</td>
<td valign="top" width="150">~/templates/Demo/​​WebPartPage.aspx|26|en-us</td>
<td valign="top" width="200">Creates legacy “non language independent path”</td>
</tr>
<tr>
<td valign="top" width="100">Legacy global </td>
<td valign="top" width="100">%template%|%pageid%</td>
<td valign="top" width="150">~/templates/Demo/​​WebPartPage.aspx|26</td>
<td valign="top" width="200">Creates legacy “language independent path”</td>
</tr>
<tr>
<td valign="top" width="100">Page/region specific</td>
<td valign="top" width="100">page|%pageid%|%region%</td>
<td valign="top" width="150">page|26|en-us</td>
<td valign="top" width="200">template independent per-page/per-language pattern</td>
</tr>
<tr>
<td valign="top" width="100">PageType specific</td>
<td valign="top" width="100">pagetype|%pagetypeid%</td>
<td valign="top" width="150">pagetype|5</td>
<td valign="top" width="200">page type specific path (notice how the previous pattern has “page” and this one has “pagetype” in it) – this is done to avoid conflicts in numbers between pages and page types of the same id</td>
</tr>
<tr>
<td valign="top" width="100">My Sidebar</td>
<td valign="top" width="100">my-sidebar</td>
<td valign="top" width="150">my-sidebar</td>
<td valign="top" width="200">You can create “named sets” that will stay the same across all pages using it</td>
</tr>
<tr>
<td valign="top" width="100">My Localizable Sidebar</td>
<td valign="top" width="100">my-sidebar|%region%</td>
<td valign="top" width="150">my-sidebar|en-us</td>
<td valign="top" width="200">A localized version of the previous “named set”</td>
</tr>
</tbody>
</table>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=103&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2009/01/08/webparts-based-sidebar-for-episerver-the-motivation-and-specification/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Text-Image generation &#8211; VirtualPathProvider for EPiServer (and ASP.NET in general) &#8211; Part 2 (configuration)</title>
		<link>http://blog.najmanowicz.com/2008/06/24/text-image-generation-virtualpathprovider-for-episerver-and-aspnet-in-general-part-2-configuration/</link>
		<comments>http://blog.najmanowicz.com/2008/06/24/text-image-generation-virtualpathprovider-for-episerver-and-aspnet-in-general-part-2-configuration/#comments</comments>
		<pubDate>Tue, 24 Jun 2008 18:36:00 +0000</pubDate>
		<dc:creator>Adam Najmanowicz</dc:creator>
				<category><![CDATA[.Net Framework]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Downloadable]]></category>
		<category><![CDATA[EPiCode]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[Internet Information Services]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web applications]]></category>

		<guid isPermaLink="false">http://blog.najmanowicz.com/2008/06/24/text-image-generation-virtualpathprovider-for-episerver-and-aspnet-in-general-part-2-configuration/</guid>
		<description><![CDATA[
The configuration of the module is a descendant of any EPiServer Virtual Path Provider configuration. This aspect is fairly well described on EPiServer pages. 
A sample configuration for the TextImageVirtualPathProvider can look as follows

&#60;configuration&#62;
  &#60;episerver&#62;
    &#60;virtualPath
      &#60;providers&#62;
        &#60;add showInFileManager="false"
 [...]]]></description>
			<content:encoded><![CDATA[</p>
<p>The configuration of the module is a descendant of any EPiServer Virtual Path Provider configuration. This aspect is fairly well <a href="http://world.episerver.com/Documentation/Items/Tech-Notes/EPiServer-CMS-SP2/Virtual-Path-Providers-in-EPiServer-CMS-5/">described on EPiServer pages</a>. </p>
<p>A sample configuration for the TextImageVirtualPathProvider can look as follows</p>
<pre>
<div style="font-size: 8pt; background: white; color: black; font-family: courier new"><span style="color: blue">&lt;</span><span style="color: #a31515">configuration</span><span style="color: blue">&gt;</span>
<span style="color: blue">  &lt;</span><span style="color: #a31515">episerver</span><span style="color: blue">&gt;</span>
<span style="color: blue">    &lt;</span><span style="color: #a31515">virtualPath</span>
<span style="color: blue">      &lt;</span><span style="color: #a31515">providers</span><span style="color: blue">&gt;</span>
<span style="color: blue">        &lt;</span><span style="color: #a31515">add</span><span style="color: blue"> </span><span style="color: red">showInFileManager</span><span style="color: blue">=</span>"<span style="color: blue">false</span>"
<span style="color: blue">             </span><span style="color: red">virtualName</span><span style="color: blue">=</span>"<span style="color: blue">Text Images</span>"
<span style="color: blue">             </span><span style="color: red">virtualPath</span><span style="color: blue">=</span>"<span style="color: blue">~/TextImages/</span>"
<span style="color: blue">             </span><span style="color: red">bypassAccessCheck</span><span style="color: blue">=</span>"<span style="color: blue">false</span>"
<span style="color: blue">             </span><span style="color: red">name</span><span style="color: blue">=</span>"<span style="color: blue">TextImages</span>"
<span style="color: blue">             </span><span style="color: red">type</span><span style="color: blue">=</span>"<span style="color: blue">Cognifide.ImageVirtualPathProvider.TextImageVirtualPathProvider,Cognifide.ImageVirtualPathProvider</span>"
<span style="color: blue">             </span><span style="color: red">physicalPath</span><span style="color: blue">=</span>"<span style="color: blue">C:\temp\TextImages</span>"
<span style="color: blue">             </span><span style="color: red">allowedReferers</span><span style="color: blue">=</span>"<span style="color: blue">(localhost)</span>"
<span style="color: blue">             </span><span style="color: red">allowNullReferrer</span><span style="color: blue">=</span>"<span style="color: blue">false</span>"
<span style="color: blue">             </span><span style="color: red">replacementStrings</span><span style="color: blue">=</span>"<span style="color: blue">$colon$,:,$gt$,&gt;,$dot$,.,$quot$,</span><span style="color: red">&amp;quot;</span><span style="color: blue">,$amp$,</span><span style="color: red">&amp;amp;</span><span style="color: blue">,$star$,*,$eol$,</span><span style="color: red">&amp;#10;</span><span style="color: blue">,</span>"<span style="color: blue">/&gt;</span>
<span style="color: blue">      &lt;/</span><span style="color: #a31515">providers</span><span style="color: blue">&gt;</span>
<span style="color: blue">    &lt;/</span><span style="color: #a31515">virtualPath</span><span style="color: blue">&gt;</span>
<span style="color: blue">  &lt;/</span><span style="color: #a31515">episerver</span><span style="color: blue">&gt;</span>
<span style="color: blue">&lt;/</span><span style="color: #a31515">configuration</span><span style="color: blue">&gt;</span>
</div>
</pre>
<p>&nbsp;</p>
<p>where:</p>
<ul>
<li>physicalPath is where the cached version of images will be stored
</li>
<li>shownInFileManager is “false” as there is nothing to present for the user in the file manager.
</li>
<li>allowedReferrers is the regular expression containing the filter for sites that are allowed to access the path provider and get images. This has been added so that your server does not turn into the internet’s text-image open service :)
</li>
<li>allowNullReferrer should be set to false in production environment but allows for testing by directly creating URL’s without using a page to fill in the referrer.
</li>
<li>replacementStrings – this one actually turned out to be very useful since some characters are invalid and not even reaching the VPP if EPiServer or ASP detects them. so to allow for characters like colon or &lt; or even a dot (which would make it hard to form regular expression if it was explicitly available) or * you need to create an escape token for them. The string is a coma separated list of token,value,token,value,…
</li>
<li>virtualPath is something you need to change if you want your VPP to serve images under a different root level folder. (e.g. if you have a page with that name already)</li>
</ul>
<p>&nbsp;</p>
<p>Additionally for IIS6 (most common scenario) you need to add &lt;location&gt; node to configuration for the VPP to work. </p>
<p><span style="color: blue">&lt;</span><span style="color: #a31515">configuration</span><span style="color: blue">&gt;</span><br /><span style="color: blue">&nbsp; &lt;</span><span style="color: #a31515">location</span><span style="color: blue"> </span><span style="color: red">path</span><span style="color: blue">=</span>&#8220;<span style="color: blue">TextImages</span>&#8220;<span style="color: blue">&gt;</span><br /><span style="color: blue">&nbsp;&nbsp;&nbsp; &lt;</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span><br /><span style="color: blue">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!&#8211;</span><span style="color: green"> Setup the StaticFileHandler for the wildcard mapping to work in IIS6</span><span style="color: blue">&#8211;&gt;</span><br /><span style="color: blue">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;</span><span style="color: #a31515">httpHandlers</span><span style="color: blue">&gt;</span><br /><span style="color: blue">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;</span><span style="color: #a31515">add</span><span style="color: blue"> </span><span style="color: red">path</span><span style="color: blue">=</span>&#8220;<span style="color: blue">*</span>&#8220;<span style="color: blue"> </span><span style="color: red">verb</span><span style="color: blue">=</span>&#8220;<span style="color: blue">GET,HEAD</span>&#8220;<span style="color: blue"> </span><span style="color: red">type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">System.Web.StaticFileHandler</span>&#8220;<span style="color: blue"> </span><span style="color: red">validate</span><span style="color: blue">=</span>&#8220;<span style="color: blue">true</span>&#8220;<span style="color: blue"> /&gt;</span><br /><span style="color: blue">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/</span><span style="color: #a31515">httpHandlers</span><span style="color: blue">&gt;</span><br /><span style="color: blue">&nbsp;&nbsp;&nbsp; &lt;/</span><span style="color: #a31515">system.web</span><span style="color: blue">&gt;</span><br /><span style="color: blue">&nbsp;&nbsp;&nbsp; &lt;</span><span style="color: #a31515">staticFile</span><span style="color: blue"> </span><span style="color: red">expirationTime</span><span style="color: blue">=</span>&#8220;<span style="color: blue">-1.0:0:0</span>&#8220;<span style="color: blue"> /&gt;</span><br /><span style="color: blue">&nbsp; &lt;/</span><span style="color: #a31515">location</span><span style="color: blue">&gt;</span><br /><span style="color: blue">&lt;/</span><span style="color: #a31515">configuration</span><span style="color: blue">&gt;</span></p>
<pre>
</pre>
<p>Unless you want to change the location of the virtual path provider can be found under, there is nothing you need to change here.</p>
<p>The <a href="https://www.coderesort.com/p/epicode/browser/Cognifide.ImageVirtualPathProvider/5.x">code is accessible on EPiCode</a>, but you can also <a href="http://www.najmanowicz.com/blog_bin/Cognifide.ImageVirtualPathProvider.zip">download a compiled binary here</a>. All you need to do then is to unzip the archive to the “bin” folder within your site and set the web.config values to your preference.</p>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=101&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2008/06/24/text-image-generation-virtualpathprovider-for-episerver-and-aspnet-in-general-part-2-configuration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CogniScale &#8211; virtual hosting made easy</title>
		<link>http://blog.najmanowicz.com/2008/06/02/cogniscale-virtual-hosting-made-easy/</link>
		<comments>http://blog.najmanowicz.com/2008/06/02/cogniscale-virtual-hosting-made-easy/#comments</comments>
		<pubDate>Mon, 02 Jun 2008 21:10:03 +0000</pubDate>
		<dc:creator>Adam Najmanowicz</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Downloadable]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[Internet Information Services]]></category>
		<category><![CDATA[Microsoft SqlServer]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web applications]]></category>

		<guid isPermaLink="false">http://blog.najmanowicz.com/2008/06/02/cogniscale-virtual-hosting-made-easy/</guid>
		<description><![CDATA[We&#8217;ve not been talking much about it and that&#8217;s partially my fault as well (busy with other projects), but Cognifide has a really cool initiative called Cognifide Labs that we intend to grow over time. The plan is to devote up to 10% company time into side projects that help us grow expertise and allow [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve not been talking much about it and that&#8217;s partially my fault as well (busy with other projects), but <a href="http://www.cognifide.com/">Cognifide</a> has a really cool initiative called <a href="http://labs.cognifide.com/">Cognifide Labs</a> that we intend to grow over time. The plan is to devote up to 10% company time into side projects that help us grow expertise and allow our devs to dwell into interesting technologies, methodologies and languages and develop their skills.</p>
<p>One of the first projects (that I took part in) is <a href="http://cogniscale.cognifide.com/">CogniScale</a> &#8211; an app that allows <a href="http://www.flexiscale.com/">FlexiScale</a> users to manage their servers. Here&#8217;s the story&#8230; </p>
<p>Being the agile company taking part in many <a href="http://www.episerver.com/">EPiServer</a> projects we never seem to have enough environments to test our web-apps and software in general in various scenarios. We find ourselves constantly reinstalling and trying to keep our servers in a state that can can at least remotely be called as stable. After all how many deployments and tearing down of various <a href="http://www.episerver.com/">EPiServer</a>, <a href="http://ccnet.thoughtworks.com/">CruiseControl</a>, <a href="http://www.jetbrains.com/teamcity/">TeamCity</a>, SQL Server and other &quot;I need to have&quot; apps can a server take before slowing down to a crawl or collapsing all together (that said I bow before our faithful THOTH for taking all the abuse it does). We definitely needed more servers! And we needed them now! </p>
<p>Early this year we&#8217;ve started to talk to the guys at XCalibre that came up with a great idea. What if you could have an unlimited amount of servers available for you at any given time? I mean really what if you could have 0 servers one day and the next day have a rich farm of servers for literally no cost, paying only when you power them up and not paying a bit if you take them down.&#160; This turned out to be quite a project for them that turned to materialize as FlexiScale. (<a href="http://flexiscale.com/about_us.html">you can read more about it here</a>). Looking at all that I&#8217;ve mentioned before while eliminating the cost of maintaining the servers locally we decided to give FlexiScale a spin. </p>
<p><span id="more-97"></span></p>
<p>Early this year FlexiScale published a set of API&#8217;s that we looked at and (being the geeks we are) tried to utilize it in a desktop application with a limited success. It turned out that the initial API was perfectly accessible from dynamically typed languages while statically typed languages like C# didn&#8217;t really get their love in the initial release :) So we started opening the support tickets and shortly after that establishing a lively dialogue with the great folks there. Let me tell you, the guys in the FlexiScale support are really an amazing and responsive bunch. Not only did we get the support and the fixes we needed for the language we chose but we also pretty much got all our suggestions implemented and added to the API&#8217;s.</p>
<p>Thus <a href="http://cogniscale.cognifide.com/">CogniScale</a> was born:</p>
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="470" alt="cogniscale" src="http://blog.najmanowicz.com/wp-content/uploads/2008/06/cogniscale_main_form.jpg" width="644" border="0" />&#160; </p>
<p>The app allows for easy powering up and down the servers (allowing you to describe the reason for the action) from a nice and shiny GUI as well as scheduling it with windows task scheduler through its command line interface. it allows you to connect using FTP or Remote Desktop as well as any other app you can run from command line (it features a custom command editor that allows you to configure any app to work with it) with a single click. The app also allows you to quickly go through the history of servers&#8217; maintenance to determine how often and for what reason were they taken on and off-line.</p>
<p>Should you decide that FlexiScale is your thing, please give <a href="http://cogniscale.cognifide.com/">CogniScale</a> a whirl and let us know what you think.</p>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=97&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2008/06/02/cogniscale-virtual-hosting-made-easy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Google Maps control (property) for EPiServer</title>
		<link>http://blog.najmanowicz.com/2007/04/10/google-maps-control-for-episerver/</link>
		<comments>http://blog.najmanowicz.com/2007/04/10/google-maps-control-for-episerver/#comments</comments>
		<pubDate>Tue, 10 Apr 2007 09:57:59 +0000</pubDate>
		<dc:creator>Adam Najmanowicz</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Downloadable]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web applications]]></category>

		<guid isPermaLink="false">http://blog.najmanowicz.com/2007/04/10/google-maps-control-for-episerver/</guid>
		<description><![CDATA[Since my effort towards making this control final has been somewhat limited lately, I&#8217;ve decided to simply release the code at its current stage so that others can play with it and perhaps we can have something decent done together. The control operation is described in my previous article therefore I will not be going [...]]]></description>
			<content:encoded><![CDATA[<p>Since my effort towards making this control final has been somewhat limited lately, I&#8217;ve decided to simply release the code at its current stage so that others can play with it and perhaps we can have something decent done together. The control operation is described in my <a href="http://blog.najmanowicz.com/2007/03/23/google-map-control-and-why-episerver-is-so-cool/">previous article</a> therefore I will not be going much into it any longer. the deployment of it is something worth mention though&#8230;</p>
<p>Download the control form <a href="http://www.najmanowicz.com/blog_bin/Cognifide.EPiServerControls.GoogleMaps.zip">here</a>.&nbsp;Extract the contents of the zip file to a folder and attach the project to your solution, make sure you have the proper EPiServer libraries referenced form the project or it may complain about the references being broken.</p>
<p>Once you have it compiling, copy the <strong>GoogleMapEditor.ascx</strong>,<strong> GoogleMapViewer.ascx</strong> and the contents of the <strong>resources</strong> folder to&nbsp;a folder named <strong>GoogleMap</strong> within your project folder. Also copy the contents of the <strong>lang</strong> folder to the <strong>lang</strong> folder of your site. </p>
<p>The controls the property instantiate try to be smart about resolving the location of its files, but the property does not know its location thus if you decide to place the scripts in a folder other than just GoogleMaps in the app main folder, you need to add to your web.config the following:</p>
<pre style="font-size: 8pt; background: white; color: black; font-family: courier new"><span style="color: blue">&lt;</span><span style="color: #a31515">add</span><span style="color: blue"> </span><span style="color: red">key</span><span style="color: blue">=</span>"<span style="color: blue">CogGoogleMapControlLocation</span>"<span style="color: blue"> </span><span style="color: red">value</span><span style="color: blue">=</span>"<span style="color: blue">\GoogleMaps\</span>"<span style="color: blue"> /&gt;</span></pre>
<p>And in <strong>web.config</strong> you define the API keys for all the addresses the control will be available from as &#8220;<span style="color: blue">CogGoogleMapApiKey_%HOSTNAME%</span>&#8221; values. </p>
<p>e.g. set for my machine <strong>localhost</strong> (for me) &amp;&nbsp;<strong>dune</strong>(for access from other computers within our network):</p>
<pre style="font-size: 8pt; background: white; color: black; font-family: courier new"><span style="color: blue">&lt;</span><span style="color: #a31515">add</span><span style="color: blue"> </span><span style="color: red">key</span><span style="color: blue">=</span>"<span style="color: blue">CogGoogleMapApiKey_localhost</span>"<span style="color: blue"> </span><span style="color: red">value</span><span style="color: blue">=</span>"<span style="color: blue">A value generated for 'localhost'</span>"<span style="color: blue"> /&gt;</span>
<span style="color: blue">&lt;</span><span style="color: #a31515">add</span><span style="color: blue"> </span><span style="color: red">key</span><span style="color: blue">=</span>"<span style="color: blue">CogGoogleMapApiKey_dune</span>"<span style="color: blue"> </span><span style="color: red">value</span><span style="color: blue">=</span>"<span style="color: blue"><span style="color: blue">A value generated for 'dune'</span></span>"<span style="color: blue"> /&gt;</span></pre>
<p>The controls determine by themselves which key to use based on the http request so that the Google API does not complain about the key being improper.</p>
<p>Other than this the control should be self registering and all you need to do is to add it to your Page Type in the Admin section of the site and add:</p>
<pre style="font-size: 8pt; background: white; color: black; font-family: courier new"><span style="color: blue">&lt;</span><span style="color: #a31515">EPiServer</span><span style="color: blue">:</span><span style="color: #a31515">Property</span> <span style="color: red">ID</span><span style="color: blue">="GoogleMapData"</span> <span style="color: red">runat</span><span style="color: blue">="server"</span> <span style="color: red">PropertyName</span><span style="color: blue">="GoogleMapData"</span> <span style="color: blue">/&gt;</span></pre>
<p>to the template you want to use it with.</p>
<p>The control really needs an improved support for translation the stuff currently there is used for learning more that than to actually be useful. Should we decide to go further with it, it definitely will be extended.</p>
<p>The scripts used for the DOPE editing are released under GPL (the scripts were originally released with the MediaWiki GoogleMaps editor under the same license). Those scripts although modified slightly are also released under GPL and are NOT a part of the control &#8211; they just happen to be used by it. I am still trying to decide what license use with the rest of the control, so be aware that this is still a subject to be changed, for now just feel free to use the code and should you make any changes to it, please feed them back so that I can improve the control further. The control will most probably end up as a part of Epicode, as soon as I get a response on the epicode forums from Steve on how to add them.</p>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=64&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2007/04/10/google-maps-control-for-episerver/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Effortless Page Comments in EPiServer using ObjectStore.</title>
		<link>http://blog.najmanowicz.com/2007/04/06/effortless-page-comments-in-episerver-using-objectstore/</link>
		<comments>http://blog.najmanowicz.com/2007/04/06/effortless-page-comments-in-episerver-using-objectstore/#comments</comments>
		<pubDate>Fri, 06 Apr 2007 12:45:26 +0000</pubDate>
		<dc:creator>Adam Najmanowicz</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Downloadable]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web applications]]></category>

		<guid isPermaLink="false">http://blog.najmanowicz.com/2007/04/06/effortless-page-comments-in-episerver-using-objectstore/</guid>
		<description><![CDATA[To finalize my mini series on the object store I&#8217;d like to put a simple page comments library. The library takes care of everything that is required for you to post and retrieve a list of comments. It does not (so far) offer any moderation functionality or even facilitates any comments removal. It&#8217;s something that [...]]]></description>
			<content:encoded><![CDATA[<p>To finalize my mini series on the object store I&#8217;d like to put a simple page comments library. The library takes care of everything that is required for you to post and retrieve a list of comments. It does not (so far) offer any moderation functionality or even facilitates any comments removal. It&#8217;s something that I will most probably be added in the process. </p>
<p>I am in the process of figuring out how I can contribute it through the Community&nbsp;<a href="https://www.coderesort.com/projects/epicode/">EpiCode</a> effort on <a href="https://www.coderesort.com/">CodeResort</a>. As soon as I get some answers from Steve, I&#8217;ll get it uploaded there. In the mean time let me document how to start using it.</p>
<p>For the time being you can get the <a title="Source code" href="http://www.najmanowicz.com/blog_bin/Cognifide.EPiServerControls.PageComments_source.zip" rel="nofollow">code here</a><a href=""></a> or the <a title="Compiled Library" href="http://www.najmanowicz.com/blog_bin/Cognifide.EPiServerControls.PageComments_bin.zip">compiled library</a> with the intellisense help form <a title="Compiled Library" href="http://www.najmanowicz.com/blog_bin/Cognifide.EPiServerControls.PageComments_bin.zip">here</a>.</p>
<h2>Posting comments</h2>
<p>the posting is somewhat manual in terms of not having a pre-made control for it. Which if you look at the code does not have much sense to have.</p>
<p>All you need to do is put two edit boxes on a page and a submit button, and then bind the action of the submit button to a code looking somewhat like:</p>
<pre style="font-size: 8pt; background: white; color: black; font-family: courier new">
<span style="color: blue">protected</span> <span style="color: blue">void</span> SubmitComment(<span style="color: blue">object</span> sender, System.<span style="color: #2b91af">EventArgs</span> e)
{
    <span style="color: #2b91af">IPageComment</span> newComment =
        <span style="color: #2b91af">PageCommentFactory</span>.createInstance(<span style="color: #2b91af">Guid</span>.Empty,
        <span style="color: blue">string</span>.Format(<span style="color: #a31515">"CommentForPage{0}"</span>, CurrentPage.PageLink.ID),
        CurrentPage.PageLink.ID,
        SubjectTextBox.Text, ContentTextBox.Text, <span style="color: #2b91af">DateTime</span>.Now, <span style="color: blue">false</span>, <span style="color: blue">true</span>, <span style="color: blue">false</span>);
    newComment.Save();
}
</pre>
<p>I honestly don&#8217;t feel like making a custom control for creating those would be worthwhile since no one would end up using it anyway.</p>
<h2>The listing of comments however&#8230;</h2>
<p>The comments can be accessed in a number of ways.</p>
<p>Probably the easiest one would be by using the templated control I&#8217;ve written in the library, which is a simple descendant of the ASP.NET repeater. The page could would look something like:</p>
<pre style="font-size: 8pt; background: white; color: black; font-family: courier new">...

<span style="background: #ffee62">&lt;%</span><span style="color: blue">@</span> <span style="color: #a31515">Register</span> <span style="color: red">TagPrefix</span><span style="color: blue">="CognifideControls"</span>
    <span style="color: red">Namespace</span><span style="color: blue">="Cognifide.EPiServerControls.PageComments.Controls"</span>
    <span style="color: red">Assembly</span><span style="color: blue">="Cognifide.EPiServerControls.PageComments"</span> <span style="background: #ffee62">%&gt;</span>

...

<span style="color: blue">&lt;</span><span style="color: #a31515">CognifideControls</span><span style="color: blue">:</span><span style="color: #a31515">PageCommentsList</span> <span style="color: red">ID</span><span style="color: blue">="CommentControl"</span> <span style="color: red">runat</span><span style="color: blue">="server"</span>
    <span style="color: red">PageLinkIdProperty</span><span style="color: blue">="</span><span style="background: #ffee62">&lt;%</span># CurrentPage.PageLink.ID <span style="background: #ffee62">%&gt;</span><span style="color: blue">"&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: #a31515">ItemTemplate</span><span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: #a31515">b</span><span style="color: blue">&gt;</span><span style="background: #ffee62">&lt;%</span><span style="color: blue">#</span> CommentControl.CurrentComment.Title <span style="background: #ffee62">%&gt;</span><span style="color: blue">&lt;/</span><span style="color: #a31515">b</span><span style="color: blue">&gt;</span> -
        <span style="background: #ffee62">&lt;%</span><span style="color: blue">#</span> CommentControl.CurrentComment.SubmitDate.ToString() <span style="background: #ffee62">%&gt;</span><span style="color: blue">&lt;</span><span style="color: #a31515">br</span> <span style="color: blue">/&gt;</span>
        <span style="background: #ffee62">&lt;%</span><span style="color: blue">#</span> CommentControl.CurrentComment.Content<span style="background: #ffee62">%&gt;</span><span style="color: blue">&lt;</span><span style="color: #a31515">br</span> <span style="color: blue">/&gt;&lt;</span><span style="color: #a31515">br</span> <span style="color: blue">/&gt;</span>
    <span style="color: blue">&lt;/</span><span style="color: #a31515">ItemTemplate</span><span style="color: blue">&gt;</span>
<span style="color: blue">&lt;/</span><span style="color: #a31515">CognifideControls</span><span style="color: blue">:</span><span style="color: #a31515">PageCommentsList</span><span style="color: blue">&gt;</span></pre>
<p>I&#8217;ve chose this way since that&#8217;s pretty much the standard way of adding controls that are defined in Episerver and just generally ASP.Net.</p>
<p>But nothing stops you from accessing the comments directly,&nbsp; and then filling in the data for the repeater yourself like:</p>
<pre style="font-size: 8pt; background: white; color: black; font-family: courier new"><span style="color: blue">&lt;</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">Repeater</span> <span style="color: red">ID</span><span style="color: blue">="CurrentComments"</span> <span style="color: red">runat</span><span style="color: blue">="server"</span>
    <span style="color: red">OnItemDataBound</span><span style="color: blue">="CurrentComments_ItemDataBound"&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: #a31515">ItemTemplate</span><span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: #a31515">b</span><span style="color: blue">&gt;&lt;</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">Label</span> <span style="color: red">ID</span><span style="color: blue">="CommentSubjectLabel"</span> <span style="color: red">runat</span><span style="color: blue">="server"&gt;&lt;/</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">Label</span><span style="color: blue">&gt;&lt;/</span><span style="color: #a31515">b</span><span style="color: blue">&gt;&lt;</span><span style="color: #a31515">br</span> <span style="color: blue">/&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">Label</span> <span style="color: red">ID</span><span style="color: blue">="CommentContentLabel"</span> <span style="color: red">runat</span><span style="color: blue">="server"&gt;&lt;/</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">Label</span><span style="color: blue">&gt;&lt;</span><span style="color: #a31515">br</span> <span style="color: blue">/&gt;&lt;</span><span style="color: #a31515">br</span> <span style="color: blue">/&gt;</span>
    <span style="color: blue">&lt;/</span><span style="color: #a31515">ItemTemplate</span><span style="color: blue">&gt;</span>
<span style="color: blue">&lt;/</span><span style="color: #a31515">asp</span><span style="color: blue">:</span><span style="color: #a31515">Repeater</span><span style="color: blue">&gt;</span></pre>
<p>And then in the code-behind</p>
<pre style="font-size: 8pt; background: white; color: black; font-family: courier new">
<span style="color: blue">protected</span> <span style="color: blue">void</span> Page_Load(<span style="color: blue">object</span> sender, <span style="color: #2b91af">EventArgs</span> e)
{
    <span style="color: #2b91af">List</span>&lt;<span style="color: #2b91af">IPageComment</span>&gt; comments =
        <span style="color: #2b91af">PageCommentFactory</span>.GetCommentsForPage(CurrentPage.PageLink.ID,
        <span style="color: #2b91af">DateTime</span>.MinValue, <span style="color: #2b91af">DateTime</span>.MaxValue, <span style="color: blue">true</span>);
    CurrentComments.DataSource = comments;
    CurrentComments.DataBind();
}

<span style="color: blue">protected</span> <span style="color: blue">void</span> CurrentComments_ItemDataBound(<span style="color: blue">object</span> sender, <span style="color: #2b91af">RepeaterItemEventArgs</span> e)
{
    <span style="color: #2b91af">IPageComment</span> comment = (e.Item.DataItem <span style="color: blue">as</span> <span style="color: #2b91af">IPageComment</span>);
    <span style="color: #2b91af">Label</span> commentSubjectLabel = (<span style="color: #2b91af">Label</span>)e.Item.FindControl(<span style="color: #a31515">"CommentSubjectLabel"</span>);
    <span style="color: blue">if</span> (comment != <span style="color: blue">null</span>)
    {
        commentSubjectLabel.Text = comment.Title;
    }

    <span style="color: #2b91af">Label</span> commentContentLabel = (<span style="color: #2b91af">Label</span>)e.Item.FindControl(<span style="color: #a31515">"CommentContentLabel"</span>);
    <span style="color: blue">if</span> (comment != <span style="color: blue">null</span>)
    {
        commentContentLabel.Text = comment.Content;
    }
}</pre>
<p>That&#8217;s pretty much what my implementation does anyway.</p>
<p>I hope to be able to put it up on CodeResort soon so that we can see what else could be done. Additionally my library allows for replacing the persistence provider, which we will probably have implemented using nHibernate to test its speed versus the ObjectStore. Should you be interested in providing some help with this, or adding come moderation code to the admin side of the site on top of the interface, it would definitely be greatly appreciated.</p>
<p>I have started implementing the Property based on the code so that it can be easily displayed on the editor&#8217;s page, but for now, I&#8217;ll have to delay it since we&#8217;ve got some other stuff to do related to the project I&#8217;m currently working on.</p>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=63&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2007/04/06/effortless-page-comments-in-episerver-using-objectstore/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Skype GeoLocation Tool</title>
		<link>http://blog.najmanowicz.com/2007/01/19/skype-geolocation-tool/</link>
		<comments>http://blog.najmanowicz.com/2007/01/19/skype-geolocation-tool/#comments</comments>
		<pubDate>Fri, 19 Jan 2007 13:40:40 +0000</pubDate>
		<dc:creator>Adam Najmanowicz</dc:creator>
				<category><![CDATA[.Net Framework]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Downloadable]]></category>
		<category><![CDATA[Lifestyle]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web applications]]></category>

		<guid isPermaLink="false">http://blog.najmanowicz.com/archives/52</guid>
		<description><![CDATA[Download source files &#8211; 103 Kb 
Download the Skype Geo Location tool &#8211; 52 Kb

Introduction
It&#8217;s a real joy to work in a international company, the problem we face are hardly ever matched by some locally based endeavours&#8230; 
As some of our friends here at work, you may choose to reveal your current location to your [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.najmanowicz.com/blog_bin/SkypeGeoLocation_Code.zip">Download source files &#8211; 103 Kb </a><br />
<a href="http://www.najmanowicz.com/blog_bin/SkypeGeoLocation.zip">Download the Skype Geo Location tool &#8211; 52 Kb</a></p>
<p><img src="http://www.najmanowicz.com/blog_bin/SkypeGeoLocation.png" alt="Application GUI" /></p>
<h2>Introduction</h2>
<p>It&#8217;s a real joy to work in a international company, the problem we face are hardly ever matched by some locally based endeavours&#8230; </p>
<p>As some of our friends here at work, you may choose to reveal your current location to your skype buddies. This is nice and easy since you can just put it in your name or description and everyone will see where you are.This poses a problem should you really travel frequently, it is more likely than not, that your location tag will be out of sync.  </p>
<p>As this is a something that happens for them once in a while I found it an interesting concept, fun  enough to be worth solving it :) </p>
<p>So how does one establish his location? Short of installing a GPS on your machine, I would suggest checking your IP address and translating it based on one of the available databases. </p>
<p>The thought process goes as follows&#8230; <a href="http://www.codeproject.com/useritems/Skype_IP_and_geo_location.asp">[Read about the technical guts of the application in my article at Code Project]</a></p>
<h2>The Convergence &#8211; The Application</h2>
<p>The application helps you maintain your location tag in your name so that whenever you travel to a different town your skype name/description will reflect it. </p>
<p>Disclaimer: The application uses <a href="http://geoiptool.com/">GeoIPTool</a> as its source of IP and geo-location. Visit <a href="http://geoiptool.com/">GeoIPTool</a> for a wide variety of web based geo-location tools.</p>
<p>It does not contain either any kind of tracking abilities other than it letting you to maintain your location tag. The application will not even change your location tag by itself but rather it will notify you that your location has changed and will allow you to change your tag with a simple press of a button.</p>
<p>Usage<br />
In your skype account set your name or description so that it has [] in it or press &#8220;Add location tab to&#8230;&#8221; in the application. Whenever the application will find those it will check if the text in the parenthesis matches your current location., if it does not it will suggest a new one and will highlight the relevant field red. You may set for this operation to be performed on every boot, you will however only be notified when/if your location actually changed.</p>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=52&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2007/01/19/skype-geolocation-tool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
