Listing author list alphabetically

Feb 12, 2011 at 12:51 PM

I asked this question in the past but cannot find the answer.  I would like to have the author list in ascending alphabetical order.

Thank you.

Feb 27, 2011 at 9:17 PM

I had the same problem, I'm not a DOT NET developer by any means, but hacked away at the file to get it sorting.

I've renamed the file to cAuthorList.cs to mark it as custom, so you will need to reference it as such at point of insertion in your blog.

The code will check if you are using user names and or profile names and do the sort accordingly, there is probably a better way of doing this but it works for me.

namespace App_Code.Controls
{
    using System;
    using System.IO;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using BlogEngine.Core;
    using Resources;
    using System.Collections.Generic;
    using System.Collections;

    /// <summary>
    /// Builds an author list.
    /// </summary>  

    public class cAuthorList : Control
    {
        #region Constants and Fields

        /// <summary>
        /// The html string.
        /// </summary>
        private static string html;

        /// <summary>
        /// The show rss icon.
        /// </summary>
        private static bool showRssIcon = true;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes static members of the <see cref="AuthorList"/> class.
        /// </summary>
        static cAuthorList()
        {
            Post.Saved += (sender, args) => html = null;
        }

        #endregion

        #region Properties

        public class Author
        {
            private string un, dn;
            private int pc;

            public Author(string userName, string displayName, int postCount)
            {
                this.un = userName;
                this.dn = displayName;
                this.pc = postCount;
            }          

            public string UserName
            {
                get
                {
                    return un;
                }
            }
            public string DisplayName
            {
                get
                {
                    return dn;
                }
            }
            public int PostCount
            {
                get
                {
                    return pc;
                }
            }

        }

        /// <summary>
        ///     Gets or sets a value indicating whether or not to show feed icons next to the category links.
        /// </summary>
        public bool ShowRssIcon
        {
            get
            {
                return showRssIcon;
            }

            set
            {
                if (showRssIcon == value)
                {
                    return;
                }

                showRssIcon = value;
                html = null;
            }
        }

        /// <summary>
        ///     Gets the rendered HTML in the private field and first
        ///     updates it when a post has been saved (new or updated).
        /// </summary>
        private string Html
        {
            get
            {
                if (html == null)
                {
                    var ul = this.BindAuthors();
                    html = Utils.RenderControl(ul);
                }

                return html;
            }
        }       

        #endregion

        #region Public Methods

        /// <summary>
        /// Outputs server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object and stores tracing information about the control if tracing is enabled.
        /// </summary>
        /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the control content.</param>
        public override void RenderControl(HtmlTextWriter writer)
        {
            writer.Write(this.Html);
            writer.Write(Environment.NewLine);
        }

        #endregion

        #region Methods

        /// <summary>
        /// Loops through all users and builds the HTML
        /// presentation.
        /// </summary>
        /// <returns>The authors.</returns>
        private HtmlGenericControl BindAuthors()
        {
            if (Post.Posts.Count == 0)
            {
                var p = new HtmlGenericControl("p") { InnerHtml = labels.none };
                return p;
            }

            var ul = new HtmlGenericControl("ul") { ID = "authorlist" };

            List<Author> Authors = new List<Author>();
            foreach (MembershipUser user in Membership.GetAllUsers())
            {
                var postCount = Post.GetPostsByAuthor(user.UserName).Count;
                if (postCount == 0)
                {                   
                    continue;
                }
                string profileName = AuthorProfile.GetProfile(user.UserName).DisplayName;
                if (string.IsNullOrEmpty(profileName))
                {
                    profileName = user.UserName;
                }
                Author curAuthor = new Author(user.UserName, profileName, postCount);             
                Authors.Add(curAuthor);

            }
            Authors.Sort(new AlphaAuthorComparator());
            foreach (Author user in Authors)
            {
                var li = new HtmlGenericControl("li");

                if (this.ShowRssIcon)
                {
                    var img = new HtmlImage
                        {
                            Src = string.Format("{0}pics/rssButton.png", Utils.RelativeWebRoot),
                            Alt = string.Format("RSS feed for {0}", user.DisplayName)
                           
                        };
                    img.Attributes["class"] = "rssButton";

                    var feedAnchor = new HtmlAnchor
                        {
                            HRef =
                                string.Format("{0}syndication.axd?author={1}", Utils.RelativeWebRoot, Utils.RemoveIllegalCharacters(user.UserName))
                        };
                    feedAnchor.Attributes["rel"] = "nofollow";
                    feedAnchor.Attributes["title"] = img.Alt;
                    feedAnchor.Controls.Add(img);

                    li.Controls.Add(feedAnchor);
                }
               
                var anc = new HtmlAnchor
                {
                    HRef = string.Format("{0}author/{1}{2}", Utils.RelativeWebRoot, user.UserName, BlogSettings.Instance.FileExtension),
                    InnerHtml = string.Format("{0}", user.DisplayName),
                    Title = "Show posts by " + user.DisplayName
                };
                string strPostCount = string.Format(" ({0})", user.PostCount);
                var spn = new HtmlGenericControl("span") { InnerText = strPostCount };

                li.Controls.Add(anc);
                li.Controls.Add(spn);
                ul.Controls.Add(li);
            }

            return ul;
        }
        #endregion

        private class AlphaAuthorComparator : IComparer<Author>
        {
            int IComparer<Author>.Compare(Author x, Author y)
            {
                return (new CaseInsensitiveComparer()).Compare(x.DisplayName, y.DisplayName);
            }
        }
    }
}

Feb 27, 2011 at 11:33 PM

Update, if you don't fill in any details for author profiles in the control panel, you will have to add a null check for the author profile (which is a good idea anyway), so change the above foreach (MembershipUser user in Membership.GetAllUsers()) with the following.

foreach (MembershipUser user in Membership.GetAllUsers())
            {
                var postCount = Post.GetPostsByAuthor(user.UserName).Count;
                if (postCount == 0)
                {                   
                    continue;
                }
                string profileName = String.Empty;
                AuthorProfile ap = AuthorProfile.GetProfile(user.UserName);
                if (ap != null)
                {
                    profileName = AuthorProfile.GetProfile(user.UserName).DisplayName;
                }
                if (string.IsNullOrEmpty(profileName))
                {
                    profileName = user.UserName;
                }
                Author curAuthor = new Author(user.UserName, profileName, postCount);             
                Authors.Add(curAuthor);

            }

Feb 28, 2011 at 12:27 AM

For the sake of completeness, here's everything tidied up and fairly well tested.

Name your control cAuthorList.cs, copy in this code and insert it where you want to use it.

namespace App_Code.Controls
{
    using System;
    using System.IO;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using BlogEngine.Core;
    using Resources;
    using System.Collections.Generic;
    using System.Collections;

    /// <summary>
    /// Builds an author list.
    /// </summary>  

    public class cAuthorList : Control
    {
        #region Constants and Fields

        /// <summary>
        /// The html string.
        /// </summary>
        private static string html;

        /// <summary>
        /// The show rss icon.
        /// </summary>
        private static bool showRssIcon = true;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes static members of the <see cref="AuthorList"/> class.
        /// </summary>
        static cAuthorList()
        {
            Post.Saved += (sender, args) => html = null;
        }

        #endregion

        #region Properties       

        /// <summary>
        ///     Gets or sets a value indicating whether or not to show feed icons next to the category links.
        /// </summary>
        public bool ShowRssIcon
        {
            get
            {
                return showRssIcon;
            }

            set
            {
                if (showRssIcon == value)
                {
                    return;
                }

                showRssIcon = value;
                html = null;
            }
        }

        /// <summary>
        ///     Gets the rendered HTML in the private field and first
        ///     updates it when a post has been saved (new or updated).
        /// </summary>
        private string Html
        {
            get
            {
                if (html == null)
                {
                    var ul = this.BindAuthors();
                    html = Utils.RenderControl(ul);
                }

                return html;
            }
        }       

        #endregion

        #region Author details
        public class Author
        {
            private string un, dn;
            private int pc;

            public Author(string userName, string displayName, int postCount)
            {
                this.un = userName;
                this.dn = displayName;
                this.pc = postCount;
            }

            public string UserName
            {
                get
                {
                    return un;
                }
            }
            public string DisplayName
            {
                get
                {
                    return dn;
                }
            }
            public int PostCount
            {
                get
                {
                    return pc;
                }
            }

        }
        #endregion

        #region Public Methods

        /// <summary>
        /// Outputs server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object and stores tracing information about the control if tracing is enabled.
        /// </summary>
        /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the control content.</param>
        public override void RenderControl(HtmlTextWriter writer)
        {
            writer.Write(this.Html);
            writer.Write(Environment.NewLine);
        }

        #endregion

        #region Methods

        /// <summary>
        /// Loops through all users and builds the HTML
        /// presentation.
        /// </summary>
        /// <returns>The authors.</returns>
        private HtmlGenericControl BindAuthors()
        {
            if (Post.Posts.Count == 0)
            {
                var p = new HtmlGenericControl("p") { InnerHtml = labels.none };
                return p;
            }

            var ul = new HtmlGenericControl("ul") { ID = "authorlist" };

            List<Author> Authors = new List<Author>();
            foreach (MembershipUser user in Membership.GetAllUsers())
            {
                var postCount = Post.GetPostsByAuthor(user.UserName).Count;
                if (postCount == 0)
                {                   
                    continue;
                }
                string profileName = String.Empty;
                AuthorProfile ap = AuthorProfile.GetProfile(user.UserName);
                if (ap != null)
                {
                    profileName = AuthorProfile.GetProfile(user.UserName).DisplayName;
                }
                if (string.IsNullOrEmpty(profileName))
                {
                    profileName = user.UserName;
                }
                Author curAuthor = new Author(user.UserName, profileName, postCount);             
                Authors.Add(curAuthor);

            }
            Authors.Sort(new AlphaAuthorComparator());
            foreach (Author user in Authors)
            {
                var li = new HtmlGenericControl("li");

                if (this.ShowRssIcon)
                {
                    var img = new HtmlImage
                        {
                            Src = string.Format("{0}pics/rssButton.png", Utils.RelativeWebRoot),
                            Alt = string.Format("RSS feed for {0}", user.DisplayName)
                           
                        };
                    img.Attributes["class"] = "rssButton";

                    var feedAnchor = new HtmlAnchor
                        {
                            HRef =
                                string.Format("{0}syndication.axd?author={1}", Utils.RelativeWebRoot, Utils.RemoveIllegalCharacters(user.UserName))
                        };
                    feedAnchor.Attributes["rel"] = "nofollow";
                    feedAnchor.Attributes["title"] = img.Alt;
                    feedAnchor.Controls.Add(img);

                    li.Controls.Add(feedAnchor);
                }
               
                var anc = new HtmlAnchor
                {
                    HRef = string.Format("{0}author/{1}{2}", Utils.RelativeWebRoot, user.UserName, BlogSettings.Instance.FileExtension),
                    InnerHtml = string.Format("{0}", user.DisplayName),
                    Title = "Show posts by " + user.DisplayName
                };
                string strPostCount = string.Format(" ({0})", user.PostCount);
                var spn = new HtmlGenericControl("span") { InnerText = strPostCount };

                li.Controls.Add(anc);
                li.Controls.Add(spn);
                ul.Controls.Add(li);
            }

            return ul;
        }
        #endregion

        #region comparator
        private class AlphaAuthorComparator : IComparer<Author>
        {
            int IComparer<Author>.Compare(Author x, Author y)
            {
                return (new CaseInsensitiveComparer()).Compare(x.DisplayName, y.DisplayName);
            }
        }
        #endregion
    }
}