Get related news items from tags? - Front- & Back-End Development - Front- & Back-End Development - Progress Community
 Front- & Back-End Development

Get related news items from tags?

  • Get related news items from tags?
  • Hi everyone,
    I just need to know how can I have related news items to a news having specific tags?
    For example, if
    News item 1 is tagged with people, runway and crowd.
    And other News item 2 have tag people
    And other News item 3 have tag crowd and runway

    Then News item 1 related news should be (ordered by most close match):
    News item 3
    News item 2

    I am trying to achieve this using Fluent API methods for NewsItem but unable to do it as it throws new kind of error with any new change.
  • Hi Saad,

     You can achieve this by querying firstly all of the related News Items that have one of the categories. And then further filter them by the different tags they contain. Here's a sample code that does this - it assumes that the particular item contains 3 tags but you can further extend it:

    NewsItem particularItem = App.WorkWith().NewsItems().Where(i => i.Title == "B").Get().First();
                var list = particularItem.GetValue<TrackedList<Guid>>("Tags");
                List<NewsItem> allItemsWithoutParticular = App.WorkWith().NewsItems()
                                                     
                                                    .Where(t => t.Status == ContentLifecycleStatus.Live)
                                                    .Where(t => !t.Title.Equals("B"))
                                                    .Get()
                                                    .ToList();
                List<NewsItem> listOfClosestRelations = new List<NewsItem>();
                List<NewsItem> listOfNotSoCloseRelation = new List<NewsItem>();
                List<NewsItem> listOfFurthestRelation = new List<NewsItem>();
                foreach (var item in allItemsWithoutParticular)
                
                    TrackedList<Guid> tags = item.GetValue<TrackedList<Guid>>("Tags");
                    if (tags.Contains(list[0]) && tags.Contains(list[1]) && tags.Contains(list[2]))
                    
                        listOfClosestRelations.Add(item);
                    
                    else if ((tags.Contains(list[0]) && tags.Contains(list[1])) ||
                             (tags.Contains(list[1]) && tags.Contains(list[2])) ||
                             (tags.Contains(list[0]) && tags.Contains(list[2])))
                    
                        listOfNotSoCloseRelation.Add(item);
                    
     
                    else if (tags.Contains(list[0]) ||
                             tags.Contains(list[1]) ||
                             tags.Contains(list[2]))
                    
                        listOfFurthestRelation.Add(item);
                    
     
                

    Let me know if this solves your issue.

    All the best,
    Svetoslav Petsov
    the Telerik team
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • I'm referencing the code posted by Svetoslav. I am trying to show related articles by tags as well but using the above code as a reference throws the following error: 

        'Telerik.Sitefinity.News.Model' does not contain a definition for 'GetValue'

    Any thoughts?

    I'm using Sitefinity 4.3
  • Lizbeth,

    be sure to include the namespace Telerik.Sitefinity.Model as this is the one that contains the extension method GetValue() for content items.

    hope this is helpful!
  • Can someone give me a full code example for how to achieve related news?

    Thanks,
    Paul
  • 15bebb3c-ba6a-496f-b8e6-d3b697dc4f6c_RelatedNewsCustom.rar
    Hello Paul,

    Please find the attached .rar file to this post. The template in it is based on the one from this blog post, but it is modified accordingly for news items. 

    Copy the files inside into your project and build the solution. Then go to the page where the News widget is and click on its Edit button. After that go to Advanced->ControlDefinitions->Views and locate the field TemplatePath. In it write down the relative path to the template e.g. ~/folder/folder/RelatedNewsCustom.ascx.

    Now you'll be able to display the related by Category news items. If you want to relate them by Tag, just go to the code file of the template and change the higlighted to "Tag".

    var assignedTags = newsItem.GetValue<TrackedList<Guid>>("Category");
                    var relatedSource = manager.GetNewsItems().Where(n => n.GetValue<TrackedList<Guid>>("Category").Any(t => assignedTags.Contains(t)) && n.Id != newsItem.Id && n.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live);

    Greetings,
    Pavel Benov
    the Telerik team
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • This seems like a solution to exactly what I need. I am trying to add a widget to a page that is used for displaying single news items. I want to have a widget that displays other news articles in the same category. My lack of Sitefinity knowledge though means I have know idea how to "copy the files inside into your project and build the solution." Any help?
  • Hi Daniel,

    There is a attached .rar file (RelatedNewsCustom.rar) at the end of the Pavel Benov's forum post here. Scroll to the end of his post and click on the following link to download the attached file from his post:
    Click here to download that attached rar file.

    After downloading the .rar file unzip this and there should have three files inside that .rar file. (RelatedNewsCustom.ascx, RelatedNewsCustom.ascx.cs and RelatedNewsCustom.ascx.designer.cs)

    or followings are the code of these three files:

    RelatedNewsCustom.ascx
    <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="RelatedNewsCustom.ascx.cs" Inherits="SitefinityWebApp.Widgets.RelatedNewsCustom" %>
    <%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI" Assembly="Telerik.Sitefinity" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.ContentUI" Assembly="Telerik.Sitefinity" %>
    <%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI.PublicControls.BrowseAndEdit"
        Assembly="Telerik.Sitefinity" %>
    <telerik:RadListView ID="DetailsView" ItemPlaceholderID="ItemContainer" AllowPaging="False"
        runat="server" EnableEmbeddedSkins="false" EnableEmbeddedBaseStylesheet="false">
        <layouttemplate>
            <div class="sfnewsDetails">
                <%-- <div class="sfnewsLinksWrp">
                    <sf:MasterViewHyperLink class="sfnewsBack" Text="<%$ Resources:NewsResources, AllNews %>" runat="server" />
                </div> --%>
                <asp:PlaceHolder ID="ItemContainer" runat="server" />
            </div>
        </layouttemplate>
        <itemtemplate>
            <h1 class="sfnewsTitle">
                <asp:Literal ID="Literal1" Text='<%# Eval("Title") %>' runat="server" />
            </h1>
            <div class="sfnewsAuthorAndDate">
                <asp:Literal ID="Literal2" Text="<%$ Resources:Labels, By %>" runat="server" />
                <sf:PersonProfileView ID="PersonProfileView1" runat="server" /> | <sf:FieldListView ID="PublicationDate" runat="server"
                    Format="PublicationDate.ToLocal():MMM dd, yyyy" />
            </div>
            <sf:ContentBrowseAndEditToolbar ID="BrowseAndEditToolbar" runat="server" Mode="Edit,Delete,Unpublish"></sf:ContentBrowseAndEditToolbar>
            <sf:FieldListView ID="summary" runat="server" Text="0" Properties="Summary" WrapperTagName="div" WrapperTagCssClass="sfnewsSummary"  />
            <div class="sfnewsContent">
                <asp:Literal ID="Literal3" Text='<%# Eval("Content") %>' runat="server" />
            </div>
     
        <asp:PlaceHolder ID="socialOptionsContainer" runat="server">
       
        </asp:PlaceHolder>
     
            <sf:ContentView
                 id="commentsListView"
                 ControlDefinitionName="NewsCommentsFrontend"
                 MasterViewName="CommentsMasterView"
                 ContentViewDisplayMode="Master"
                 runat="server" />
             <sf:ContentView
                 id="commentsDetailsView"
                 ControlDefinitionName="NewsCommentsFrontend"
                 DetailViewName="CommentsDetailsView"
                 ContentViewDisplayMode="Detail"
                 runat="server" />
        </itemtemplate>
    </telerik:RadListView>
     
    <telerik:RadListView ID="RadListView1" ItemPlaceholderID="ItemsContainer" runat="server" EnableEmbeddedSkins="false" EnableEmbeddedBaseStylesheet="false">
        <LayoutTemplate>
            <sf:ContentBrowseAndEditToolbar ID="MainBrowseAndEditToolbar" runat="server" Mode="Add"></sf:ContentBrowseAndEditToolbar>
            <ul class="sfnewsList sfnewsListTitleDateSummary">
                <asp:PlaceHolder ID="ItemsContainer" runat="server" />
            </ul>
        </LayoutTemplate>
        <ItemTemplate>
            <li class="sfnewsListItem">
                <h2 class="sfnewsTitle">
                    <sf:DetailsViewHyperLink ID="DetailsViewHyperLink1" TextDataField="Title" ToolTipDataField="Description" runat="server" />
                </h2>
                <div class="sfnewsMetaInfo">
                    <sf:FieldListView ID="PublicationDate" runat="server" Format="PublicationDate.ToLocal():MMM dd, yyyy" />
                </div>
     
                <sf:FieldListView ID="summary" runat="server" Text="0" Properties="Summary" WrapperTagName="div" WrapperTagCssClass="sfnewsSummary"  />
     
                <sf:DetailsViewHyperLink ID="FullStory" Text="Full story" runat="server" CssClass="sfnewsFullStory" />
                <sf:ContentBrowseAndEditToolbar ID="BrowseAndEditToolbar" runat="server" Mode="Edit,Delete,Unpublish"></sf:ContentBrowseAndEditToolbar>
            </li>
        </ItemTemplate>
    </telerik:RadListView>

    RelatedNewsCustom.ascx.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Telerik.Sitefinity.Modules.News;
    using Telerik.Sitefinity.News.Model;
    using Telerik.Reporting.Charting;
    using Telerik.Sitefinity.Model;
    using Telerik.OpenAccess;
     
    namespace SitefinityWebApp.Widgets
        public partial class RelatedNewsCustom : System.Web.UI.UserControl
        
            protected void Page_Load(object sender, EventArgs e)
            
                var manager = NewsManager.GetManager();
                //Get the detail item URL
                var itemUrl = this.GetUrlParameterString(true);
                string redirectUrl = "";
                //Get the actual product from the URL parameters in details page URL
                var newsItem = manager.GetItemFromUrl(typeof(NewsItem), itemUrl, out redirectUrl) as NewsItem;
                if (newsItem != null)
                
                    var assignedTags = newsItem.GetValue<TrackedList<Guid>>("Category");
                    var relatedSource = manager.GetNewsItems().Where(n => n.GetValue<TrackedList<Guid>>("Category").Any(t => assignedTags.Contains(t)) && n.Id != newsItem.Id && n.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live);
     
                    // So you query template should be something like
                    //var relatedSource = manager.GetProducts().ToArray().Where(p => p.GetValue<T>("FieldName").Contains("query criteria") && p.Id != product.Id);
     
                    //Then we bind the listview
                    //If no data is present, nothing will be displayed
                    RadListView1.DataSource = relatedSource;
                    RadListView1.DataBind();
                
            
        

    RelatedNewsCustom.ascx.designer.cs
    //------------------------------------------------------------------------------
    // <auto-generated>
    //     This code was generated by a tool.
    //
    //     Changes to this file may cause incorrect behavior and will be lost if
    //     the code is regenerated.
    // </auto-generated>
    //------------------------------------------------------------------------------
     
    namespace SitefinityWebApp.Widgets
         
         
        public partial class RelatedNewsCustom
             
            /// <summary>
            /// DetailsView control.
            /// </summary>
            /// <remarks>
            /// Auto-generated field.
            /// To modify move field declaration from designer file to code-behind file.
            /// </remarks>
            protected global::Telerik.Web.UI.RadListView DetailsView;
             
            /// <summary>
            /// RadListView1 control.
            /// </summary>
            /// <remarks>
            /// Auto-generated field.
            /// To modify move field declaration from designer file to code-behind file.
            /// </remarks>
            protected global::Telerik.Web.UI.RadListView RadListView1;
        

    Copy these files inside a custom folder of the project (e.g. CustomNews) and build the project from the Visual Studio. 


    Then write the relative path into the TemplatePath field (e.g. ~/CustomNews/RelatedNewsCustom.ascx) 
    and then follow the Pavel Benov's forum post.

    Regards,
    Arnob Makhlaqur
    Telerik
     
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Sitefinity CMS Ideas&Feedback Portal and vote to affect the priority of the items