Wednesday 9 June 2010

N2CMS Forum Addon: Fixing the Theme

My work on the VWT2OC site is on hiatus at the moment due to hosting issues so I thought I’d blog a useful fix that I’ve found.
I’ve noticed a bug with the Forum Addon.  The first page would be correctly themed but any subsequent pages were not when running against a build of the latest N2CMS.
On investigation it seems that the Forum Pages CurrentItem was resolving to null which prevented the ThemeConcern for assigning the correct theme:
   1: namespace N2.Templates.Web
   2: {
   3:     /// <summary>
   4:     /// Sets the theme of the page template.
   5:     /// </summary>
   6:     [Service(typeof(TemplateConcern))]
   7:     public class ThemeConcern : TemplateConcern
   8:     {
   9:         public override void OnPreInit(ITemplatePage template)
  10:         {
  11:             var item = template.CurrentItem;
  12:             if (item == null)
  13:                 return; // <=== D'oh!  This is why the forum has no theme!
  14:             
  15:             /* Implementation doesn't matter here as it will never run! */
  16:  
  17:         }
  18:     }
  19: }
Looking into the N2.Templates.dll that comes the the Forum Addon, it looks like things were handled differently back in the day, with the N2.Templates.Web.ThemeModifier just using the theme for that start page:
   1: public void Modify<T>(TemplatePage<T> page) where T: AbstractPage
   2: {
   3:     string theme = GenericFind<ContentItem, StartPage>.StartPage.Theme;
   4:     if ((!this.themeVerified && (theme != null)) && Directory.Exists(page.Server.MapPath("~/App_Themes/" + theme)))
   5:     {
   6:         this.themeVerified = true;
   7:     }
   8:     if (this.themeVerified)
   9:     {
  10:         page.Theme = theme;
  11:     }
  12: }
  13:  
  14: /* Taken from Reflector
  15: public void Modify<T>(TemplatePage<T> page) where T: AbstractPage;
  16:  
  17: Declaring Type: N2.Templates.Web.ThemeModifier 
  18: Assembly: N2.Templates, Version=1.0.403.25743 
  19: */
So, the fix is to make the forum page take the theme from the start page, without affecting other page types…..tricky whilst maintaining separation of concerns…hmm.

The Fix

The fix has to belong with the forum addon so that the change in behaviour doesn’t knacker the standard n2cms features.  N2CMS populates the CurrentItem property based on the current url and as the Forum Plugin is generating links directly to it’s core template (/Forum/UI/Views/Forum.aspx) this is causing a problem.
Fortunately, the YAF Framework provides an extension point we can use to fix the problem yaf.IUrlBuilder.  This is a simple interface which takes the query string parameters and returns the appropriate link.
   1: using System.Web;
   2:  
   3: namespace N2.Templates.Forum
   4: {
   5:     /// <summary>
   6:     /// Build links from the current page
   7:     /// </summary>
   8:     public class N2UrlLinkBuilder : yaf.IUrlBuilder
   9:     {
  10:         #region IUrlBuilder Members
  11:  
  12:         /// <summary>
  13:         /// Builds the URL.
  14:         /// </summary>
  15:         /// <param name="url">The URL.</param>
  16:         /// <returns></returns>
  17:         public string BuildUrl(string url)
  18:         {
  19:             return string.Format("{0}?{1}", HttpContext.Current.Request.RawUrl.Split('?')[0], url);
  20:         }
  21:  
  22:         #endregion
  23:     }
  24: }
Unfortunately, YAF doesn’t allow you to set the link builder via configuration – it has to be done programmatically.  So you’ll need to amend ‘/Forum/UI/Views/Forum.aspx’ to ensure it’s set:
   1: namespace N2.Templates.Forum.UI.Views
   2: {
   3:     public partial class Forum : N2.Templates.Web.UI.TemplatePage<Items.Forum>
   4:     {
   5:         protected override void OnPreInit(EventArgs e)
   6:         {
   7:             if (!(yaf.Config.IsRainbow || yaf.Config.IsDotNetNuke || yaf.Config.IsPortal || yaf.Config.EnableURLRewriting == "true")) // based on logic found in yaf.Config
   8:                 HttpContext.Current.Application["yaf_UrlBuilder"] = new N2UrlLinkBuilder();
   9:             base.OnPreInit(e);
  10:         }
  11:     }
  12: }
Another possible workaround is to investigate the UrlRewriting….but this look too involved for the time available.

6 comments:

  1. Hi Martin. I am following your series on N2 development, and I like it very much. If you need good and reliable hosting that works nice with N2, I can recommend Arvixe. Also, you can find confirmed list here - http://n2cms.codeplex.com/Thread/View.aspx?ThreadId=52065

    ReplyDelete
  2. Hmmm, worth a look certainly - the personal packages (http://www.arvixe.com/asp_net_web_hosting) are even a little cheaper than the current hosting provider...and providers pretty much the same (or better) features.

    What's the customer support like?

    ReplyDelete
  3. Let me try putting it this way - usually when speaking with customer support, you feel like you are speaking with uneducated persons reading prepared answers from some kind of manual. Not with Arvixe - I think they have really skilled support staff. Chat is available 24/7 and each time they either directed me to solution or reminded me that solution is already in one of the emails you get when you open account :)
    I know I may sound like someone who is payed to advertise them, so if you want some more info, you can contact me personally and I will be glad to give you more info.

    Once more - I just like you series and although I am professional ASP.NET developer with several N2 sites behind me, I learned some new tricks. Would you be interested in supporting N2 community and help N2 gain more momentum? Me and two other guys are working on a community site for N2. Feel free to join. Please contact me if you would like to discuss details. Thanx!

    ReplyDelete
  4. Sounds good. This is my first n2cms build - but it seems simple enough at the moment. I think with some more documentation/examples on the web about how to do tasks it would be a much more approachable platform.

    ReplyDelete
  5. How do I attach forum to existing ASP.NET MVC site. After downloading the N2SimpleForum and Blog I followed the steps, pasted the code to Areas folder of N2.Templates.MVC/Areas. Everything compiles well. I am able to open N2 Management view, how do I attach forum/Blog now?

    Will I get a new entry in the tree on the left?

    Pl help..

    ReplyDelete
  6. I've not tried to use the MVC forum, so I can't really help. When I was working on this, it was WAP only.

    Sorry.

    Have you tried asking on: http://n2cms.codeplex.com/discussions/235976 ?

    ReplyDelete

Got something to say? Let it out then!
Comments are moderated, so it may take a while to for them to be displayed here!