Patrick's SharePoint Blog

SharePoint's Booming world

Using Social Tagging to create a Favorites web part

Posted by Patrick Boom on February 16, 2011

On my journey in the new features of SharePoint 2010, my attention was caught by the so-called ‘Social’ features of SharePoint 2010. In particular, the use of the tagging and rating functionality had my interest.

A client wanted to give end-users a quick way to register favourites on their Intranet. I immediately thought of the ‘I Like It’ button in the Ribbon, where end-users can quickly tag a page that they like. In their profile, they could see all the tags and the url’s where they placed the tags.

Unfortunately, I could not find a web part that could display the tags for a given user for a specific url, or vice versa. The latter is what I needed. And so I decided to write some small code to do that for me.

In fact, the basic principles are simple. We connect to the Users profile, retrieve their tags, get the tag we want to filter on, retrieve the urls for that tag and display those in a list. Easy right?

Social Tagging

SharePoint 2010 stores tags entered by users in their user profile. You can view the tags you entered by going to your profile page and review the Tags and Notes section. That sections shows all the notes and tags, as well as a history (activities) trail for that particular tag or note. Simply put, the information is there.

I tried to find the controls SharePoint is actually using to generate these views, but was not able to make those available through a web part. Secondly, I want to be able to control the output and settings, so I will go with my own web part anyway.

Setting up the solution

I would like to keep this post simple, so I will not go into the specific details of formatting and making things configurable. I will just show the principle.

So, start Visual Studio 2010 and create a new Empty SharePoint project. Add a new item of the type Web Part. Give it all some reasonable names and your solution explorer should resemble the following picture:

Open the Favourites.cs file and we will start adding the code. Add the following references to your project:

  • Microsoft.Office.Server (needed for the UserProfile servercontext)
  • Microsoft.Office.Server.UserProfiles (needed for the UserProfiles)
  • Microsoft.SharePoint.Taxonomy (needed for the term store)
  • Microsoft.SharePoint (needed for the normal SharePoint objects)

 GetUserUrlsByTag method

Below code shows the GetUserUrlsByTag method that will retrieve all urls from the current user for a specific tag.

private Uri[] GetUserUrlsByTag(string tag)
{
   // first get the service context
   SPContext ctx = SPContext.Current;
   SPServiceContext serviceContext = SPServiceContext.GetContext(ctx.Site);

   // Then load the UserProfileManager

   UserProfileManager mngr = new
   UserProfileManager(serviceContext);

   // Get the user’s profile

   UserProfile currentProfile = mngr.GetUserProfile(false);

   // If the user has a profile, get the SocialTagManager
   if (currentProfile != null)
   {
      SocialTagManager smngr = new
      SocialTagManager(serviceContext);

      // Get the terms for the user

      SocialTerm[] terms = smngr.GetTerms(currentProfile);
      SocialTerm favTerm = null;

      //Iterate through the terms and search for the passed tag
      foreach (SocialTerm t in terms)
      {
         if (t.Term.Name.ToLower() == tag.ToLower())
         {
            favTerm = t;
            break;
         }
      }

      // If found, get the Urls and return
      if (favTerm != null)
         return smngr.GetUrls(favTerm.Term, currentProfile);
      else
         return null;
   }
   return null;
}

The method needs to return an array of urls that have a certain tag applied to it. We first set up the context and service context for this site. We then create a UserProfileManager based on the service context and retrieve the UserProfile of the current user.

If the current user has a user profile, we create a SocialTagManager that will perform the bulk of the functionalities we need. We then get all the SocialTerms for this user. It would be better if we could request a specific Term to be retrieved, but unfortunately I have not found a method to do so. So instead, we will need to iterate through the returned terms until we find the one we want to filter on. I would be much obliged if someone know a better method of doing this. For now, it works.

Once we found the term we are interested in, we can request all the url’s for that tag by calling the SocialTagManager.GetUrls method, passing the term and the profile.

And we are done! The web part I coded contains the method call and will output all the url’s in a list. However, you can style it in the any way you want obviously. Now when users click the ‘I like it’ button in the ribbon, it will show up in their favorites web part.

To be complete, the code in the CreateChildControls method of the web part.

protected override void CreateChildControls()
{
   try
   {
      Uri[] urls = GetUserUrlsByTag(“I Like It”);
      HtmlGenericControl table = new
      HtmlGenericControl(“table”);
      Controls.Add(table);

      if (urls != null)
      {
         foreach (Uri url in urls)
         {
            HtmlGenericControl row = new
            HtmlGenericControl(“tr”);
            HtmlGenericControl cell = new
            HtmlGenericControl(“td”);

            HyperLink link = new HyperLink();
            link.NavigateUrl = url.AbsoluteUri;
            link.Text = url.AbsoluteUri;
            table.Controls.Add(row);
            row.Controls.Add(cell);
            cell.Controls.Add(link);
         }
      }
      else
      {
         Label lbl = new Label();
         lbl.Text = “No favourites found.”;
         Controls.Add(lbl);
      }
   }
   catch (SPException ex)
   {
      Label lbl = new Label();
      lbl.Text = ex.ToString();
      Controls.Add(lbl);
   }
}

And finally the output:

Improvements on this code

So, a couple of things can obviously be improved in this little piece of code.

  1. Make the input and output configurable. So selecting the term to filter on and exporting the output through XML, which allows us to use XSL for the rendering.
  2. Get details about the url’s in the profile. For example, we could retrieve the page title rather than the url by obtaining that from the page instance in the pages library.
  3. Add a button or control to the ribbon or expose that as a separate web part that does the favourite tagging. That way we can control the term we call favourite (for example, MyFavourite instead of I like it)
  4. Improve the filtering on the terms. As soon as a user gets a lot of terms, the filtering might slow down.

 Conclusion

The new Social framework of SharePoint 2010 can be used for very neat things. To bad some of the features are not exposed more through web parts, but I am sure the community will provide their own sets of controls that expose the power behind Social tagging and rating. You can find the VS project for this example here.

Till next time!

Advertisements

37 Responses to “Using Social Tagging to create a Favorites web part”

  1. You completed a number of good points there. I did a search on the theme and found nearly all people will go along with your blog.

  2. Jacquiline Schneiders said

    I just want to say I’m newbie to blogs and honestly savored your web-site. Likely I’m planning to bookmark your blog post . You amazingly have amazing stories. Thank you for sharing your web site.

  3. Fraser said

    Just wondering if there is any sample code of how to add a “new” social tag to a document (via code)

  4. Hari said

    I have put an image button onto the master page and when i click on that , the link should be added to the webpart which u developed here , just wondering how to link it (i am new to sharepoint).

    • Not sure if I understand you correctly. Could you pelase elaborate some more?

      • Hari said

        Hi,
        Thanks for the reply , i have developed a Favourites list . I creted a delegate control called favourites button when i click on that a newform.aspx appears with url field being prepopulated with the current page url . I also added an action called Add to Favourites in ecb(edit Control Block ) for announcements , Dashboards list .Now when i click on this action the url field has to be prepopulated with the current item url , i am unable to do this so please help ,
        Following gives you more idea about what i am talking about

        I have written the following code such that when clicked on ecb item context menu links list new form .aspx pops upin my wsp in visualstudio 2010

        But i want to prepopulate the url field in this newform.aspx with currentitem url . i am able to prepopulate with current page url by placing the following code in master page :

        function setDefaultParentUrl()
        {

        var url =window.location.href;
        var strArry = url.split(‘?’);
        if( strArry[1] != ‘RootFolder=&IsDlg=1’ )
        {
        var pUrl =window.parent.location.href;
        var elm;
        var elements = document.getElementsByTagName(‘input’);
        for( i=0, elm; elm=elements.item(i++); )
        if ((elm.getAttribute(‘type’) == “text”) && (elm.getAttribute(‘title’) == “URL”))
        elm.setAttribute(‘value’,pUrl);
        }

        }
        _spBodyOnLoadFunctionNames.push(‘setDefaultParentUrl’);

        But how to prepopulate the url field with current item url of the itemcontextmenu where i clicked the addtofavourites action in ecb please help me out in this aspect

        note: i could get currentitemurl by taking {itemurl} , but this doesnot work in master page , so i tried pushing this as a parameter to the setdefaultparenturl function in master page , but as i am pushing this the item url value is not getting stored.

        so wat to do in order to prepopulate with current item url in url field of newform.aspx of links list please help

  5. Hari said

    This is the folloewing code i am using to get add to favourites action in ecb and when clicked on it newform.aspx pops up

  6. Hari said

  7. Hari said

    sorry i tried posting my code here its not getting posted anyways the above info is enough i guess

  8. Hello…

    your post is good. But what should i do if i need all users information with tag/term info who like same url.
    i have tried your post with userprofile loop for all users. but it only works with current login user not for other users.

    if i put my user in to administrators from central admin then that user is able to see all user information with their tags/term. but i dont want to do so for each user.

    thanx in advance.
    Jinesh

    • What you could do is granting your application pool account administrative access to the User Profile service and run the code you mentioned using SPSecurity.RunWithElevatgedPriviliges

      Please be sure to minimize the amount of code run in such a block and that your permissions are only elevated to that of the application pool account.

      Patrick 

  9. Kevin Dube said

    hey Patrik, awesome post… i have taken your web part and modified it . 2 things i have added… i trim the length of the link which is fairly simple and i have added a delete button.. i’m going to paste the code here for everyone

    creating the deletion link…

    int length = filename.Length;
    if (length>25)
    {
    filename = filename.Substring(0, 24) + “…”;
    }

    link.Text = filename;
    LinkButton btnDel = new LinkButton();
    btnDel.Text = ” Delete”;
    btnDel.Command += new CommandEventHandler(DynamicCommand);
    btnDel.CommandArgument = url.AbsoluteUri;

    table.Controls.Add(row);
    row.Controls.Add(cell);
    delcell.Controls.Add(btnDel);

    row.Controls.Add(cellsp);
    row.Controls.Add(delcell);
    cell.Controls.Add(link);

    event handler to delete “i like it tag”

    public void DynamicCommand(object sender, CommandEventArgs e)
    {
    // first get the service context
    SPContext ctx = SPContext.Current;
    SPServiceContext serviceContext = SPServiceContext.GetContext(ctx.Site);

    // Then load the UserProfileManager
    UserProfileManager mngr = new UserProfileManager(serviceContext);
    // Get the user’s profile
    UserProfile currentProfile = mngr.GetUserProfile(false);

    // If the user has a profile, get the SocialTagManager
    if (currentProfile != null)
    {
    SocialTagManager smngr = new SocialTagManager(serviceContext);
    // Get the terms for the user
    SocialTerm[] terms = smngr.GetTerms(currentProfile);

    SocialTerm favTerm = null;

    //Iterate through the terms and search for the passed tag
    foreach (SocialTerm t in terms)
    {
    if (t.Term.Name.ToLower() == “i like it”)
    {
    favTerm = t;
    break;
    }
    }
    Uri url;
    url=new Uri(e.CommandArgument.ToString());

    // If found, get the Urls and return
    if (favTerm != null)
    smngr.DeleteTag(url, favTerm.Term);
    Controls.Clear();
    CreateChildControls();

    }

    }

    • Thanks for your contribution! Appreciated!

    • Carole said

      Thanks for your post, it was very helpful, but i have a question, when you said :

      <>

      I begin in SharePoint developpment, but I think you forgot something, no ? O_o
      Like, what/where is “cellsp” in row.Controls.Add(cellsp); OR “event handler to delete “i like it tag” ” ?

      • Carole said

        Oups, my reference was deleted…

        table.Controls.Add(row);
        row.Controls.Add(cell);
        delcell.Controls.Add(btnDel);

        row.Controls.Add(cellsp);
        row.Controls.Add(delcell);
        cell.Controls.Add(link);

  10. Mayra said

    We stumbled over here by a different page and thought I
    might check things out. I like what I see so now i am following
    you. Look forward to exploring your web page yet again.

  11. Alfonso said

    Admiring the time and effort you put into your site and
    detailed information you provide. It’s awesome to come across a blog every once in a while that isn’t the same old rehashed information.
    Excellent read! I’ve bookmarked your site and I’m including your RSS feeds to my Google account.

  12. To jest naprawdę znakomity kawałek:) Podziękowania dla
    pracujących na rzecz blogów.

  13. I’m truly enjoying the design and layout of your blog. It’s a very easy on the eyes which makes
    it much more pleasant for me to come here and visit more often.

    Did you hire out a designer to create your theme? Great work!

  14. Hey there just wanted to give you a quick heads up. The text
    in your article seem to be running off the screen in Ie.
    I’m not sure if this is a formatting issue or something to do with browser compatibility but I thought I’d post to let you know.
    The design look great though! Hope you get the issue fixed soon.
    Cheers

  15. あなたが最新のトレンドを維持して、レプリカシャネルの
    ハンドバッグを取ったが、限ら
    れた予算であなたのこと
    を強化したい場合はあなたの非常に最良の選択かもし
    れない

  16. Nie jestem aż takim Internet maniakiem jesli mam być prawdomówna, jednakże twoje forum jest tak pasjonujące i w istocie swobodnie się
    je czyta, że nie mogłam sie oderwać.W istocie miło:), tak trzymać!

    . Dziekujęza okazałą lekturę.

  17. Good blog you’ve got here.. It’s hard to find excellent writing like yours these days.
    I truly appreciate people like you! Take care!!

  18. sex said

    always i used to read smaller content that also clear their motive, and that is also happening with this article which I am reading here.

  19. These kinds of video games don’t require search engines like Google or book marks and they’re available anytime at the own fingertips.
    The ideas released for this new MMORPG title are as follows:
    . Every game has them, they are not just exclusive to the
    Browser MMORPG.

  20. Fantastic goods from you, man. I’ve understand your stuff previous
    to and you are just too magnificent. I actually like what you’ve acquired here, really like what you are stating and the way in which you say it.
    You make it entertaining and you still take care
    of to keep it smart. I can’t wait to read far more from you.
    This is actually a terrific web site.

  21. squishable said

    squishable

    Using Social Tagging to create a Favorites web part « Patrick’s SharePoint Blog

  22. Wizard99 said

    In using social tagging to create a favorites web part, how would you go about replacing the URL link with the Site Title link? Your code worked amazingly but just want to make this final adjustment. Please advise.

  23. 79k said

    I’m not sure why but this blog is loading incredibly slow for me.
    Is anyone else having this issue or is it a problem on my
    end? I’ll check back later and see if the problem still exists.

  24. Quality Rotational Molding

    Using Social Tagging to create a Favorites web part « Patrick’s SharePoint Blog

  25. In fact when someone doesn’t be aware of after that its up to other visitors that they will
    help, so here it happens.

  26. For the reason that the admin of this site is working, no question very shortly it will be renowned, due to its quality contents.|

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: