Friday, December 18, 2009

Sitefinity- Filtering Tags for specific blog in a Tag Cloud

Recently i was working on a sitefinity project. The problem i was facing was, there are 5 blogs in my website and i want to show all the blogs separately on different pages.
When i use the Tags List control on the page, it is showing all the tags from all the blogs.
But my requirement is, i want only Tags related to specific blog.

I managed to come up with a simple solution that requires creating a custom control that inherits from TagsList, implementing a simple property and overriding one method - InitializeControls.

Save this class file into App_Code folder.
Make a entry into web.config file.(in <toolboxcontrols> tag)
<add name="FilteredTags Cloud" section="Tags & Categories" type="Ramp.TagsListFiltered, App_Code" description="Displays Blog related tags" />

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Telerik.Cms.Engine.WebControls.Categories;
using Telerik.Cms.Engine.WebControls.Tags;
using Telerik.Cms.Web.UI;
using System.ComponentModel;
using System.Collections;
using Telerik.Cms.Engine;
using Telerik.Blogs;
using Telerik.Cms;
using System.Web.UI;
using Telerik.Cms.Engine.Data;
using System.Web.UI.WebControls;
using Telerik.Web;


namespace Ramp
{
/// 
/// Summary description for TagsListFiltered
/// 
public class TagsListFiltered : TagsList
{
public TagsListFiltered()
{

}

#region Private contstraints
private Guid[] selectedBlogs = new Guid[] { };
private BlogManager blogManager;
#endregion

public override string LayoutTemplatePath
{
 get
 {
    return "~/Sitefinity/ControlTemplates/Generic_Content/TagsList.ascx";
 }
}

[TypeConverter("Telerik.Blogs.WebControls.SelectedBlogsConverter, Telerik.Blogs")]
[WebEditor("Telerik.Blogs.WebControls.BlogsSelector, Telerik.Blogs")]
public Guid[] SelectedBlogs
{
    get
    {
        return this.selectedBlogs;
    }
    set
    {
        this.selectedBlogs = value;
    }
}

#region Methods

protected override void InitializeControls(Control controlContainer)
{
 IList<ITag> blogTags = new List<ITag>();

 blogManager = new BlogManager("Blogs");
 if (this.selectedBlogs.Length == 0)
 {
    // call the base class we will not change anything. 
    //base.BindCategories();
 }
 else
 {
    IList allBlogs = blogManager.GetBlogs(selectedBlogs);
    foreach (IBlog blog in allBlogs)
    {
        IList blogPosts = blog.Posts;
        foreach (IContent post in blogPosts)
        {
            IList postTags = blogManager.Content.GetTags(post.ID);
            foreach (ITag tag in postTags)
            {
                if (!blogTags.Contains(tag))
                {
                    blogTags.Add(tag);
                }
            }
        }
    }

    if (this.DefaultDisplayMode == DisplayMode.List)
    {
        this.TagsRepeaterList.DataSource = blogTags;
        this.TagsRepeaterList.ItemDataBound += new RepeaterItemEventHandler(this.TagsRepeaterList_ItemDataBound);
        this.TagsRepeaterList.DataBind();
    }
    else
    {
        this.TagsRepeaterCloud.DataSource = blogTags;
        this.TagsRepeaterCloud.ItemDataBound += new RepeaterItemEventHandler(this.TagsRepeaterCloud_ItemDataBound);
        this.TagsRepeaterCloud.DataBind();
    }

    if (this.ControlTitleControl != null)
    {
        this.ControlTitleControl.Text = this.ControlTitle;
    }

    this.TagsRepeaterCloud.Visible = this.DefaultDisplayMode == DisplayMode.Cloud;
    this.TagsRepeaterList.Visible = this.DefaultDisplayMode == DisplayMode.List;
    if (this.DisplayCloudLink != null)
    {
        this.DisplayCloudLink.Enabled = this.DefaultDisplayMode == DisplayMode.List;
        this.DisplayCloudLink.CommandName = "DisplayCloud";
        this.DisplayCloudLink.Command += new CommandEventHandler(this.Button_CommandNew);
    }
    if (this.DisplayListLink != null)
    {
        this.DisplayListLink.Enabled = this.DefaultDisplayMode == DisplayMode.Cloud;
        this.DisplayListLink.CommandName = "DisplayList";
        this.DisplayListLink.Command += new CommandEventHandler(this.Button_CommandNew);
    }
 }
}

private void Button_CommandNew(object sender, CommandEventArgs e)
{
 string commandName = e.CommandName;
 if (commandName != null)
 {
    if (!(commandName == "DisplayCloud"))
    {
        if (!(commandName == "DisplayList"))
        {
            return;
        }
    }
    else
    {
        this.DefaultDisplayMode = DisplayMode.Cloud;
        base.ChildControlsCreated = false;
        return;
    }
    this.DefaultDisplayMode = DisplayMode.List;
    base.ChildControlsCreated = false;
 }
}

private void TagsRepeaterCloud_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
 if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
 {
    int num3;
    ITag dataItem = (ITag)e.Item.DataItem;
    HyperLink link = (HyperLink)e.Item.FindControl("tagLink");
    link.Text = dataItem.TagName;
    link.NavigateUrl = (this.TagKeyType == TagKeyTypes.ID) ? base.ResolveUrl(this.TaggedContentUrl + "?" + this.TagItemKey + "=" + dataItem.ID.ToString()) : base.ResolveUrl(this.TaggedContentUrl + "?" + this.TagItemKey + "=" + dataItem.TagName);
    IUrlService languageService = UrlServices.GetLanguageService();
    if (languageService != null)
    {
        link.NavigateUrl = languageService.ResolveLanguageUrl(link.NavigateUrl);
    }
    float num = Convert.ToSingle(this.Manager.ContentCount(SelectedBlogs));
    float num4 = Convert.ToSingle(dataItem.ContentsTagged) / num;
    if (num4 > 0.83)
    {
        num3 = 1;
    }
    else if (num4 > 0.66)
    {
        num3 = 2;
    }
    else if (num4 > 0.5)
    {
        num3 = 3;
    }
    else if (num4 > 0.33)
    {
        num3 = 4;
    }
    else
    {
        num3 = (num4 > 0.16) ? 5 : 6;
    }
    string str = link.CssClass + num3.ToString();
    link.CssClass = str;
 }
}

private void TagsRepeaterList_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
 if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
 {
    ITag dataItem = (ITag)e.Item.DataItem;
    HyperLink link = (HyperLink)e.Item.FindControl("tagLink");
    link.Text = dataItem.TagName;
    link.NavigateUrl = (this.TagKeyType == TagKeyTypes.ID) ? base.ResolveUrl(this.TaggedContentUrl + "?" + this.TagItemKey + "=" + dataItem.ID.ToString()) : base.ResolveUrl(this.TaggedContentUrl + "?" + this.TagItemKey + "=" + dataItem.TagName);
    IUrlService languageService = UrlServices.GetLanguageService();
    if (languageService != null)
    {
        link.NavigateUrl = languageService.ResolveLanguageUrl(link.NavigateUrl);
    }
    ITextControl control = (ITextControl)e.Item.FindControl("taggedContentCount");
    control.Text = dataItem.ContentsTagged.ToString();
 }
}

#endregion
}
}

4 comments:

Anonymous said...

Thanks, Jayakrishna! One thing that's missing from your InitializeControls method is sorting. Below is a code snippet to handle sorting.


if (this.SortByPopularity)
blogTags = blogTags.OrderByDescending(t => t.ContentsTagged).ToList();
else
blogTags = blogTags.OrderBy(t => t.TagName).ToList();

One limitation I noticed is that the tag count that is shown in the list view is a count across all blogs. Given how the ITag object works, I'm not sure there is much that can be done about this, at least easily.

Anonymous said...

Great Post, it helped me a lot, the above suggestion for sorting tags list is now working for me, can you help me ?

Vipul Patel

Joshna Samala said...

Is there any simple way or a way like creating a tool for handling tags exclusively. I'm new to sitefinity. Please reply.


-Joshna
http://test-givethebest.blogspot.com
http://utilityline.blogspot.com

wethanet said...

I know this is old, but it still helped me.

I used

ITextControl control = (ITextControl)e.Item.FindControl("taggedContentCount");
//control.Text = dataItem.ContentsTagged.ToString();
int i = 0;
IList allBlogs = blogManager.GetBlogs(selectedBlogs);
foreach (IBlog blog in allBlogs)
{
IList blogPosts = blog.Posts;
foreach (IContent post in blogPosts)
{
IList postTags = blogManager.Content.GetTags(post.ID);
foreach (ITag tag in postTags)
{
if (tag == dataItem)
{
i++;
}
}
}
}
control.Text = i.ToString();

to get around the incorrect tag count issue.

Post a Comment