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;