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

<channel>
	<title>Fabio&#039;s blog</title>
	<atom:link href="http://fbrz.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://fbrz.wordpress.com</link>
	<description>marketing &#124; technology</description>
	<lastBuildDate>Fri, 21 Jan 2011 11:41:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='fbrz.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Fabio&#039;s blog</title>
		<link>http://fbrz.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://fbrz.wordpress.com/osd.xml" title="Fabio&#039;s blog" />
	<atom:link rel='hub' href='http://fbrz.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Using EPiServer dynamic content to create a widget manager</title>
		<link>http://fbrz.wordpress.com/2010/12/17/using-episerver-dynamic-content-to-create-a-widget-manager/</link>
		<comments>http://fbrz.wordpress.com/2010/12/17/using-episerver-dynamic-content-to-create-a-widget-manager/#comments</comments>
		<pubDate>Fri, 17 Dec 2010 15:50:19 +0000</pubDate>
		<dc:creator>Fabio</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[EPiServer]]></category>

		<guid isPermaLink="false">http://fbrz.wordpress.com/2010/12/17/using-episerver-dynamic-content-to-create-a-widget-manager/</guid>
		<description><![CDATA[Dynamic content, a feature introduced in EPiServer 5, is very useful as it allows CMS users to effectively inject your code in the WYSIWYG editor. Unfortunately, there is no way of using this feature in a more controlled manner&#8230; unless you fancy rolling out your custom property to do that. What I wanted to achieve [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fbrz.wordpress.com&amp;blog=1748807&amp;post=59&amp;subd=fbrz&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Dynamic content, a feature introduced in EPiServer 5, is very useful as it allows CMS users to effectively inject your code in the WYSIWYG editor. Unfortunately, there is no way of using this feature in a more controlled manner&#8230; unless you fancy rolling out your custom property to do that.</p>
<p>What I wanted to achieve was to use dynamic content plug-ins like WordPress widgets or Umbraco macros; for example, when you have an area in your template where CMS users can add/edit/delete/sort dynamic content plug-ins, each one with its property setters. So after taking a look at the way the dynamic content dialogue works, I thought this would be easy to do with a simple custom property and some javascript / jquery.</p>
<h3>The custom property</h3>
<p>A simple override of the PropertyXhtmlString, using an .ascx control for the editing experience.</p>
<p><pre class="brush: csharp;">
  [Serializable]
  [PageDefinitionTypePlugIn(DisplayName = &quot;Features catalogue&quot;)]
  public class PropertyWidgetContainer : PropertyXhtmlString
  {
    public override IPropertyControl CreatePropertyControl()
    {
      return (IPropertyControl)BuildManager.CreateInstanceFromVirtualPath(&quot;~/templates/controls/features/widgetcontainer.ascx&quot;, typeof(WidgetContainer));
    }
  }
</pre></p>
<h3>The editing control (code behind)</h3>
<p>This is the default code which will render the property to the editor.</p>
<p><pre class="brush: csharp;">
  public partial class WidgetContainer : UserControlBase, IPropertyControl
  {
    public WidgetContainer()
    {
      Enabled = true;
    }

    public void SetupControl()
    {
      if (RenderType == RenderType.Edit)
      {
        EpiContext = &quot;{ \&quot;id\&quot;: \&quot;&quot; + CurrentPage.PageLink.ID + &quot;_&quot; + CurrentPage.PageLink.WorkID + &quot;\&quot;, \&quot;parentId\&quot;: \&quot;&quot; + CurrentPage.ParentLink.ID + &quot;\&quot;, \&quot;pageFolderId\&quot;: \&quot;&quot; + CurrentPage.Property[&quot;PageFolderID&quot;].Value + &quot;\&quot;, \&quot;epslanguage\&quot;: \&quot;&quot; + CurrentPage.LanguageBranch + &quot;\&quot; }&quot;;
        dataContainer.Text = (string)PropertyData.Value;
      }
    }

    public void ApplyChanges()
    {
      PropertyData.Value = dataContainer.Text;
    }

    public bool DisplayEditUI
    {
      get { return PropertyData.DisplayEditUI; }
    }

    public PropertyData PropertyData { get; set; }
    public PropertyDataCollection Properties { get; set; }
    public RenderType RenderType { get; set; }

    public TableRowLayout RowLayout
    {
      get { return TableRowLayout.Default; }
    }

    public string ValidationGroup { get; set; }
    public bool Enabled { get; set; }
    public string EpiContext { get; set; }
  }
</pre></p>
<h3>The editing control</h3>
<p>So far so good, a quick test of the basics is to have a textarea to input the source code of any dynamic content…</p>
<p><pre class="brush: xml;">
&lt;asp:textbox id=&quot;dataContainer&quot; textmode=&quot;MultiLine&quot; runat=&quot;server&quot; /&gt;
</pre></p>
<p>So I can run this, enter something like the html source generated by a dynamic content plug-in and save…</p>
<p><pre class="brush: xml;">
&lt;span classid=&quot;b30218a7-77fc-43dd-a844-81935aa9b35e&quot; dynamicclass=&quot;Simple text&quot; state=&quot;PHA+SnVzdCBzb21lIHRleHQgb24gdGhlIHJpZ2h0PC9wPg==|&quot; disabled=&quot;disabled&quot; contentEditable=&quot;false&quot;&gt;{DynamicContent:Simple text}&lt;/span&gt;
</pre></p>
<p>Now, if I can find a way of translating what&#8217;s in this textarea to a friendly interface, we&#8217;re basically there. JQuery to the rescue…</p>
<p><pre class="brush: xml;">
&lt;asp:textbox id=&quot;dataContainer&quot; textmode=&quot;MultiLine&quot; runat=&quot;server&quot; /&gt;
&lt;div class=&quot;epi-buttonDefault&quot;&gt;
  &lt;span class=&quot;epi-cmsButton&quot;&gt;&lt;input class=&quot;epi-cmsButton-text epi-cmsButton-tools epi-cmsButton-Add&quot; id=&quot;addplugin&quot; type=&quot;button&quot; /&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;table class=&quot;epi-default&quot; id=&quot;tableContainer&quot;&gt;
	&lt;thead&gt;
		&lt;tr class=&quot;header&quot;&gt;
			&lt;th&gt;Module&lt;/th&gt;
			&lt;th&gt;Actions&lt;/th&gt;
		&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;	
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/js/lib.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
  var tpl = '&lt;tr class=&quot;pluginRow&quot;&gt;' +
                    '&lt;td class=&quot;plugin&quot;&gt;%PLUGIN%&lt;/td&gt;' +
                    '&lt;td&gt;&lt;span class=&quot;epi-cmsButton&quot;&gt;&lt;input class=&quot;epi-cmsButton-tools epi-cmsButton-Delete&quot; type=&quot;button&quot;&gt;&lt;/span&gt;' +
                    '&lt;span class=&quot;epi-cmsButton&quot;&gt;&lt;input class=&quot;epi-cmsButton-tools epi-cmsButton-Edit&quot; type=&quot;button&quot;&gt;&lt;/span&gt;&lt;/td&gt;' +
                '&lt;/tr&gt;';

  var context = &lt;%= EpiContext %&gt;, data, table;
  jQuery(function () {
    var widgetMgr = new widgets.manager($('#&lt;%= dataContainer.ClientID %&gt;'), $('#&lt;%= tableContainer.ClientID %&gt;'), tpl);
    if (widgetMgr.data.val() != '') {
      var el = $('&lt;div /&gt;').append(widgetMgr.data.val());
      $('.dynamiccontent', el).each(function() {
        widgetMgr.addItem({ plugin: $('&lt;div /&gt;').append($(this)).html() });
      });
    }
    $('#&lt;%= addplugin.ClientID %&gt;').click(function (evt) {
      var args = { plugin: '', index: -1, instance: widgetMgr };
      EPi.CreateDialog(EPi.ResolveUrlFromUI('Editor/Dialogs/DynamicContent.aspx') + '?' +  $.param(context), widgetMgr.onDialogClosed, args, null, { width: 470, height: 380 });
      evt.preventDefault();
    });
  });
&lt;/script&gt;
</pre></p>
<p>The widgetManager javascript class takes care of doing most of the hard work…</p>
<p><pre class="brush: csharp;">
/**************************************************
* Widget manager for EPiServer, requires JQuery and the TableDnD plug-in for JQuery (for sorting)
***************************************************/
	widgets = {};
	widgets.manager = function (d, t, k) {
	  this.init(d, t, k);
	};
	widgets.manager.prototype = {
	  constructor: widgets.manager,
	  init: function (d, t, k) {
	    this.data = d.hide();
	    this.table = t.hide();
	    this.tpl = k;
	  },
	  data: null,
	  table: null,
	  tpl: '',
	  setItems: function () {
	    this.data.empty();
	    var el = $('&lt;div /&gt;');
	    $('.plugin', this.table).each(function () {
	      el.append($(this).html());
	    });
	    this.data.val(el.html());
	    if (this.data.val() === '') {
	      this.table.hide();
	    } else {
	      this.table.show();
	      this.bindTableEvents();
	    }
	  },
	  addItem: function (arguments) {
	    $('tbody', this.table).append($(this.tpl.replace('%PLUGIN%', arguments.plugin)));
	    this.setItems();
	  },
	  editItem: function (arguments) {
	    var tblrows = $('.pluginRow', this.table);
	    $(tblrows[arguments.index]).html($(this.tpl.replace('%PLUGIN%', arguments.plugin)).html());
	    this.setItems();
	  },
	  bindTableEvents: function () {
	    var instance = this;
	    var tblrows = $('.pluginRow', instance.table);
	    $('.epi-cmsButton-Delete', tblrows).unbind('click');
	    $('.epi-cmsButton-Delete', tblrows).click(function (evt) {
	      if (confirm(&quot;Are you sure?&quot;)) {
	        var tr = $(this).parents(&quot;tr:first&quot;);
	        tr.remove();
	        instance.setItems();
	      }
	      evt.preventDefault();
	    });
	    $('.epi-cmsButton-Edit', tblrows).unbind('click');
	    $('.epi-cmsButton-Edit', tblrows).click(function (evt) {
	      var tr = $(this).parents(&quot;tr:first&quot;);
	      var selectedNode = $('.dynamiccontent', tr);
	      var formString = '&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;&lt;head&gt;&lt;title&gt;&lt;/title&gt;&lt;/head&gt;&lt;body onload=&quot;document.forms[0].submit()&quot;&gt;' +
                    '&lt;form action=&quot;' + EPi.ResolveUrlFromUI('Editor/Dialogs/DynamicContent.aspx') + '?' + $.param(context) + '&quot; method=&quot;post&quot;&gt;' +
                    '&lt;input name=&quot;state&quot; type=&quot;hidden&quot; value=&quot;' + selectedNode.attr(&quot;state&quot;).replace(/&quot;/g, '&amp;quot;') + '&quot; /&gt;' +
                    '&lt;input name=&quot;hash&quot; type=&quot;hidden&quot; value=&quot;' + selectedNode.attr(&quot;hash&quot;).replace(/&quot;/g, '&amp;quot;') + '&quot; /&gt;' +
                    '&lt;input name=&quot;dynamicclass&quot; type=&quot;hidden&quot; value=&quot;' + selectedNode.attr(&quot;dynamicclass&quot;).replace(/&quot;/g, '&amp;quot;') + '&quot; /&gt;' +
                    '&lt;/form&gt;&lt;/body&gt;&lt;/html&gt;';
	      var args = { plugin: $('td:first', tr).html(), index: tblrows.index(tr), instance: instance };
	      var dialog = EPi.CreateDialog(EPi.ResolveUrlFromUI('Editor/Dialogs/DynamicContent.aspx') + '?' + $.param(context), instance.onDialogClosed, args, null, { width: 470, height: 380 });
	      dialog._dialog.document.write(formString);
	      dialog._dialog.document.close();
	      evt.preventDefault();
	    });
	    instance.table.tableDnD({
	      onDrop: function (table, row) {
	        instance.setItems();
	      }
	    });
	  },
	  onDialogClosed: function (returnObject, onCompleteArguments) {
	    if (!returnObject) {
	      return;
	    }
	    if (onCompleteArguments.index === -1) {
	      onCompleteArguments.plugin = returnObject;
	      onCompleteArguments.instance.addItem(onCompleteArguments);
	    } else {
	      onCompleteArguments.plugin = returnObject;
	      onCompleteArguments.instance.editItem(onCompleteArguments);
	    }
	  }
	};
</pre></p>
<p>Excellent, now I can add widgets…</p>
<p><img src="http://fbrz.files.wordpress.com/2010/12/121710_1550_usingepiser1.png?w=700" alt="" /></p>
<p><img src="http://fbrz.files.wordpress.com/2010/12/121710_1550_usingepiser2.png?w=700" alt="" /></p>
<p>… sort them with drag&#8217;n'drop, delete them, change their settings…</p>
<p><img src="http://fbrz.files.wordpress.com/2010/12/121710_1550_usingepiser3.png?w=700" alt="" /></p>
<p>… and so on.</p>
<p>When I view the saved version, the dynamic content plugins render as I expect them to do.</p>
<p><img src="http://fbrz.files.wordpress.com/2010/12/121710_1550_usingepiser4.png?w=700" alt="" /></p>
<h3>Limitations</h3>
<p>The dynamic content factory in the current EPiServer version does not allow you to provide an alternative implementation – one, for instance, where you can organise your dynamic content by user role or area, so limiting which plug-ins can be used by who or where.</p>
<h3>Other stuff</h3>
<p>I&#8217;ve been using the labs DCPlugin to make creation of plugins easier (<a href="http://labs.episerver.com/en/Blogs/Allan/Dates/2009/2/Turn-your-User-Controls-into-Dynamic-Content/">http://labs.episerver.com/en/Blogs/Allan/Dates/2009/2/Turn-your-User-Controls-into-Dynamic-Content/</a>) – I&#8217;ve recompiled it to address a Unicode character bug.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fbrz.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fbrz.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fbrz.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fbrz.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/fbrz.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/fbrz.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/fbrz.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/fbrz.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fbrz.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fbrz.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fbrz.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fbrz.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fbrz.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fbrz.wordpress.com/59/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fbrz.wordpress.com&amp;blog=1748807&amp;post=59&amp;subd=fbrz&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fbrz.wordpress.com/2010/12/17/using-episerver-dynamic-content-to-create-a-widget-manager/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/94e77199fcf00e9994a43d6a14bbe392?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fabrz</media:title>
		</media:content>

		<media:content url="http://fbrz.files.wordpress.com/2010/12/121710_1550_usingepiser1.png" medium="image" />

		<media:content url="http://fbrz.files.wordpress.com/2010/12/121710_1550_usingepiser2.png" medium="image" />

		<media:content url="http://fbrz.files.wordpress.com/2010/12/121710_1550_usingepiser3.png" medium="image" />

		<media:content url="http://fbrz.files.wordpress.com/2010/12/121710_1550_usingepiser4.png" medium="image" />
	</item>
		<item>
		<title>EPiServer and MVC</title>
		<link>http://fbrz.wordpress.com/2009/10/10/episerver-and-mvc/</link>
		<comments>http://fbrz.wordpress.com/2009/10/10/episerver-and-mvc/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 13:21:57 +0000</pubDate>
		<dc:creator>Fabio</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[EPiServer]]></category>
		<category><![CDATA[MVC]]></category>

		<guid isPermaLink="false">http://fbrz.wordpress.com/?p=11</guid>
		<description><![CDATA[Thanks to the great work of Joel Abrahamsson (here his first stab at the solution) and a little more prototyping, it looks like EPiServer and MVC can play together very well! Time to say goodbye to asp.net webforms templates on EPiServer? At Syzygy, we got this working with EPiServer 5.2.375.236 (the latest production version), MVC [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fbrz.wordpress.com&amp;blog=1748807&amp;post=11&amp;subd=fbrz&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Thanks to the <a href="http://pagetypebuilder.codeplex.com/">great work</a> of Joel Abrahamsson (here <a href="http://joelabrahamsson.com/post/2009/07/29/A-first-stab-at-EPiServer-CMS-with-ASPNET-MVC-and-Page-Type-Builder.aspx">his first stab</a> at the solution)  and a little more prototyping, it looks like EPiServer and MVC can play together very well! Time to say goodbye to asp.net webforms templates on EPiServer?</p>
<p>At Syzygy, we got this working with EPiServer 5.2.375.236 (the latest production version), MVC 1.0 and recompiled versions of the PageTypeBuilder and Castle DynamicProxy2 assemblies (the reason for this was to solve trust exceptions when the code was running from IIS 7.5).</p>
<p>The trick to get the EPiServer Friendly URL rewriter to play nicely with MVC is to use custom MvcHandler and IControllerFactory implementations: a wild-card style route can be passed to the custom handler which then will be able to:</p>
<ul>
<li>find out from EPiServer the ID of the content item (from the friendly URL)</li>
<li>load the page data</li>
<li>read custom properties of the page data such as &#8220;ControllerName&#8221; and &#8220;ActionName&#8221;</li>
<li>forward the page data to the correct controller / action through our controller factory</li>
</ul>
<p>So, in our prototype, we implemented the custom MVC handler with the following code:</p>
<p><pre class="brush: csharp;">
		protected override void ProcessRequest(HttpContextBase httpContext)
		{
			var internalUrlBuilder = GetInternalUrl(httpContext.Request.RawUrl);
			var mvcPage = CurrentPageResolver.Instance.GetCurrentPage(internalUrlBuilder.QueryCollection[&quot;id&quot;] ?? string.Empty);
			var controllerName = mvcPage.ControllerName;
			var actionName = mvcPage.ActionName;

			RequestContext.RouteData.Values.Add(&quot;action&quot;, actionName);
			RequestContext.RouteData.Values.Add(&quot;controller&quot;, controllerName);

			RequestContext.RouteData.Values[&quot;data&quot;] = mvcPage;

			var controller = ControllerBuilder.Current.GetControllerFactory().CreateController(RequestContext, controllerName);
			controller.Execute(RequestContext);
		}
</pre></p>
<p>This code will intercept the request, convert the raw URL (as generated by the EPiServer Friendly URL rewriter) into the internal EPiServer URL, which will give us the ID of the content item (or, when in edit mode, the ID followed by an underscore and the version ID – i.e. &#8220;the slug&#8221;).</p>
<p>At this point, we can use any custom class to call the EPiServer DataFactory and get the PageData object. In our custom CurrentPageResolver class, the page data is cast to the base class for all our page types (MvcPageData), which contains information about the controller and the action to use for rendering.</p>
<p><pre class="brush: csharp;">
using System;
using System.Collections.Generic;
using EPiServer;
using EPiServer.Core;
using MvcCms.Bases;

namespace MvcCms.Utilities
{
    public class CurrentPageResolver
    {
        private static readonly CurrentPageResolver instance = new CurrentPageResolver();

        private CurrentPageResolver()
        {
        }

        public static CurrentPageResolver Instance
        {
            get { return instance; }
        }

        public MvcPageData GetCurrentPage(string id)
        {
            if (String.IsNullOrEmpty(id))
            {
                return GetHomePage();
            }

            return IsWorkPage(id) ?
                           GetWorkPage(id) : GetPage(id);
        }

        private static bool IsWorkPage(string id)
        {
            return id.Contains(&quot;_&quot;);
        }

        private static MvcPageData GetWorkPage(string slug)
        {
            PageData page = null;

            string[] splitSlug = slug.Split(new[] {'_'}, StringSplitOptions.RemoveEmptyEntries);

            int pageId;
            if (splitSlug.Length &gt; 1 &amp;&amp; int.TryParse(splitSlug[0], out pageId))
            {
                int workPageId;
                if (int.TryParse(splitSlug[1], out workPageId))
                {
                    var workPageReference = new PageReference(pageId, workPageId);
                    page = DataFactory.Instance.GetPage(workPageReference);
                }
            }

            return page as MvcPageData;
        }

        protected MvcPageData GetPage(string id)
        {
            int pageId;
            if (int.TryParse(id, out pageId))
            {
                var pageReference = new PageReference(pageId);
                return DataFactory.Instance.GetPage(pageReference) as MvcPageData;
            }

            return null;
        }

        public static MvcPageData GetHomePage()
        {
            return DataFactory.Instance.GetPage(PageReference.StartPage) as MvcPageData;
        }

        public List&lt;MvcPageData&gt; GetChildren()
        {
            return GetChildren(GetHomePage().PageLink);
        }

        public List&lt;MvcPageData&gt; GetChildren(PageReference parent)
        {
            PageDataCollection pages = DataFactory.Instance.GetChildren(parent);
            var list = new List&lt;MvcPageData&gt;(pages.Count);
            foreach (PageData page in pages)
            {
                list.Add(page as MvcPageData);
            }
            return list;
        }
    }
}
</pre></p>
<p>Our page type base (MvcPageData) class looks like this:</p>
<p><pre class="brush: csharp;">
using System.Collections.Generic;
using MvcCms.Utilities;
using PageTypeBuilder;

namespace MvcCms.Bases
{
    public abstract class MvcPageData : TypedPageData
    {
        public abstract string ControllerName { get; }
        public virtual string ActionName
        {
            get
            {
                return &quot;Index&quot;;
            }
        }

        public string PageUrlSegment
        {
            get { return this.GetPropertyValue(page =&gt; page.PageUrlSegment); }
        }

        public virtual List&lt;MvcPageData&gt; Children
        {
            get
            {
                if (PageLink == StartPage.PageLink)
                {
                    return new List&lt;MvcPageData&gt;(0);
                }

                return CurrentPageResolver.Instance.GetChildren(PageLink);
            }
        }

        public virtual List&lt;MvcPageData&gt; SiteLinks
        {
            get { return CurrentPageResolver.Instance.GetChildren(StartPage.PageLink); }
        }

        public MvcPageData StartPage
        {
            get { return CurrentPageResolver.GetHomePage(); }
        }
    }
}
</pre></p>
<p>The custom controller factory will use the information that is contained in the route data to create the correct controller from the available ones. Once the controller is created, this will again be able to use the MvcPageData available in the route data (through a custom model binder), and pass it to a view.</p>
<p>The last step would be to wire up all the work in the global.asax, ignoring the requests to edit, admin, util and app_themes URLs. </p>
<p><pre class="brush: csharp;">
		protected void Application_Start(Object sender, EventArgs e)
		{
			ControllerBuilder.Current.SetControllerFactory(new MvcControllerFactory());
			ModelBinders.Binders.Add(typeof (MvcPageData), new PageDataModelBinder());

			RegisterRoutes(RouteTable.Routes);
		}

		public static void RegisterRoutes(RouteCollection routes)
		{
			routes.IgnoreRoute(&quot;{resource}.axd/{*pathInfo}&quot;);
			routes.IgnoreRoute(&quot;cms/{*pathInfo}&quot;);
			routes.IgnoreRoute(&quot;util/{*pathInfo}&quot;);
			routes.IgnoreRoute(&quot;app_themes/{*pathInfo}&quot;);

			routes.Add(new Route(&quot;{*data}&quot;, new WildCardRouteHandler()));
		}
</pre></p>
<p>In order to get the <a href="http://cid-3d3c147d60da8c06.skydrive.live.com/self.aspx/.Public/EPiServer-Mvc.zip">solution</a> working, you&#8217;ll need to follow the instructions in the readme.txt file. Any problems, contact me.</p>
<p>Enjoy!</p>
<p>Fabio</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fbrz.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fbrz.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fbrz.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fbrz.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/fbrz.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/fbrz.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/fbrz.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/fbrz.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fbrz.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fbrz.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fbrz.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fbrz.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fbrz.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fbrz.wordpress.com/11/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fbrz.wordpress.com&amp;blog=1748807&amp;post=11&amp;subd=fbrz&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://fbrz.wordpress.com/2009/10/10/episerver-and-mvc/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/94e77199fcf00e9994a43d6a14bbe392?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">fabrz</media:title>
		</media:content>
	</item>
	</channel>
</rss>
