<?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; Open Source</title>
	<atom:link href="http://blog.najmanowicz.com/category/software-development/open-source/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>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>Simple registration for files served by EPiServer</title>
		<link>http://blog.najmanowicz.com/2009/03/12/simple-registration-for-files-served-by-episerver/</link>
		<comments>http://blog.najmanowicz.com/2009/03/12/simple-registration-for-files-served-by-episerver/#comments</comments>
		<pubDate>Thu, 12 Mar 2009 21:01: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[EPiCode]]></category>
		<category><![CDATA[EPiServer]]></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/03/12/simple-registration-for-files-served-by-episerver/</guid>
		<description><![CDATA[With the culture of knowledge sharing and open source spreading, everyone races to show they have something valuable that you may want. And while you may not ask for money for your content you may still want to get something in return, say a contact, an email address that’s verified (or not), to keep in [...]]]></description>
			<content:encoded><![CDATA[<p>With the culture of knowledge sharing and open source spreading, everyone races to show they have something valuable that you may want. And while you may not ask for money for your content you may still want to get something in return, say a contact, an email address that’s verified (or not), to keep in touch with the consumer of your content. </p>
<p>Yet a full fledged registration doesn’t seem like a proper thing to do – cluttering your EPiServer user repository with (let’s face it – for a large part fake or temporary email addresses that user create only to get your content).</p>
<p>While there may be a lot of ways to handle that (streaming it through a page Response.WriteFile might seem as one of the more obvious ones), I would like to show you a cleaner, simpler and more elegant way that I’ve come up with.</p>
<p>We really don’t want people to deep link to our files without them knowing the files are from our site, that’s just rude – so hiding them behind an obscure URL wouldn’t work (thus we cannot use the regular file providers). We’ve already establish that we don’t want to log them in, so setting file rights are useless. But I want all the benefits including client-side caching.</p>
<p>Basically the solution boils down to creating a thin layer over the File provider of our choice, in my case the versioning file provider. The only method we need to override in it is <strong>GetFile</strong>. I want to allow downloading for logged in users and I want to allow downloading for all users that have a “magic-cookie” set. If either of the conditions are met, the file just downloads using the underlying provider’s routines including all the logic EPiServer has put for caching and rights. But if neither of the requirements are met, the user is directed to a page of our choice. </p>
<p><span id="more-117"></span></p>
<pre>
<div style="font-family: courier new; background: white; color: black; font-size: 8pt"><span style="color: blue">public</span> <span style="color: blue">override</span> <span style="color: #2b91af">VirtualFile</span> GetFile(<span style="color: blue">string</span> virtualPath)
{
    <span style="color: blue">string</span> handledPath;

    <span style="color: blue">if</span> (TryGetHandledAbsolutePath(virtualPath, <span style="color: blue">out</span> handledPath))
    {
        <span style="color: blue">if</span> ((<span style="color: #2b91af">HttpContext</span>.Current.Profile != <span style="color: blue">null</span> &amp;&amp; !<span style="color: #2b91af">HttpContext</span>.Current.Profile.IsAnonymous) ||
            <span style="color: #2b91af">HttpContext</span>.Current.Request.Cookies.AllKeys.Contains(PASS_COOKIE_NAME))
        {
            <span style="color: blue">return</span> <span style="color: blue">base</span>.GetFile(virtualPath);
        }

        <span style="color: #2b91af">HttpContext</span>.Current.Response.Redirect(
            <span style="color: blue">string</span>.Format(registrationFormUrl,<span style="color: #2b91af">HttpContext</span>.Current.Server.HtmlEncode(virtualPath)));
        <span style="color: blue">return</span> <span style="color: blue">null</span>;
    }
    <span style="color: blue">return</span> Previous.GetFile(virtualPath);
}</div>
</pre>
<p>How you specify that page’s totally up to you, but there is a nice initialization routine called during the Virtual Path Provider loading phase where all of the settings that are specified in your relevant web.config VPP declaration are passed to you, why not use it? What you’ll need define your VPP in the web.config is what follows:</p>
<pre>
<div style="font-family: courier new; background: white; color: black; font-size: 8pt">
<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>&quot;<span style="color: blue">true</span>&quot;<span style="color: blue"> </span><span style="color: red">virtualName</span><span style="color: blue">=</span>&quot;<span style="color: blue">CookieEnabled</span>&quot;<span style="color: blue"> </span><span style="color: red">virtualPath</span><span style="color: blue">=</span>&quot;<span style="color: blue">~/CookieEnabled/</span>&quot;<span style="color: blue"> </span>
<span style="color: blue">     </span><span style="color: red">bypassAccessCheck</span><span style="color: blue">=</span>&quot;<span style="color: blue">false</span>&quot;<span style="color: blue"> </span><span style="color: red">name</span><span style="color: blue">=</span>&quot;<span style="color: blue">CookieEnabled</span>&quot;<span style="color: blue"> </span>
<span style="color: blue">     </span><span style="color: red">type</span><span style="color: blue">=</span>&quot;<span style="color: blue">Cognifide.EPiServer.CookieEnabledVirtualPathProvider.CookieEnabledVirtualPathProvider,Cognifide.EPiServer.CookieEnabledVirtualPathProvider</span>&quot;<span style="color: blue"> </span>
<span style="color: blue">     </span><span style="color: red">indexingServiceCatalog</span><span style="color: blue">=</span>&quot;<span style="color: blue">Web</span>&quot;<span style="color: blue"> </span><span style="color: red">physicalPath</span><span style="color: blue">=</span>&quot;<span style="color: blue">C:\vpp\Resources</span>&quot;<span style="color: blue"> </span>
<span style="color: blue">     </span><span style="color: red">RegistrationFormUrl</span><span style="color: blue">=</span>&quot;<span style="color: blue">/File-Asset-Request-Form/?filepath={0}</span>&quot;<span style="color: blue"> /&gt;</span>
</div>
</pre>
<p>
  <br />you can then define your class as:</p>
<pre>
<div style="font-family: courier new; background: white; color: black; font-size: 8pt">
<span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">CookieEnabledVirtualPathProvider</span> : <span style="color: #2b91af">VirtualPathVersioningProvider</span>
{
    <span style="color: blue">private</span> <span style="color: blue">const</span> <span style="color: blue">string</span> REGISTRATION_FORM_URL_WEB_CONFIG_PARAM_NAME = <span style="color: #a31515">&quot;RegistrationFormUrl&quot;</span>;
    <span style="color: blue">public</span> <span style="color: blue">const</span> <span style="color: blue">string</span> PASS_COOKIE_NAME = <span style="color: #a31515">&quot;ResourcePass&quot;</span>;
    <span style="color: blue">private</span> <span style="color: blue">string</span> registrationFormUrl;

    <span style="color: blue">public</span> CookieEnabledVirtualPathProvider(<span style="color: blue">string</span> name, <span style="color: #2b91af">NameValueCollection</span> configParameters) :
        <span style="color: blue">base</span>(name, configParameters)
    {
        registrationFormUrl = configParameters[REGISTRATION_FORM_URL_WEB_CONFIG_PARAM_NAME];
    }

    ...

}
</div>
</pre>
<p>So we know now where we want to direct people without a “magic-cookie” who want to get our assets, and how to do it, but how do we finally allow that file to get down to them?</p>
<p>In your page – for the same of simplicity I assume you will be using XForms for gathering the user data, but that really does not matter. When you validate the form data (or get the user to click on a link that you’ve sent them) you just set the “magic” cookie that I called “ResourcePass” to any value and to to expire in some a long amount of time, like a year. So that they can now access your files unrestrained and direct them BACK at the URL they came from – and now the VPP will allow them to just download the file they initially requested:</p>
<pre>
<div style="font-family: courier new; background: white; color: black; font-size: 8pt">
<span style="color: blue">protected</span> <span style="color: blue">void</span> XForm_BeforeSubmitPostedData(<span style="color: blue">object</span> sender, <span style="color: #2b91af">SaveFormDataEventArgs</span> e)
{
    <span style="color: blue">if</span> (!Page.IsValid)
    {
        e.CancelSubmit = <span style="color: blue">true</span>;
    }
    <span style="color: blue">else</span>
    {
        <span style="color: blue">string</span> requestedFile = Request.Params[<span style="color: #a31515">&quot;filepath&quot;</span>];
        <span style="color: #2b91af">HttpCookie</span> cookie = <span style="color: blue">new</span> <span style="color: #2b91af">HttpCookie</span>(<span style="color: #2b91af">CookieEnabledVirtualPathProvider</span>.PASS_COOKIE_NAME, <span style="color: #a31515">&quot;true&quot;</span>);
        cookie.Expires = <span style="color: #2b91af">DateTime</span>.Now.AddYears(1);
        cookie.HttpOnly = <span style="color: blue">true</span>;
        Response.Cookies.Add(cookie);
        <span style="color: blue">if</span> (!<span style="color: blue">string</span>.IsNullOrEmpty(requestedFile))
        {
            Response.Redirect(requestedFile);
        }
    }
}
</div>
</pre>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=117&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2009/03/12/simple-registration-for-files-served-by-episerver/feed/</wfw:commentRss>
		<slash:comments>4</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 1</title>
		<link>http://blog.najmanowicz.com/2008/06/23/text-image-generation-virtualpathprovider-for-episerver-and-aspnet-in-general-part-1/</link>
		<comments>http://blog.najmanowicz.com/2008/06/23/text-image-generation-virtualpathprovider-for-episerver-and-aspnet-in-general-part-1/#comments</comments>
		<pubDate>Mon, 23 Jun 2008 18:00: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[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>

		<guid isPermaLink="false">http://blog.najmanowicz.com/2008/06/23/text-image-generation-virtualpathprovider-for-episerver-and-aspnet-in-general-part-1/</guid>
		<description><![CDATA[The module code is already available on Epicode SVN, the relevant wiki pages will be following as soon as documentation is complete.
The use case is as follows:

The client wants the site to look exactly as in a template provided as a image, 
the text is using a non standard font that is not available on [...]]]></description>
			<content:encoded><![CDATA[<p>The module code is already available on Epicode SVN, the relevant wiki pages will be following as soon as documentation is complete.</p>
<p>The use case is as follows:</p>
<ul>
<li>The client wants the site to look exactly as in a template provided as a image, </li>
<li>the text is using a non standard font that is not available on 60% of Windows machines, </li>
<li>the site does not use flash. </li>
<li>the site needs to be equally good looking in IE6 (more about it later) </li>
</ul>
<p>The solution was to generate images, but how to do it the right way? This has presented us with a once-in-a-lifetime :) opportunity to create a virtual path provider, do something good and learn something new &amp; cool in the process.</p>
<h2>Creating a new virtual path provider.</h2>
<p>this functionality in itself is fairly well <a href="http://msdn.microsoft.com/en-us/library/system.web.hosting.virtualpathprovider.aspx">documented on MSDN</a> one thing to pay attention to is to remember to pass the control to the next provider in the provider queue if your provider does not want to serve the request, so in my case:</p>
<pre>
<div style="font-size: 8pt; background: white; color: black; font-family: courier new">        <span style="color: blue">public</span> <span style="color: blue">override</span> <span style="color: #2b91af">VirtualFile</span> GetFile(<span style="color: blue">string</span> virtualPath)
        {
            <span style="color: blue">if</span> (IsPathVirtual(virtualPath))
                <span style="color: #2b91af">VirtualFile</span> file = <span style="color: blue">new</span> <span style="color: #2b91af">TextImageVirtualFile</span>(<span style="color: blue">this</span>, virtualPath);
                <span style="color: blue">return</span> file;
            <span style="color: blue">else</span>
                <span style="color: red"><strong>return Previous.GetFile(virtualPath);</strong></span>
        }</div>
</pre>
<p>this is necessary so you don’t have to have all-or nothing solution (your provider either serving everything the user requests or not being accessible at all) and honestly I’ve spent quite a while before I found out that… I was just being silly – thinking the technology by itself will resolve that ;)</p>
<p>If your Virtual path provider does not actually implement directories you don’t have to make the very provider to do a lot of complicated things. you are perfectly fine to limit the implementation to providing a custom constructor so that EPiServer passes you the configuration data and a couple of methods to tell whether a file is what you want to handle or not</p>
<pre>
<div style="font-size: 8pt; background: white; color: black; font-family: courier new"><span style="color: green">// this one is actually really cool - whatever values you set in your web.config </span>
<span style="color: green">// will be passed to you in the collection so you can really make your VPP </span></div>
<div style="font-size: 8pt; background: white; color: black; font-family: courier new"><span style="color: green">// as configurable as necessary</span>
<span style="color: blue">public</span> TextImageVirtualPathProvider(<span style="color: blue">string</span> name, <span style="color: #2b91af">NameValueCollection</span> configAttributes)</div>
<div style="font-size: 8pt; background: white; color: black; font-family: courier new">
<div style="font-size: 8pt; background: white; color: black; font-family: courier new"><span style="color: green">// This one resolves if the file can be generated</span>
<span style="color: blue">public</span> <span style="color: blue">override</span> <span style="color: blue">bool</span> FileExists(<span style="color: blue">string</span> virtualPath) { <span style="color: green">/* ... */</span> }

<span style="color: green">// Pretty much only passes the info that directory was not found </span>
<span style="color: green">// found if the virtual path matches a path that we should handle</span>
<span style="color: blue">public</span> <span style="color: blue">override</span> <span style="color: blue">bool</span> DirectoryExists(<span style="color: blue">string</span> virtualDir) {  <span style="color: green">/* ... */</span>  }

<span style="color: green">// Retrieves the virtual file that generates the image if the</span>
<span style="color: green">// Virtual path matches our pattern or disregards the request if it doesn't</span>
<span style="color: blue">public</span> <span style="color: blue">override</span> <span style="color: #2b91af">VirtualFile</span> GetFile(<span style="color: blue">string</span> virtualPath) {  <span style="color: green">/* ... */</span>  }

<span style="color: green">// Again this is only a pass through method as we don't support directories</span>
<span style="color: blue">public</span> <span style="color: blue">override</span> <span style="color: #2b91af">VirtualDirectory</span> GetDirectory(<span style="color: blue">string</span> virtualDir) {  <span style="color: green">/* ... */</span> }</div>
</div>
</pre>
<p>Now that we have ASP passing the request to us we need to wonder how to format the request in a way that is intuitive to the user, I wanted the URL to be straightforward and follow the path of EPiServer’s friendly URL-S so that they are easily formed by editors. So how about:</p>
<p><a href="http://my.server.com/color/font-name/font-size/The%20text%20i%20want%20toprint.gif">http://my.server.com/color/font-name/font-size/The%20text%20i%20want%20to%20print.gif</a></p>
<p>Ok.. well…, that won’t fly for GIFs &#8211; the font will be plain ugly if I don’t use antialiasing and if I do I will have an ugly black background underneath it. The solution to that would be using translucent PNG (which the VPP supports) but IE6 does not support those with transparency without ugly hacks. So I need to replace the blacks with a hint so that it generates a background colour when it merges the background with the font for antialiasing. For the sake of this article let’s assume it was an easy switch (IT WASN’T!) and let’s extend the URL to:</p>
<p><a href="http://my.server.com/color/antialias-hint-color/font-name/font-size/the-text-i-want-to-print.gif">http://my.server.com/color/antialias-hint-color/font-name/font-size/The%20text%20i%20want%20to%20print.gif</a></p>
<p>But I need the font to be bold! Ok… ok…</p>
<p><a href="http://my.server.com/color/antialias-hint-color/font-name/font-size/font-formatting/The%20text%20i%20want%20to%20print.gif">http://my.server.com/color/antialias-hint-color/font-name/font-size/font-formatting/The%20text%20i%20want%20to%20print.gif</a></p>
</p>
<p>Can I have the image rotated too? Sigh….</p>
</p>
<p><a href="http://my.server.com/color/antialias-hint-color/font-name/font-size/font-formatting(optional)/transformatio(optional)/The%20text%20i%20want%20to%20print.gif">http://my.server.com/color/antialias-hint-color/font-name/font-size/font-formatting(optional)/transformatio(optional)/The%20text%20i%20want%20to%20print.gif</a></p>
<p>The image rotation follows the <a href="http://msdn.microsoft.com/en-us/library/system.drawing.rotatefliptype(VS.71).aspx">RotateFlipType enumeration</a> so you can specify any string that is defined in the <a href="http://msdn.microsoft.com/en-us/library/system.drawing.rotatefliptype(VS.71).aspx">MSDN documentation for the enumeration</a>.</p>
</p>
<p>A sample result for the URL:</p>
<p><a title="http://cms5.cognifide.com/TextImages/Blue/white/Courier%20New/40/BUI/rotate270flipnone/Hello$eol$from$eol$Cognifide!.gif" href="http://my.server.com/TextImages/Blue/white/Courier%20New/40/BUI/rotate270flipnone/Hello$eol$from$eol$Cognifide!.gif">http://my.server.com/TextImages/Blue/white/Courier%20New/40/BUI/rotate270flipnone/Hello$eol$from$eol$Cognifide!.gif</a></p>
<p>Will look as follows</p>
<p align="center"><a href="http://blog.najmanowicz.com/wp-content/uploads/2008/06/helloeolfromeolcognifide.png"><img title="Hello$eol$from$eol$Cognifide!" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="240" alt="Hello$eol$from$eol$Cognifide!" src="http://blog.najmanowicz.com/wp-content/uploads/2008/06/helloeolfromeolcognifide-thumb.png" width="124" border="0" /></a>&#160;</p>
<h2></h2>
<h2>For the curious</h2>
<p>The final string format matching regular expression looks as follows: </p>
<pre>
<div style="font-size: 8pt; background: white; color: black; font-family: courier new"><span style="color: #2b91af">Regex</span> regex = <span style="color: blue">new</span> <span style="color: #2b91af">Regex</span>(
<span style="color: #a31515">    @&quot;^(?&lt;colour&gt;                  # The first match - starting form the beginning of the string</span></div>
<div style="font-size: 8pt; background: white; color: black; font-family: courier new"><span style="color: #a31515">    ([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[a-zA-Z]*))   # match either a 6 hex digit string or a name of a known color - this is for text color</span>
<span style="color: #a31515">    /                             # now we expect the first separating slash</span>
<span style="color: #a31515">    (?&lt;hint&gt;                      # next match group is about background hint for antialiasing</span>
<span style="color: #a31515">    ([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[a-zA-Z]*))   # match either a 3 or 6 hex digit string or a name of a known color - this is for antialiasing color hint</span>
<span style="color: #a31515">    /                             # again separating slash</span>
<span style="color: #a31515">    (?&lt;font&gt;[\w\s]*)              # font family name - accept white spaces</span>
<span style="color: #a31515">    /                             # yet another separating slash</span>
<span style="color: #a31515">    (?&lt;size&gt;[\d]{0,3})            # font size </span>
<span style="color: #a31515">    /                             # oh noes! another slash!</span>
<span style="color: #a31515">    ((?&lt;style&gt;[BIUSRN\s]*)        # font style Bold, Italic, Underline, Strikethrough</span>
<span style="color: #a31515">    /){0,1}                       # this group is optional.</span>
<span style="color: #a31515">    ((?&lt;transform&gt;[\w]*)          # transformation name as specified with System.Drawing.RotateFlipType - this group is optional</span>
<span style="color: #a31515">    /){0,1}                       # this group is optional too.</span>
<span style="color: #a31515">    (?&lt;text&gt;[\s\S]*[^\.])         # the text to render - basically anything but a dot - use relacement strings for dots</span>
<span style="color: #a31515">    [\.]                          # separating dot - now that's a nice change!</span>
<span style="color: #a31515">    (?&lt;extension&gt;(png|gif))       # the file extension - so that we know whether to generate png or gif</span>
<span style="color: #a31515">    $                             # everything comes to an end  </span>
<span style="color: #a31515">    &quot;</span>,
    <span style="color: #2b91af">RegexOptions</span>.Compiled | <span style="color: #2b91af">RegexOptions</span>.IgnoreCase | <span style="color: #2b91af">RegexOptions</span>.IgnorePatternWhitespace | <span style="color: #2b91af">RegexOptions</span>.CultureInvariant);</div>
</pre>
<p>&#160;</p>
<h2>Usability concerns</h2>
<p>The Colours can be provided as both named Colours (red, green, etc..) or html hex formatted colours (e.g. ff00bb, fob, fff, badfoo) both 6 and 3 hex digits strings are accepted.</p>
<p>The URL accepts spaces, and whatever text string that cannot be passed as a part of the url or is invalidated by EPiServer can be escaped by defining a token for it in web.config so for example as you can see in the above url the end of line “\n” character has been escaped into $eol$.</p>
<p>Obviously the font selection is limited to what is installed on your server.</p>
<h2>Performance concerns</h2>
<p>The basic concern that comes to mind is – how does this impact the server performance if the image is generated every time? Even though the performance impact seemed to be negligible I’ve decided to cache content. These things simply pile up if you have a high load site so why take the chance? Once an URL is called it is saved on first generation asserting the uniqueness of each parameter. Colours like black and 000 will be treated as same colour and cached only once. </p>
<h2>Security concerns</h2>
<p>So what was done to prevent our server to be an open server for generating images for everyone on the Internet? The VPP only allows for the images to be generated if the request referrer is in a domain or a host that is specified in the web.config. Additionally for testing you can enable the referrer to be null (direct call to images, as opposed to referring to them from a page). </p>
<p>Also as a seconds line of defence, it’s wise to define the cache folder on a share with a quota so we don’t get our server filled up with images should the referrer limiting measure fail for some reason.</p>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=100&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2008/06/23/text-image-generation-virtualpathprovider-for-episerver-and-aspnet-in-general-part-1/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Episerver&#8217;s brand new blogger</title>
		<link>http://blog.najmanowicz.com/2008/03/04/episervers-brand-new-blogger/</link>
		<comments>http://blog.najmanowicz.com/2008/03/04/episervers-brand-new-blogger/#comments</comments>
		<pubDate>Tue, 04 Mar 2008 14:56:28 +0000</pubDate>
		<dc:creator>Adam Najmanowicz</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Blogging]]></category>
		<category><![CDATA[EPiCode]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[Faceted Navigation]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://blog.najmanowicz.com/2008/03/04/episervers-brand-new-blogger/</guid>
		<description><![CDATA[I&#8217;m really glad to notice that Marek is getting into blogging about EPiServer. Marek is a really bright developer and a colleague at Cognifide with a number of successful EPiServer projects in his portfolio, we&#8217;ve worked together on Faceted Navigation (he&#8217;s the brain behind all the nifty editors in it) that I&#8217;m working on open [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m really glad to notice that <a href="http://marekblotny.blogspot.com/">Marek</a> is getting into blogging about <a href="http://www.episerver.com/">EPiServer</a>. Marek is a really bright developer and a colleague at <a href="http://www.cognifide.com/">Cognifide</a> with a number of successful EPiServer projects in his portfolio, we&#8217;ve worked together on Faceted Navigation (he&#8217;s the brain behind all the nifty editors in it) that I&#8217;m working on open sourcing of currently, and on the <a href="http://www.setantasports.com/">Setanta Sports Portal</a> and the <a href="http://www.setanta.com/">Setanta corporate</a> site projects. Now he&#8217;s out in the wild writing about it. Go ahead and read his analysis on the <a href="http://marekblotny.blogspot.com/2008/03/episerver-5-vs-episerver-461-part-i.html">performance of Episerver 4.x versus CMS 5</a>. It appears that the CMS is getting&#8230; nah&#8230; I won&#8217;t spoil it for you&#8230; Read all about it on <a href="http://marekblotny.blogspot.com/">Marek&#8217;s brand new blog</a>!</p>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=92&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2008/03/04/episervers-brand-new-blogger/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Faceted Service Structure</title>
		<link>http://blog.najmanowicz.com/2008/01/24/faceted-service-structure/</link>
		<comments>http://blog.najmanowicz.com/2008/01/24/faceted-service-structure/#comments</comments>
		<pubDate>Thu, 24 Jan 2008 16:18:33 +0000</pubDate>
		<dc:creator>Adam Najmanowicz</dc:creator>
				<category><![CDATA[.Net Framework]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[EPiCode]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[Faceted Navigation]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web applications]]></category>

		<guid isPermaLink="false">http://blog.najmanowicz.com/2008/01/24/faceted-service-structure/</guid>
		<description><![CDATA[This article is a part of the series describing the faceted navigation system for EPiServer that we have developed in Cognifide and that&#8217;s already proven to be a robust solution for delivering tagged content a heavy traffic site. The engine will be released shortly as an open source project.
So how is the faceted engine structured?

 [...]]]></description>
			<content:encoded><![CDATA[<p>This article is a part of the <a href="http://blog.najmanowicz.com/category/episerver/faceted-navigation/">series describing the faceted navigation system for EPiServer</a> that we have developed in <a href="http://www.cognifide.com/">Cognifide</a> and that&#8217;s already proven to be a robust solution for delivering tagged content a heavy traffic site. The engine will be released shortly as an open source project.<br />
<h2>So how is the faceted engine structured?</h2>
</p>
<p align="center"><a href="http://blog.najmanowicz.com/wp-content/uploads/2008/01/facetednavigationschema.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="195" alt="FacetedNavigationSchema" src="http://blog.najmanowicz.com/wp-content/uploads/2008/01/facetednavigationschema-thumb.png" width="244" border="0"/></a> </p>
<p><span id="more-91"></span></p>
<h2>Content provider</h2>
<p>As you can see the driving force behind the engine is the Facet Tagged Content Provider. If you know EPiServer, the basic functionality of the module is roughly an an equivalent of find page with criteria for categories, which allows for searching pages tagged with facets with exclusion of some other facets and tagged some optional data, the module however is paging and and allows you to plug a feedback event handler so that your controls can accept or deny a story before they are sent to is and take part in the paging. The stories are provided to you in reverse order of publishing so you always get the latest stories first, (pretty much what any blog and any news site wants).</p>
<p>Another function of the content provider is assertion of story uniqueness on the page. This is actually a pretty cool mechanism that deserves closer attention.</p>
<p>Let&#8217;s imagine a page having a control with &#8220;main story&#8221; that is pre-selected by an editor, and then some &#8220;featured stories&#8221; also pre-selected, then there is a control with &#8220;latest news concerning facet A&#8221; and a &#8220;latest news concerning facet B&#8221;. The problem with this scenario is that if a story was pre-selected for the &#8220;main story&#8221; and perhaps then someone added it to &#8220;featured stories&#8221;, and the story actually is tagged by facet A and facet B &#8211; in a traditional search you would normally get it in all of the controls&#8230; not cool! </p>
<p>The solution that we&#8217;ve come up with is based on a free market rules. And the procedure is as follows:</p>
<ol>
<li>The request starts and the engine opens a bidding for articles.  </li>
<li>All the controls request their interest in stories by either providing the engine with pre-selected stories they would like to display or asking it to provide the freshest content based on the facets the content is tagged with. They also provide it with their value (priority). And a callback for the engine to provide them with the stories.  </li>
<li>The acceptance phase ends and the engine distributes the stories looking from the highest value controls down the list in the following way
<ul>
<li>when the control provide the list of articles if so check for each article if it has not been taken yet, and otherwise feed it back to the control  </li>
<li>otherwise if the control provided it with the facets it&#8217;s &#8220;interested in&#8221; it asks the tagged content store for articles tagged with this context and feeds them to the control if they have not been otherwise provided to another control with higher priority, until it reaches the number requested by the control. (this way of providing articles also allows for paging).</li>
</ul>
</li>
<li>Upon satisfying all the controls the bidding is closed and all articles become available again.</li>
</ol>
<h2>Content Accelerator</h2>
<p>Content accelerator is a caching module that we have made mandatory that all of our EPiServer calls must pass through. The engine turns the pages into objects with a well defined and hard typed objects rather than a-bag-of-strings-and-the-likes your usual PageData is.</p>
<p>This makes it much more efficient for us to cache only the important data contained in any given page and only the data that we use frequently, e.g. page name and page URL that are used by URL provider and that are likely to be called multiple times within any given user request. This has been been implemented to compensate for the slowness of GetPage calls.</p>
<p>For that to work effectively we always tread content accelerator as a proxy for GetPage &#8211; which allows us to filter any expired or not yet published pages faster and refresh the content and accessibility for everyone, any time any given content is refreshed.</p>
<p>The For this concept to work &#8211; any page type that is going to be used in it has to have its own class added to it with the properties you will usually access (this however should be done with caution, for example you can cache article intro, but caching a potentially big article is a bad idea &#8211; also a full article text is very unlikely to be displayed on a high traffic page so caching all of your article full texts will not offset for a potential quick running out of memory).</p>
<p>Also the content cache is written using generics in a way that allows you to specify a multiple classes for any page types &#8211; the class consuming the cache defines how it wants to treat the content and access it. The different cache classes will then be chain linked and refreshed.</p>
<p>The content expires on an arbitrary set time (1 minute in our case but you can specify any other period), but we&#8217;ve also written a web service allowing for expiring a page-cache-item whenever it is changed on any of servers in a multiserver scenario. This for this to work &#8211; you have to plug into the global EPiServer event handlers. Which I&#8217;ll describe later.</p>
<p>The accelerator is used extensively by the faceted engine, but it can also be used directly and is completely independent of the rest of the faceted engine.</p>
<h2>Facet Context Provider</h2>
<p>This provides the control with ewasy facility to retrieve the facets with which the request was performed.</p>
<h2>Facet URL Provider</h2>
<p>This service allows you to construct URLs based on a facet context &#8211; with automatic determination of a preferred visualisation (hub page). Naturally you can still force the provider to format the URL for a pre-determined page. The effect will be a request that can later be succesfully parsed by the Context Provider once that URL is executed on the server.</p>
<h2>Auto Tagging Module</h2>
<p>This block which originally was a separate module is now basically shrunk to a single method that you can plug into EPiServer in the Global.asax. The routine tags a page with facets predefined in its parent, during the process of a page creation. This is useful for tagging e.g. all the &#8220;technology&#8221; stories with &#8220;technology&#8221; facet and an &#8220;News&#8221; facet once its created in the &#8220;Technology articles&#8221; branch.</p>
<h2>Furniture</h2>
<p>Part of the faceted navigation, but not directly part of the engine are editors for facet roles, the very facets and facet selectors.</p>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=91&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2008/01/24/faceted-service-structure/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Faceted Navigation Engine Nomenclature</title>
		<link>http://blog.najmanowicz.com/2008/01/24/faceted-navigation-engine-nomenclature/</link>
		<comments>http://blog.najmanowicz.com/2008/01/24/faceted-navigation-engine-nomenclature/#comments</comments>
		<pubDate>Thu, 24 Jan 2008 15:36:35 +0000</pubDate>
		<dc:creator>Adam Najmanowicz</dc:creator>
				<category><![CDATA[.Net Framework]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[EPiCode]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[Faceted Navigation]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web applications]]></category>

		<guid isPermaLink="false">http://blog.najmanowicz.com/2008/01/24/faceted-navigation-engine-nomenclature/</guid>
		<description><![CDATA[This article is the second of a series describing the faceted navigation system for EPiServer that we have internally developed in Cognifide, that&#8217;s already proven to be a robust solution for delivering tagged content a heavy traffic site, which will be released shortly as an open source project.
First of all we have to explain the [...]]]></description>
			<content:encoded><![CDATA[<p align="left">This article is the second of a <a href="http://blog.najmanowicz.com/category/episerver/faceted-navigation/">series describing the faceted navigation system for EPiServer</a> that we have internally developed in <a href="http://www.cognifide.com/">Cognifide</a>, that&#8217;s already proven to be a robust solution for delivering tagged content a heavy traffic site, which will be released shortly as an open source project.</p>
<p align="left">First of all we have to explain the nomenclature as it is going to be used quite a bit. A few terms we use pretty extensively are:</p>
<ul>
<li>
<div align="left">Facet &#8211; this is roughly an elaborate version of an EPiServer (or Wordpress) category. One of the problem with EPiServer category is that it is just that and absolutely nothing more. There is no way for attaching metadata and conditional structuring of the category tree. There is no way to assign them roles. Facets provide you with much, MUCH more.</div>
</li>
</ul>
<p><span id="more-88"></span></p>
<li>
<div align="left">Navigation space &#8211; Facets just like categories are structured in a tree, this is good for browsing them in a back end for tagging and organizing them. However we sometimes need to have a different view at facets structure based on the place we are in on the site. a good sample of that is <a href="http://www.setantasports.com/">Setanta Sports site</a>. you want to have a different navigation in the Sports (news) section and a different navigation when you browse blogs. Facets can have a different set of children and other facets that they expose based on the navigation space you are in.</div>
</li>
<li>
<div align="left">Facet collection &#8211; a simple set of any facets.</div>
</li>
<li>
<div align="left">Facet context &#8211; this is a special collection of facets possibly of many roles, but also abiding to the rules stated by Facet roles. Most notably a &#8220;current context&#8221; is a collection of facets the request has been performed with.</div>
</li>
<li>
<div align="left">Facet role &#8211; a facet can be a tagging unit like a category, but a facet can be much more. for that we came up with a concept of facet roles which allows us to profile facets:</div>
<ul>
<li>
<div align="left">ability to use for tagging &#8211; not all facets you necessarily want to be used for tagging. Some tags are indeed used to identify a content, but some tags play more utilitatian way like &#8220;locale&#8221; that we are in &#8211; you would not necessarily tag a content as being only available within a certain locale (although you might want to do that anyway), therefore a role &#8220;locale&#8221; may be set as not taggable. </div>
</li>
<li>
<div align="left">uniqueness &#8211; You may want to limit a role to only be able to has one of its member in any facet collection (IFacetrCollection). After all a user cannot be in 2 places at once so yet another logical extension for locale. Also request can only be performed within a context of one navigation space &#8211; therefore a navigation space representing tag need to be unique.</div>
</li>
<li>
<div align="left">separating facets of different roles &#8211; once you are presented with a context of tags, you may want to categorize them. e.g. to color a header in a control you may want to know which &#8220;sport&#8221; the tag represents.</div>
</li>
<li>
<div align="left">menu visibility &#8211; you may choose to display or not some tags in your navigation- this is the simplest way to specify that a meta-facets like say.. &#8220;flash video&#8221; should not generate a menu item as this is quite irrelevant to user.</div>
</li>
<li>
<div align="left">context mandatory &#8211; this indicates that any given context has to have at least one facet of that role &#8211; if a context does not have any of the facets of this role &#8211; a default facet for this role will be used. For example &#8211; a user cannot be placed in a null locale, he has to be &#8220;somewhere on earth&#8221;, doesn&#8217;t he? ;)</div>
</li>
<li>
<div align="left">availability for selection &#8211; this allows us to tell whether a facet can be used by editors and be visible on the site or whether it&#8217;s use is of more esoteric nature and the editor should not have it visible anywhere on the site &#8211; after all why would the editor want to see the navigation space representatives.</div>
</li>
<li>
<div align="left">System Role &#8211; this indicates that a role is crucial to the operation of the faceted navigation and as such should never be deleted.</div>
</li>
</ul>
</li>
<li>
<div align="left">Facet mappings &#8211; allows us to link facets to external id&#8217;s available outside the system. for example when you import an rss feed &#8211; you want to be able to always tag the articles from it with a proper facet &#8211; so for mapping &#8220;Rss Feeds&#8221; there will be mutually unique relation between a tag and a URL of the rss feed.</div>
</li>
<li>
<div align="left">Facet Navigation Info &#8211; allows the engine to specialize the facet structure within the navigation space &#8211; the navigation is a cross-section between a facet and a navigation space.</div>
</li>
<li>
<div align="left">Preferred Facet Hub Page &#8211; all facets can carry the information on what is their preferred page to be displayed(this is defined in the navigation info) . In any given context you don&#8217;t really care what page are you on &#8211; the page is just a visualisation of content that is defined by facets. But you may want your facet to cause a switch of this visualisation once it is becoming the dominating facet in the context (a facet with highest priority in the context) &#8211; So for any given set of facets &#8211; you query the URL provider with it and it will check the context and select the dominating facet and get the hub page for displaying the context from it. For example when you&#8217;re on a sports page and you click on a football &#8211; you want a more specialized page that might have some football tables on it rather than the generic sports page.</div>
</li>
<img src="http://blog.najmanowicz.com/?ak_action=api_record_view&id=88&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://blog.najmanowicz.com/2008/01/24/faceted-navigation-engine-nomenclature/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
