Tuesday, June 10, 2008

Multiple Templates for a PageType

It looks like a Dev / Partner summit is the perfect birthplace for ideas to grow. Here is yet another idea that grew out of discussions with partners, eMVPs and other Guru's at the summit: It could be cool to have multiple renderings (templates) for a page type. Today several PageType's can share the same template, but it's not possible to specify more than one template to use for a given PageType - a feature which would be very handy when for instance you wanted to make a special set of templates to show your site to mobile users. Or perhaps just special templates for IE or Firefox. Or maybe just a "Printable" set of templates. In any case I think this can be an important building block in making flexible websites.

So, naturally the day after the summit (a bit hungover I must admit) I sat down and began coding. There's several ways to achieve this goal - VPP's being one of them, but to keep it simple I decided to just hook into the UrlRewriting and change the internal url for the pages before they were executed. I ended up with this simple prototype that can change the executing template for a page depending on the User Agent of the client. I'll supply both the source and the compiled versions below - but keep in mind that it's just a prototype and it IS PROVIDED AS IS.

In order to use it, place the assembly in your bin, and add the following to the section-registration of your web.config:

<section name="multiRenderings" type="EPiServer.Research.MultiRenderingSection, MultiRenderingPlugin" allowLocation="true"/>

Then, After the "episerver" section you can add a list of the renderings:

<multiRenderings>
  <renderings>
    <rendering name="IE" userAgent=".*MSIE.*"/>
  </renderings>
</multiRenderings>

This rendering above will try to execute the IE template for userAgents matching the regular expression: ".*MSIE.*" - meaning that all IE browsers will be sent to templates located in the "IE" subfolder (if such templates exist).

On my test site I have the following folder structure:

/      
  Templates    
    MyPage.aspx  
    MyPage2.aspx  
    IE  
      MyPage.aspx

 

When looking at a page that uses "MyPage.aspx" IE will be using the "MyPage.aspx" located in the "IE" folder, but since MyPage2.aspx doesn't exist there, MyPage2.aspx will fall back to the one in "Templates".

This will probably become a lot more elegant as the plugin evolves - but I think it already now might proof useful to some of you, which is why I post it here.

Download from labs.

Sunday, June 8, 2008

Busy Times

A lot of people has been asking me what I'm up to lately - and complaining that my posts aren't as frequent as they used to...
I know it's been way too long since I blogged on this blog. It's not because I have nothing to blog about - in fact every day a new interesting blog-topic springs to mind and I begin writing it...But before I finish it, work or family-life or another idea interferes and break away my concentration.

I just got back last friday from Sweden where I had spend more than a week. First I went to a terrific(!) partner summit and after that I stayed to work at the office with the rest of the Research team. Unfortunately I learned the hard way that I should stay away from local food when traveling to exotic places like Stockholm, so that took a couple of workdays out of my calendar.

At the summit I presented a Wiki built on EPiServer - one of the projects that's been taking a bit of my time lately. Soon I'll do a dedicated post about it - and put it public somehow.
Meanwhile I'm also working on a ton of other stuff - like a new version of EPiDiff, Defining design patterns for EPiServer, LINQ, and a couple of gadgets that I'll reveale in the coming weeks.

Sunday I'm leaving DK again and once again heading for Ukraine, where I'll get to meet our new team in Kiev as well as some developers from a Partner in Kharkov.

Thursday, February 21, 2008

Mixing ASP.NET MVC with an exisiting WebForms web application project

I had a chance last night to integrate the new cool asp.net MVC with a "normal" web application - it went rather painless. Read the recipe on my work-blog.

Thursday, February 14, 2008

Nightly Fun with 301

WARNING: GEEKY STUFF.

 

Do you ever have difficulty falling asleep at night, because your brain begins to code the moment your tired body hits the bed? Well, I do every once in a while. And then I know that I can either toss and turn all night or sneak downstairs and code for a while - just to get it out of my system.

Last night was one of those nights. This time, though, I decided to make something simple but useful. The idea had been in the back of my head ever since I visited a large client recently who was getting ready to move a big and popular web site in the media industry to EPiServer CMS 5.

Basically this is the classic problem that I'm trying to solve: When moving a web site to a new platform it often happens that the url to the individual pages changes which breaks links, search engine ranks and results in a lot of 404 errors. For instance, with Friendly URLS in EPiServer a page that used to be called "/articles/article124145.html" might now get the friendlier path"/News/New+Website+Launched/". So, my solution to this problem is simply a generic HttpModule that loads a series of old-path / new-path sets from a text-file when the web application is started and then makes a quick check for every request to see if it's actually an old URL being requested. If it is, it'll do the correct thing and send back an HTTP 301 Permanently Moved reply with the new location of the document. That way both global search engines and various caches should get updated and no links will be broken. Simple, but it seems to work - and to my luck it was so easy to code that I still got most of a good nights sleep.

 

    public class RedirectModule : IHttpModule
{
private Dictionary<string, string> map;

public void Init(HttpApplication app)
{
app.BeginRequest += new EventHandler(app_BeginRequest);
map = new Dictionary<string, string>();
//Load from file
StreamReader sr = File.OpenText(ConfigurationManager.AppSettings["UrlMapping"]);
string s = null;
while ((s = sr.ReadLine()) != null)
{
string[] parts = s.Split('|');
if(parts.Length==2) map.Add(parts[0], parts[1]);
}
sr.Close();
}

void app_BeginRequest(object sender, EventArgs e)
{
HttpApplication app = (sender as HttpApplication);
if (map.ContainsKey(app.Request.Url.LocalPath))
{
app.Response.Status = "301 Moved Permanently";
app.Response.AddHeader("Location", map[app.Request.Url.LocalPath]);
app.Response.End();
}
}

public void Dispose()
{
}
}



 



As said - it didn't keep me up all night.



In order for it to work the following adjustments needs to go into web.config:



<appSettings>

  <add key="UrlMapping" value="c:\\inetpub\\UrlMapping.txt"/>


</appSettings>



<system.web>

  <httpModules>


    <add name="RedirectModule" type="EPiServer.Research.RedirectModule.RedirectModule,EPiServer.Research.RedirectModule"/>


  </httpModules> 
</system.web>



 



And the mapping file should just be a series of [path]|[new path], one on each line like this:



/oldpath/article.html|/newpath/newarticle.aspx

/oldpath/oldpage|http://www.google.com/?q=oldpage+topic