How to use Classifications > Categories widget?
I tried adding the guid from the database in the Taxonomy ID, but I cannot get it to display categories. I would like to display children of a specific category. Is this possible with the built in widget?
Hello Basem,
You can use RadTreeBinder control
<
telerik:RadTreeView
id
=
"parentTaxonTreeView"
runat
=
"server"
ShowLineImages
=
"false"
Skin
=
"Sitefinity"
ExpandAnimation-Type
=
"None"
CollapseAnimation-Type
=
"None"
/>
<
sitefinity:RadTreeBinder
id
=
"parentTaxonTreeViewBinder"
runat
=
"server"
ServiceUrl
=
"~/Sitefinity/Services/Taxonomies/HierarchicalTaxon.svc/"
ServiceChildItemsBaseUrl
=
"~/Sitefinity/Services/Taxonomies/HierarchicalTaxon.svc/subtaxa/"
ServicePredecessorBaseUrl
=
"~/Sitefinity/Services/Taxonomies/HierarchicalTaxon.svc/predecessor/"
TargetId
=
"parentTaxonTreeView"
ParentDataKeyName
=
"ParentTaxonId"
DataKeyNames
=
"Id"
RootTaxonID
=
"5e8512c3-a195-42ee-877e-8a3ebdfa948c"
DataMembers
=
"Title"
BindOnLoad
=
"true"
>
<
Containers
>
<
sitefinity:BinderContainer
ID
=
"BinderContainer1"
runat
=
"server"
RenderContainer
=
"false"
>
<
span
> Title </
span
>
</
sitefinity:BinderContainer
>
</
Containers
>
</
sitefinity:RadTreeBinder
>
Hello,
Is there any other way to get taxon by name/irl? ID is not really friendly approach.
Can Categories Widget used for this purpose?
Thanks,
Denis.
Hello Denis,
Getting an item by Id is the best way that you can use. I am not sure what do you mean by friendly way, since we allow to taxons with the same name. Then getting the item by name is not an option if you have two or more taxons with the same name but different url.
You can create a static class with method that gets all taxons and returns List<Taxon> and after that loop the list by Name or another property.
All the best,
Ivan Dimitrov
the Telerik team
Hi Ivan,
thanks for the prompt response.
I am not sure what do you mean by friendly way
I mean that in order to get taxon ID you have to browse database. That would be easier to get ID information from sitefinity backend someway.
I have another question. In this post we created custom categories widget. But we have out-of-box categories widget in sitefinity. Why we don't use this widget to achieve same thing? And how it works? It is probably simple question, but I never used categories widget before. I tried to drop this widget on my page and assign BaseUrl property. But it doesn't generate any output.
Thanks,
Denis.
Hi Denis,
Get all items and then loop through them and get the item by name. You can use a simple LINQ query to do this. I think that the out of the box widget shows items as a list.
Regards,
Ivan Dimitrov
the Telerik team
Is this what you are looking for? I hope it helps:
public
static
IEnumerable<T> GetTaxonItems<T>(ITaxon taxon)
// get the manager for the items, e.g. NewsManager
var manager = ManagerBase.GetMappedManager(
typeof
(T));
// get the base content database provider
var contentProvider = manager.Provider
as
ContentDataProviderBase;
// get a taxonomy property descriptor for this item type and taxon
TaxonomyPropertyDescriptor prop = TaxonomyManager.GetPropertyDescriptor(
typeof
(T), taxon);
int
? totalCount = 0;
// use the GetItemsByTaxon() method to return IEnumerable of items.
var items = contentProvider.GetItemsByTaxon(taxon.Id,
prop.MetaField.IsSingleTaxon,
prop.Name,
typeof
(T),
string
.Empty,
// filter
string
.Empty,
// order by
0,
// skip
100,
// take
ref
totalCount);
return
items
as
IEnumerable<T>;
var items = GetTaxonItems<NewsItem>(taxon);
var news = items
.Where(n => n.Status == ContentLifecycleStatus.Live)
.Select(n =>
new
Title = n.Title.Value,
Url = n.Urls.FirstOrDefault().Url
);
RadGrid1.DataSource = news;
RadGrid1.DataBind();
Basem and Ivan,
thank you for responses! I'm clear now about getting taxones.
I already created cusom widget that works great.
But I still doesn't understand why out-of-box categories widget doesn't generate any output for me?
I drop this widget on my page and assign BaseUrl property. What do I do wrong?
Thanks!
Denis.
Ya it took me some time to grasp the built in category widget. I believe you need to put a news list widget (or events, blogs, etc) on the same page as the category widget to get it working.
For me though, I ended up starting from scratch like this:
public
void
BuildCategoryUL(
string
name)
//GET CATEGORY BY PARENT NAME
var taxa =
this
.TaxonomyManager.GetTaxa<HierarchicalTaxon>()
.Where(t => t.Parent.Name == name)
.OrderBy(t => t.Ordinal);
//CHECK IF CHILDREN CATEGORIES EXIST
if
(taxa !=
null
&& taxa.Count() > 0)
//BUILD UL LIST OF CHILDREN CATEGORIES
if
(
this
.Output.Length == 0 && !String.IsNullOrEmpty(
this
.CssClass))
this
.Output.AppendFormat(
"<ul class=\"0\">"
,
this
.CssClass);
else
this
.Output.AppendLine(
"<ul>"
);
foreach
(var item
in
taxa)
this
.Output.AppendLine(
"<li>"
);
//BUILD LINK FOR CATEGORY PAGE
string
page = String.Empty;
if
(!String.IsNullOrEmpty(item.Description))
//PAGE STORED IN DESCRIPTION FIELD IN OUR CASE
page =
this
.ResolveUrl(item.Description);
else
//RESOLVE CONTENT PAGE WITH CATEGORY FILTER CONTROL
page =
this
.ResolveUrl(
this
.ContentPage);
//BUILD CATGORY URL FORMAT
page +=
"/-in-Category/Categories"
+ item.FullUrl;
//RENDER TITLE AS LINK
this
.Output.AppendFormat(
"<a href=\"0\" class=\"title\">1</a>"
, page, item.Title);
//RENDER DESCRIPTION IF APPLICABLE
if
(
this
.DisplayDescription)
this
.Output.AppendFormat(
"<p class=\"description\">0</p>"
, item.Description);
//RENDER CONTENT ITEMS IF APPLICABLE
if
(
this
.DisplayContentItems)
var contents = GetItems(item)
.Cast<ProductItem>()
.OrderBy(p => p.Title.Value)
.Where(p => !p.GetValue<
bool
>(
"CategoryItem"
))
.ToList();
if
(contents.Count > 0)
this
.Output.AppendLine(
"<ul>"
);
foreach
(var content
in
contents)
this
.Output.AppendLine(
"<li>"
);
//DETERMINE TITLE
string
title = content.GetValue<
string
>(
"LabelName"
);
if
(String.IsNullOrEmpty(title))
//USE TITLE AS MENU NAME IF APPLICABLE
title = content.Title;
//RENDER TITLE AS LINK
this
.Output.AppendFormat(
"<a href=\"0\" class=\"title\">1</a>"
,
this
.ResolveUrl(
this
.ContentPage + content.Urls[0].Url), title);
this
.Output.AppendLine(
"</li>"
);
this
.Output.AppendLine(
"</ul>"
);
//RECURSIVELY BUILD CHILDREN CATEGORIES
this
.BuildCategoryUL(item.Name);
this
.Output.AppendLine(
"</li>"
);
this
.Output.AppendLine(
"</ul>"
);
public
static
IEnumerable GetItems(ITaxon taxon)
string
itemTypeName =
typeof
(ProductItem).FullName;
Type itemType = TypeResolutionService.ResolveType(itemTypeName);
var manager = ManagerBase.GetMappedManager(itemType,
""
);
ContentDataProviderBase contentProvider = manager.Provider
as
ContentDataProviderBase;
TaxonomyPropertyDescriptor prop = TaxonomyManager.GetPropertyDescriptor(itemType, taxon);
int
? totalCount = 0;
var filter =
"Status = Master"
;
var items = contentProvider.GetItemsByTaxon(taxon.Id, prop.MetaField.IsSingleTaxon, prop.Name, itemType, filter, String.Empty, 0, 100,
ref
totalCount);
return
items;
Basem,
thank you for the good example!
This is looks like the best solution.
Denis.