Pin post to top of category

Jun 4, 2010 at 10:54 AM

Hi there

Is there a way to always display a particular post at the top of a category ?

Many thanks

Steve

Jun 7, 2010 at 2:38 PM

anyone ?

 

many thankss

 

steve

 

Jun 9, 2010 at 6:55 AM

Hi All - just wondering if there was an easy way to achieve this ?

Thanks

Steve

Coordinator
Jun 9, 2010 at 9:48 AM

It's possible.  There's a few questions that come to mind with what you're looking to do.

For example, is this pinned post going to just be the first post in the list of posts for the category.  Or will it be separated in a distinct box/div from the rest of the posts for the category (so it stands out more).  And will this pinned post only be pinned for a particular category, or for all categories.  And is the pinned post a post from the current category, or might it be a post not tied to the category, but displayed for the current category.

At any rate, here's code that would display a post at the top of all categories.  And it's displayed as just the first post within that category.  If the post is part of the category, it will actually display twice -- once at the top, and the 2nd time it'll appear where it would normally appear in the flow of posts for the category.

To achieve this, in default.aspx.cs, in DisplayCategories() is this line of code:

PostList1.Posts = Post.GetPostsByCategory(categoryId).ConvertAll(
	new Converter<Post, IPublishable>(delegate(Post p) {
		return p as IPublishable; }));

Replace that code above with the code below.  In this case, the pinned post is the one with the title of "Top Tips To Beating RSI".

PostList1.Posts = new List<IPublishable>();

Post post = Post.Posts.Find(delegate(Post p) {
	return p.Title.Equals("Top Tips To Beating RSI",
		StringComparison.OrdinalIgnoreCase);
});

if (post != null)
	PostList1.Posts.Add(post);

PostList1.Posts.AddRange(Post.GetPostsByCategory(categoryId).ConvertAll(
	new Converter<Post, IPublishable>(delegate(Post p) { 
		return p as IPublishable; })));

Jun 9, 2010 at 10:57 AM

Yeah sorry I should have been clearer about what I was trying to achieve !

Its basically working within one category

e.g. If you look at the category : http://www.rsi-symptoms.org.uk/category/RSI-Symptoms.aspx

I would like the post : http://www.rsi-symptoms.org.uk/post/RSI-Symptoms.aspx to always appear at the top of this categor. Ideally this post wouldn't appear any where else within the category - i.e. just at the top ?

Its basically so I can provide a bit of fixed info at the top of each category

Thanks for your help with all this - its much appreccated !

 

 

 

 

 

Coordinator
Jun 10, 2010 at 10:40 AM

Ok, that answers some questions..!

Here's replacement code for the entire DisplayCategories() method in default.aspx.cs.  It allows you to have one pinned post per category.  The pinned post will be displayed as the first post in the list of posts, and will not appear again within the list of posts.

private void DisplayCategories()
{
	if (!String.IsNullOrEmpty(Request.QueryString["id"]))
	{
		Guid categoryId = new Guid(Request.QueryString["id"]);
		Category category = Category.GetCategory(categoryId);
		List<Post> catPosts = Post.GetPostsByCategory(categoryId);
		PostList1.Posts = new List<IPublishable>();
		
		// key is Category Title
		// value is Post Title of pinned post.
		Dictionary<string, string> pinnedPostsPerCategory =
			new Dictionary<string, string>(
				StringComparer.OrdinalIgnoreCase);

		// Categories and their Pinned posts.
		pinnedPostsPerCategory.Add("RSI Symptoms", "RSI Symptoms");
		pinnedPostsPerCategory.Add("Beating RSI",
			"Top Tips To Beating RSI");
		pinnedPostsPerCategory.Add("RSI Stretches / Exercises",
			"Head Tilt (or Chin Tilt) Stretch");

		if (pinnedPostsPerCategory.ContainsKey(category.Title))
		{
			string pinnedPostTitle =
				pinnedPostsPerCategory[category.Title];

			Post pinnedPost = catPosts.Find(delegate(Post p)
			{
				return p.Title.Equals(pinnedPostTitle,
					StringComparison.OrdinalIgnoreCase);
			});

			if (pinnedPost != null)
			{
				catPosts.Remove(pinnedPost);
				PostList1.Posts.Add(pinnedPost);
			}
		}

		PostList1.Posts.AddRange(catPosts.ConvertAll(
			new Converter<Post, IPublishable>(delegate(Post p)
		{
			return p as IPublishable;
		})));

		Page.Title = category.Title;
	}
}

Jun 10, 2010 at 12:22 PM

You're a star ! That works great !!

Thanks again  for all your assistance !

Sep 20, 2010 at 3:00 PM

Hi

 

Just to follow up on this

 

Is there a way to pin a post to the top of the home page as well ? I'd like a default load of info to appear there all the time

 

Many thanks

 

Steve

Sep 21, 2010 at 3:54 PM

Any ideas folks ?

Thanks

Steve

Sep 24, 2010 at 8:17 AM

Helloooo ? Any ideas on this one - thanks

Coordinator
Sep 24, 2010 at 12:50 PM

For pinning a post to the homepage, in default.aspx.cs you'll find the code below (it's towards the bottom of Page_Load).  I inserted a new block of code.  You can put in the title of the post you want pinned -- I put a post title in there for starters .....

PostList1.ContentBy = ServingContentBy.AllContent;
PostList1.Posts = Post.Posts.ConvertAll(new Converter<Post,
	IPublishable>(delegate(Post p) { return p as IPublishable; }));

// New Code START
Post homepagePinnedPost = Post.Posts.Find(delegate(Post p)
{
	return p.Title.Equals("Tendonitis Symptoms", StringComparison.OrdinalIgnoreCase);
});
if (homepagePinnedPost != null)
{
	PostList1.Posts.Insert(0, homepagePinnedPost);
}
// New Code END

if (!BlogSettings.Instance.UseBlogNameInPageTitles)
	Page.Title = BlogSettings.Instance.Name + " | ";

Sep 24, 2010 at 1:18 PM

Thanks Ben - nearly there

The only problem now is that the post appears twice (as its already in the list)

http://www.rsi-symptoms.org.uk/

Do I need to somehow delete the post if its in PostList1, then add it again at position 0 ?

Thanks for your help

Steve

Sep 27, 2010 at 8:30 AM

Hi again - no worries I have sorted this now (combined the above two solutions)

Many thanks for your help !

 

//PostList1.Posts = Post.Posts.ConvertAll(new Converter<Post, IPublishable>(delegate(Post p) { return p as IPublishable; }));


            List<Post> homePosts = Post.Posts;
            PostList1.Posts = new List<IPublishable>();



// New Code START
string homepagePinnedTitle = "RSI Symptoms and Treatment";
Post homepagePinnedPost = Post.Posts.Find(delegate(Post p)
{
    return p.Title.Equals(homepagePinnedTitle , StringComparison.OrdinalIgnoreCase);
});
if (homepagePinnedPost != null)
{
    PostList1.Posts.Insert(0, homepagePinnedPost);
}

// remove the pinned post from its original position
Post removePost = homePosts.Find(delegate(Post p)
            {
                return p.Title.Equals(homepagePinnedTitle,
                    StringComparison.OrdinalIgnoreCase);
            });

            if (removePost != null)
            {
                homePosts.Remove(removePost);
            }


PostList1.Posts.AddRange(homePosts.ConvertAll(
            new Converter<Post, IPublishable>(delegate(Post p)
        {
            return p as IPublishable;
        })));



// New Code END



            if (!BlogSettings.Instance.UseBlogNameInPageTitles)
                Page.Title = BlogSettings.Instance.Name + " | ";

Sep 28, 2010 at 10:18 AM

hmmm

well it appears my cunning fix doesn't work - the line "homePosts.Remove(removePost);" looks like it removes the post forever (the code works once - but then the post is not displayed again when home page is refreshed. Restart IIS and it works again - but just once

 

Any ideas ?

Thanks in advance

Steve

Coordinator
Sep 28, 2010 at 10:48 AM

Here's something that will work.  Your last idea was good ... before seeing your solution, I was thinking it was going to be trickier, but then saw what you did and realized your approach was simpler than what I was thinking would be needed.

PostList1.ContentBy = ServingContentBy.AllContent;
PostList1.Posts = Post.Posts.ConvertAll(new Converter<Post,
	IPublishable>(delegate(Post p) { return p as IPublishable; }));

// New Code START
string homepagePinnedTitle = "RSI Symptoms and Treatment";

// find the post we want to pin to the front.
Post homepagePinnedPost = Post.Posts.Find(delegate(Post p)
{
	return p.Title.Equals(homepagePinnedTitle, StringComparison.OrdinalIgnoreCase);
});

if (homepagePinnedPost != null)
{
	IPublishable pinnedPostInList = PostList1.Posts.Find(delegate(IPublishable ip)
	{
		// search for post by Id (title works too).
		return ip.Id == homepagePinnedPost.Id;
	});

	if (pinnedPostInList != null)
	{
		PostList1.Posts.Remove(pinnedPostInList);
	}

	// add the pinned post to the front of the list.
	PostList1.Posts.Insert(0, homepagePinnedPost);
}
// New Code END


if (!BlogSettings.Instance.UseBlogNameInPageTitles)
	Page.Title = BlogSettings.Instance.Name + " | ";

Sep 28, 2010 at 10:51 AM

Thanks Ben - i'm afraid I get an error:

Compiler Error Message: CS0117: 'ASP.user_controls_postlist_ascx' does not contain a definition for 'ContentBy'

Coordinator
Sep 28, 2010 at 10:53 AM

Oops, just get rid of that line -- it's a new property starting from BE 1.6.  Actually, I think my original code from a few days ago had that in it too, but you might have skipped over it that time.  Not needed.

Sep 28, 2010 at 10:53 AM

ah - if I remove the line 'PostList1.ContentBy = ServingContentBy.AllContent;' it seems to work - is that line important ? Maybe from a newer version of BE?'

Thanks again for your help with this !

Sep 28, 2010 at 10:55 AM

ha - our posts crossed !

Many thanks Ben - its all good now. Thanks for all your help

Steve