How to add "More" link in the blog posts ?

Topics: Themes
Jul 24, 2013 at 3:53 AM
How to add "More" link in the blog posts ?
Jul 24, 2013 at 12:05 PM
Jul 24, 2013 at 12:26 PM
Thank you Andy.

How to have a Read more icon or image instead of plain "More" hyperlink ?
Jul 24, 2013 at 2:39 PM
Edited Jul 24, 2013 at 2:40 PM
Pepper,

In answer to your questions on both customizing the more link and making the author image an image link, use the revised PostView.ascx.cs code below.

The more link has class 'more' added and text set to 'more...'
You can of course alter that text or present the link however you like via the CSS class.

I used to have author profile pages, BlogEngine pages with the same name as the author's user name. Doing so provides the basis for automating access via links in controls.

I decided to get rid of that in favour of summary in widget

New PostView.ascx.cs
using System;
using System.Web.UI.WebControls;
using BlogEngine.Core;


public partial class PostView : BlogEngine.Core.Web.Controls.PostViewBase
{   
    private static int cropChars = 170;
    
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        Utils.InjectUserControls((PlaceHolder)this.FindControl("BodyContent"), this.Body);
    }

    //Customize more link
    public new string Body
    {
        get
        {
            var post = this.Post;
            var body = post.Content;

            if (Blog.CurrentInstance.IsSiteAggregation)
            {
                body = Utils.ConvertPublishablePathsToAbsolute(body, post);
            }

            if (this.ShowExcerpt)
            {
                var link = string.Format(
                    "<a href='{0}' class='more'> {1}...</a>",
                    post.RelativeLink,
                    Resources.labels.more
                );
                int cropLength = (this.DescriptionCharacters > 0) ? this.DescriptionCharacters : cropChars;
                body = CropContent(post, cropLength) + link;
            }


            var arg = new ServingEventArgs(body, this.Location, this.ContentBy);
            Post.OnServing(post, arg);

            if (arg.Cancel)
            {
                if (arg.Location == ServingLocation.SinglePost)
                {
                    this.Response.Redirect("~/error404.aspx", true);
                }
                else
                {
                    this.Visible = false;
                }
            }

            return arg.Body ?? string.Empty;
        }
    }

    public string GetAuthorDetails(int width, int height, bool includeSummary)
    {
        AuthorProfile ap = this.Post.AuthorProfile;
        if (ap != null)
        {            
            string authorBio = string.Empty;
            string email = HasValidEntry(ap.EmailAddress) ? ap.EmailAddress : GetEmailAddress(ap.UserName);
           
            var avatar = Avatar.GetAvatar(email);
            var imgSrc = avatar.Url.ToString();
            string authorImage = string.Format(
                "<img class='authorImage' width='{0}' height='{1}' src='{2}' alt='{3}' />",
                width,
                height,
                imgSrc,
                ap.DisplayName
            );
            
            if(HasValidEntry(ap.UserName))
            {
                var blog = Post.GetBlogByAuthor(ap.UserName);
                string blogName = blog.IsPrimary ? "" : blog.Name + "/";
                string href = string.Format("{0}{1}author/{2}{3}", Utils.ApplicationRelativeWebRoot, blogName, ap.UserName, BlogConfig.FileExtension);                
                string imageLink = string.Format(
                    "<a href='{0}' class='authorImageLink' >{1} <span class='authorName'>{2}</span></a>",
                    href,
                    authorImage,
                    ap.DisplayName
                );
                authorImage = imageLink;
            }
            

            if (HasValidEntry(ap.AboutMe))
            {
                authorBio = "<p class=\"authorBio\">" + ap.AboutMe + "</p>";
            }

            return includeSummary ? authorImage + authorBio : authorImage;
        }
        return string.Empty;
    }
    
    /// <summary>
    /// Checks the given string for null, spaces or literal null text.
    /// Useful for checking data entry fields.
    /// </summary>
    public static bool HasValidEntry(string s)
    {
        return s != null && s.Trim().Length > 0 && s != "null";
    }

    /// <summary>
    /// Get email address for a given user.   
    /// </summary>
    public static string GetEmailAddress(string userName)
    {
        if(!string.IsNullOrEmpty(userName))
        {
            System.Web.Security.MembershipUser user = System.Web.Security.Membership.GetUser(userName);
            if (user != null)
            {
                return user.Email;
            }
        }       
        return string.Empty;
    }

    /// <summary> 
    /// Truncates post or page content to the specified number of chars and adds ellipses.
    /// Content is considered to be the post/page description or the body striped of HTML.
    /// </summary>
    /// <param name="item">The content to crop.</param>
    /// <param name="maxChars">The truncated length.</param>
    /// <returns>The sized content stripped of any HTML or an empty string.</returns>
    public static string CropContent(IPublishable item, int maxChars)
    {
        string content = HasValidEntry(item.Description) ? item.Description : Utils.StripHtml(item.Content);

        if (content.Length > maxChars)
        {
            content = content.Substring(0, maxChars) + "&nbsp;&hellip;&nbsp;";
        }

        return content;
    }
}
Jul 24, 2013 at 2:56 PM
Thank Andy - In this code somehow the blog post on home page as well as blog post page, it is being repeated twice ?
Jul 24, 2013 at 3:14 PM
In OnLoad remove the line base.OnLoad(e);
protected override void OnLoad(EventArgs e)
    {
        //base.OnLoad(e);
        Utils.InjectUserControls((PlaceHolder)this.FindControl("BodyContent"), this.Body);        
    }
Jul 24, 2013 at 3:35 PM
Thank Andy,

I asked these questions in other topic where we were discussing about displaying author's profile and image.

Quick questions:

1) How to make the image of author as image link and link with the author's posts ? [SOLVED]
2) How to display author's full name (first and last) right with the image instead of username ?
3) Is it possible to have public profile for users in Blog Engine ? if yes, how ? how to make image link navigate to public profile page of author in this case ?

Could you please answer question # 2 and question 3 ?
Jul 24, 2013 at 4:02 PM
The code you now have uses the author profile display name in preference to the user name.
So if you make sure that each author profile has a display name, you should be good.

The way I used to handle profile pages, was simply to use BlogEngine pages named with the author's user-name and then link to them. As far as I'm aware there's no built in mechanism.
Jul 24, 2013 at 4:04 PM
Edited Jul 24, 2013 at 4:07 PM
Andy, I have first and last name saves in my profile but still I see my username as "admin" ?

Also, any public profile feature in BE? If no, then what is the use of profile page when nobody can see the profile page anyway ? What is the use of even having all the fields in the profile page when they are not being used anywhere ?

2) I just enabled - self-registration and created a new role "Member" and gave rights to view , post comments etc

but when any new user registers, and click on profile page, he/she gets an error message:

Line: 2
Error: '$T.d.FirstName' is null or not an object


is this a bug ?
Jul 24, 2013 at 4:46 PM
Edited Jul 24, 2013 at 5:34 PM
I think I might know what's going on, there are fields for first, middle and last name but also for 'display name' in profile settings - it's the display name that this code is using.

As far as I'm aware there is no publicly facing profile page out the box, the AuthorList control is perhaps closest, but all the backend stuff is available for use. That means you can assemble any profile information and present it as you see fit. Admittedly, that requires a degree of familiarity with programming for BE.

I used to have a control that you drop in a page that collected all that profile info and displayed it, but it's old and would probably need rewriting for newer BE versions. I think it kind of depends on what you want, there are so many different ways of presenting that information and the level of automation.

I'm not well up on the user registration side of things, but at a glance looks like a mandatory field is missing content, not sure, will need to have a look.

Edit.
Just repeated those steps for registration and profile page, unfortunately could not reproduce the error, maybe some one else has an insight as to what might be happening there.
Jul 24, 2013 at 5:39 PM
so this is a bug ? any way to fix this bug ?