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); 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
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);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>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(); //------------------------------------------------------------------------------// <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;