Showing Summary Instead of Full Post

Topics: ASP.NET 2.0, Business Logic Layer, Controls
Aug 3, 2007 at 2:18 AM
On the home page, how can I show a summary instead of a full post?

I understand that this is ugly, but for SEO purposes, it is needed.

Can this be done easily?
Aug 3, 2007 at 6:21 AM
Edited Aug 3, 2007 at 6:34 AM
I just added a quick function to my already Custom PostView to do this for me. Quick and dirty:

using System.Web;
using BlogEngine.Core;
using BlogEngine.Core.Web.Controls;
namespace Controls
    public class MBCPostView : PostViewBase
        protected override string CategoryLinks(string separator)
            string[] keywords = new string[Post.Categories.Count];
            string link = "<a href=\"{0}{1}.aspx\" rel=\"tag directory\">{2}</a>";
            string path = VirtualPathUtility.ToAbsolute("~/category/");
            for (int i = 0; i < Post.Categories.Count; i++)
                if (CategoryDictionary.Instance.ContainsKey(Post.Categories[i]))
                    string category = CategoryDictionary.Instance[Post.Categories[i]];
                    keywords[i] = string.Format(link, path, Utils.RemoveIlegalCharacters(category), category);
            return "Categories: " + string.Join(separator, keywords);
        protected virtual string TechnoratiTagLinks(string separator)
            if (Post.Tags.Count == 0)
                return null;
            string[] tags = new string[Post.Tags.Count];
            //SBE 07/06/2007:  the link for technorati nees "+"'s instead of spaces
            string link = "<a href=\"{0}\" rel=\"tag\">{1}</a>";
            for (int i = 0; i < Post.Tags.Count; i++)
                string tag = Post.Tags[i];
                tags[i] = string.Format(link, tag.Replace(" ", "+"), tag);
            return "Technorati Tags: " + string.Join(separator, tags);
        public string ContentExcerpt()
            if (Request.RawUrl.ToLowerInvariant().Contains("/post/"))
                return Post.Content;
                return ExcerptString(Post.Content, 250, true);
        private static string ExcerptString(string stringToExcerpt, int stringLength, bool showEllipsis)
            string output;
            int indexOfSpace;
            //SBE 09/14/2006:  if null, no point in continuing
            if (stringToExcerpt == null) return null;
            //SBE 09/14/2006:  if the string is smaller than the length, return
            if (stringToExcerpt.Length <= stringLength)
                return stringToExcerpt;
            //SBE 09/14/2006:  find first space we can break it at after length
            indexOfSpace = stringToExcerpt.IndexOf(" ", stringLength - 1);
            if (indexOfSpace < 0) return stringToExcerpt;
            output = stringToExcerpt.Substring(0, indexOfSpace);
            if (showEllipsis) output += "...";
            return output;
Aug 4, 2007 at 3:27 PM
Hey Scott,

How would one do this for the RSS feed, then?


Aug 5, 2007 at 7:31 AM
That would require more seriousness. You would have to go into the Core/API/MetaBlog files and make a change there. At that point, you might as well just roll it into the product by added a setting in the xml file, adding the admin utility for "Summary - yes/no", and then looking it up from there.
Aug 5, 2007 at 7:38 AM
There was a major problem with my Excerpt function above, however. It is not smart about what HTML it cuts off when the 250 characters is hit. It makes sure it doesn't break a word in half, but that's about it. I had a problem where a sentence was started with bold and italics, and then the whole rest of my page was italicized and bolded because the string hit the 250 mark before the end </i></b>.

I looked around and saw that Wordpress had already solved this with its balanceTags() function, so I spent some time and converted it to c#:

         Balances Tags of string using a modified stack.
         @param text      Text to be balanced
         @param force     Forces balancing, ignoring the value of the option
         @return          Returns balanced text
         @author          Leonard Lin (
         @version         v1.1
         @date            November 4, 2001
         @license         GPL v2.0
         ---  Modified by Scott Reilly (coffee2code) 02 Aug 2004
                1.1  Scott Elkin ported to C# 08/05/2007
	        1.1  Fixed handling of append/stack pop order of end text
	             Added Cleaning Hooks
	        1.0  First Version
        private static string balanceTags(string text)
            Stack<string> tagStack = new Stack<string>();
            string tagQueue = "";
            string newText = "";
            string tag = "";
            //WP bugfix for comments - in case you REALLY meant to type < !--
            text = text.Replace("< !--", "<    !--");
            //WP bugfix for LOVE <3 (and other situations with '<' before a number)
            text = Regex.Replace(text,"<([0-9]{1})", "&lt;$1", RegexOptions.IgnoreCase);
            foreach(Match match in Regex.Matches(text,@"<(\/?\w*)\s*([^>]*)>",RegexOptions.IgnoreCase))
                int i = text.IndexOf(match.Value);
                int len = match.Value.Length;
                tag = match.Groups[1].ToString().ToLower();
                if (tag.Contains("/")) // End Tag
                    tag = tag.Substring(1);
                    if (tagStack.Count == 0)
                        tag = "";
                    else if (tagStack.Peek() == tag)  // if stacktop value = tag close value then pop
                        tag = "</" + tag + ">"; // Close tag
                        //for j = max stacksize #, where j > 0 and count down
                        string[] arr = tagStack.ToArray();
                        for (int index = tagStack.Count - 1; index >= 0; index--)
                            if (arr[index] == tag)
                                //add tag to the tagQueue
                                for (int qIndex = tagStack.Count - 1; qIndex > index; qIndex--)
                                    tagQueue += "</" + tagStack.Pop() + ">";
                        tag = "";
                else  // Begin Tag
                    if (tag.Contains("/") || tag == "")
                        // If self-closing or '', don't do anything.
                    else if (tag == "br" || tag == "img" || tag == "hr" || tag == "input")
                         // ElseIf it's a known single-entity tag but it doesn't close itself, do so
                        tag += "/";
                        // Push the tag onto the stack
                        // If the top of the stack is the same as the tag we want to push, close previous tag
                        if (tagStack.Count > 0 && tag != "div" && tagStack.Peek() == tag)
                            tagQueue = "</" + tagStack.Pop() + ">";
                    string attributes = match.Groups[2].ToString();
                    if (attributes.Length > 0)
                        attributes = " " + attributes;
                    tag = "<" + tag + attributes + ">";
                    if (tagQueue.Length > 0)
                        tagQueue += tag;
                        tag = "";
                newText += text.Substring(0, i) + tag;
                text = text.Substring(i + len);
            // Clear Tag Queue
            newText += tagQueue;
            // Add Remaining text
            newText += text;
            // Empty Stack
            while (tagStack.Count > 0)
                newText += "</" + tagStack.Pop() + ">";  // Add remaining tags to close
            // WP fix for the bbug with HTML comments
            newText = newText.Replace("< !--", "<!--");
            newText = newText.Replace("<    !--", "< !--");
            return newText;
Aug 6, 2007 at 9:19 AM
The latest source code support this out-of-the-box. You can control it from the settings page and it works across themes. It uses the description or creates an excerpt based on your settings (or both). It doesn't effect the RSS though.
Aug 6, 2007 at 6:42 PM

Wow, cool!

I took a look, and there are a couple problems, some bigger than others.

  1. Can you also allow a setting to choose how many characters you want to show?
  2. You are breaking it off at 300 characters, regardless of whether you are in the middle of a word or not. (My code above fixes that)
  3. You are not including markup with the description. That will break CSS rules if one is counting on <p> tags and such. It also doesn't allow for images to show. If you use the code above, you can solve this also, as the code above will automatically close all open tags.

You can see my implementation here:
Aug 6, 2007 at 10:43 PM

1. No, but that is a good idea
2. Is that really so bad when it appends three periods?
3. It strips all html tags so it is no problem

I'll take a look at your code tomorrow. Thanks
Aug 6, 2007 at 11:53 PM
2. Using the ellipses (...) isn't what is bad, I just don't want to cut the word in half. So instead of "disruption...", your code would do "di...".
3. It is a problem. It strips ALL HTML, so even the <p> tags are gone. I apply formatting to paragraphs, and since your code strips them, I get formatting issues.
Aug 7, 2007 at 12:11 AM
Good points. Let me see what I can do.
Aug 7, 2007 at 12:12 PM
How about a <!--more--> comment that, when entered, would cause a manual break?

Or, since code should be formatted with either p or br tags by the editor, how about breaking at the next close tag of those?

So: 'Read through x characters, and find the next br or /p, and stop immediately after it.'

Aug 7, 2007 at 2:06 PM

strivinglife wrote:
How about a <!--more--> comment that, when entered, would cause a manual break?

That's an interesting option!
Aug 7, 2007 at 7:06 PM
The comment option would be another great feature, but it isn't fullproof. If I forget to add it when I post a new entry, I would still need it broken at the correct number of characters.

Breaking it after a tag is not as good as my solution, in my humble opinion. For one, you can't break after a <br/>, since that break may be within a <p>.

Also, some idiots write really long paragraphs.

Just look at how other popular blogs handle this problem. The function that I translated comes directly from Wordpress, one of the biggest platforms there is.

Capping it at an exact number of characters and then balancing the tags is easy, the code is already written, and is guaranteed to work.
Aug 9, 2007 at 9:46 PM
FWIW I build the content management system behind a large news site that needed a lot of flexibility about where we broke articles and positioned adverts (sorry about the last one, but it keeps the site free!) etc

For the "more..." links we basically worked on a simple rules table that said
- if the user has entered the more tag use that to control positioning the <more...> link (if there is more content after the tag)
- if the first (or first plus second) paragraph less than the number of characters defined for the content section (home page stories broke at 300 chars, drill down sections at 500 usually) then position <more...> after first (or second) paragraph (if there is more content)
- find the closest punctuation point prior to the specified number of characters and break there, closing any open HTML tags

character counting happened after stripping out hyperlinks etc so it was controlled on display characters. It would also identify image tags in the story and strip those for calculation but remember the first image and if smaller than a certain size display it in the story image position in the summary layout

It was a lot of work to get the rules tuned and reliable but worked for our needs :)