Custom Control Rebuild Issue

Topics: Controls
Mar 4, 2009 at 5:58 PM
I've created a custom control that displays posts from the "feature" category on my blog's homepage. When I add a new feature post, it should move to the head of the list in the splash section, under the menu. Unfortunately, this behavior is only sometimes triggered, and I end up with new feature posts that have not been included in the splash section. Can someone take a look at my code and let me know if I'm hooking into the right events? Oh, the blog is here: http://www.glcbowling.com/

#region Using

using System;
using System.Web;
using System.Web.UI;
using System.Text;
using System.Collections.Generic;
using BlogEngine.Core;

#endregion

namespace Controls
{
  /// <summary>
  /// Formats posts for the splash header on the home page.
  /// </summary>
  public class SplashPosts : Control
  {

    static SplashPosts()
    {
      BuildPostList();
      Post.Saved += new EventHandler<SavedEventArgs>(Post_Saved);
    }

    static void Post_Saved(object sender, SavedEventArgs e)
    {
      if (e.Action != SaveAction.Update)
        BuildPostList();
    }

    private static object _SyncRoot = new object();
    private static List<Post> _Posts = new List<Post>();

    private static void BuildPostList()
    {
      lock (_SyncRoot)
      {
                int number = 5;
        if (number > Post.GetPostsByTag("feature").Count)
          number = Post.GetPostsByTag("feature").Count;

        int counter = 1;
        _Posts.Clear();
        foreach (Post post in Post.GetPostsByTag("feature"))
        {
          if (counter <= number && post.IsPublished)
          {
            _Posts.Add(post);
            counter++;
          }
        }
      }
    }

    private static string RenderPosts()
    {

            if (_Posts.Count == 0)
            {
                return "<p>" + Resources.labels.none + "</p>";
            }

      StringBuilder sb = new StringBuilder();
            StringBuilder sb2 = new StringBuilder();
      sb.Append("<div class=\"splashPosts\" id=\"splashPosts\">");
            sb2.Append("<div class=\"pane-nav title\" id=\"splashNav\">");

            int counter = 1;
      foreach (Post post in _Posts)
      {
        if (!post.IsVisible)
          continue;
                    
                if (counter == 1)
                {
                    sb.Append("<div class=\"pane xfolkentry first active\">");
                    sb2.Append("<span class=\"active\">" + counter.ToString() + "</span>");
                }
                else
                {
                    sb.Append("<div class=\"pane xfolkentry\">");
                    sb2.Append("<span>" + counter.ToString() + "</span>");
                }
                
                sb.Append("<img class=\"pane-img\" src=\"/images/feature/" + post.Slug + ".jpg\" width=\"616\" height=\"250\" alt=\"" + post.Title + "\" />");
                
                sb.Append("<div class=\"pane-title title\"><a href=\"" + post.RelativeLink +"\" class=\"taggedlink\">" + post.Title + "</a></div>");
                
                sb.Append("<p>" + post.Description + " [<a href=\"" + post.RelativeLink + "\">Read more »</a>]</p>");
                
                sb.Append("</div>");
                counter++;
      }

      sb.Append("</div>");
            sb2.Append("</div>");
            sb.Append(sb2.ToString());
      return sb.ToString();
    }

    public override void RenderControl(HtmlTextWriter writer)
    {
      if (Page.IsCallback)
        return;
      
      string html = RenderPosts();
      writer.Write(html);
    }
  }
}
Coordinator
Mar 4, 2009 at 7:23 PM
I tested the control.  I *think* the problem is with this line:

foreach (Post post in Post.GetPostsByTag("feature"))

Each time through the iteration, the same posts might not be coming back or something might be getting out of sync.  Try replacing that line above with:

List<Post> posts = Post.GetPostsByTag("feature");
foreach (Post post in posts)
Mar 4, 2009 at 7:35 PM
Ben,

Thank you for the reply. That line of code is helpful, but I've realized that I'm having a different problem than the one stated.

If I save a new feature post without publishing it, it is not added to the SplashPosts list. If I reopen the post and then save and publish it, the post is still not added to the SplashPosts list.

If I save and publish a new feature post at the same time, then it is automatically added to the SplashPosts list.

Expected behavior is for a feature post to join the list when saved and published.
Coordinator
Mar 4, 2009 at 7:57 PM
That should be an easy fix ...

if (e.Action != SaveAction.Update)
    BuildPostList();

Just remove the first line so BuildPostList() is also called when you are updating the post (which includes when you are changing it from unpublished to published).
Mar 4, 2009 at 8:11 PM
:-) I feel like a complete moron! "If event.Action is not equal to SaveAction.Update"

Thanks so much for taking the time out to help me with this.