Reputation: 494
Imagine I have a content type that has two fields of type category: one is a taxonomy Author and another one is a taxonomy Topics, these two taxonomies are unrelated, the only 'thing' they may have in common is the component itself.
Now we go to the website as a visitor, then when the visitor clicks on a given Author I want to create a list with all the Topics that are present in Components that also contain the specific Author.
I know I could create a query object with a criteria containing both keywords from the different taxonomies to check if it retrieves any values, the problem is that I would need to do that for every single topic i.e. Author and Topic1, Author and Topic2, Author and Topic 3 etc, in the end it may mean tens of queries which I obviously don't want to do.
As I see it the taxonomy API won't help because both taxonomies and thefore their keywords are completely unrelated. Any alternatives?
Upvotes: 11
Views: 730
Reputation: 494
Based on the comment by Ram G and therefore taking as starting point the code example in live content, I have verified that the following solution works:
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Tridion.ContentDelivery.Taxonomies;
using Tridion.ContentDelivery.DynamicContent.Query;
using Tridion.ContentDelivery.DynamicContent;
namespace Asier.Web.UI
{
public class TagCloud : System.Web.UI.WebControls.WebControl
{
protected override void Render(HtmlTextWriter writer)
{
TaxonomyRelationManager relationManager = new TaxonomyRelationManager();
TaxonomyFactory taxFactory = new TaxonomyFactory();
string taxonomyUriWhichIWantTheKeywordsFrom = "tcm:69-265-512";
String[] componentUris = GetComponentUris();
String[] contextKeywordUris = GetKeywordUris();
Keyword[] contextKeywordArray = GetKeywordsFromKeywordUris(taxFactory, contextKeywordUris);
Keyword[] cloudFacets = relationManager.GetTaxonomyKeywords(taxonomyUriWhichIWantTheKeywordsFrom, componentUris, contextKeywordArray, new CompositeFilter(), 16);
ProcessKeywords(cloudFacets);
}
private static string[] GetComponentUris()
{
// This should probably be replaced with a Query object that
// retrieves the URIs dynamically
return new String[] { "tcm:69-3645-16", "tcm:69-3648-16", "tcm:69-3651-16" };
}
private static string[] GetKeywordUris()
{
// this should probably be passed in as a property of the control
return new string[] { "tcm:69-3078-1024" };
}
private static Keyword[] GetKeywordsFromKeywordUris(TaxonomyFactory taxFactory, String[] contextKeywordUris)
{
Keyword[] contextKeywordArray = new Keyword[contextKeywordUris.Length];
for (int i = 0; i < contextKeywordUris.Length; i++)
{
contextKeywordArray[i] = taxFactory.GetTaxonomyKeyword(contextKeywordUris[i]);
}
return contextKeywordArray;
}
private static void ProcessKeywords(Keyword[] cloudFacets)
{
for (int i = 0; i < cloudFacets.GetLength(0); i++)
{
if (cloudFacets[i].ReferencedContentCount > 0)
{
// Do whatever...
}
}
}
}
}
Upvotes: 2
Reputation: 1097
So you want to find all components that are tagged with a specific author and then find the corresponding Topic keyword relations of the found components?
The TaxonomyRelationManager should be able to help you here:
TaxonomyRelationManager manager = new TaxonomyRelationManager();
string[] contentWithThisAuthor = manager.GetTaxonomyContent(new Keyword(taxonomyUriOfAuthors, authorUri), false);
Keyword[] relatedTopics = manager.GetTaxonomyKeywords(taxonomyUriOfTopics, contentWithThisAuthor, new Keyword[] {}, null, 16);
Upvotes: 2
Reputation: 4829
If I understand your requirement correctly, you could get this using the combination of CategoryCriteria
and KeywordCriteria
.
CategoryCriteria
to specify which category the content tagged to in this case Topics
.
KeywordCriteria
to specify which category key value (e.g.; Author=Chris ).
PublicationCriteria pubCriteria = new PublicationCriteria(59); // publication scope
CategoryCriteria categoryCriteria = new CategoryCriteria("Topics");
KeywordCriteria taxonomyKeywordCriteria = new KeywordCriteria("Author", "Chris");
Criteria allCriteria = CriteriaFactory.And(
new Criteria[] { pubCriteria,
CriteriaFactory.And(new Criteria[] { categoryCriteria, taxonomyKeywordCriteria }) }
);
Query allComps = new Query(allCriteria);
string[] compIDs = allComps.ExecuteQuery();
Response.Write("<br /> Legth : " + compIDs.Length );
Upvotes: 3
Reputation: 622
For creating the query object, take help of a component. In the component, add these categories in seperate fields : Topic (ListBox, with Multiple Selection) Author (Dropdown, with single selection...or as desired).
In your case, select all the listbox options for Topic. Suppose you have 3 keywords viz Topic 1,Topic 2,Topic 3.
So that keywords would be formed as:
KeywordCriteria topicCriteria1= new KeywordCriteria("Topic","Topic 1");
KeywordCriteria topicCriteria2= new KeywordCriteria("Topic","Topic 2");
KeywordCriteria topicCriteria3= new KeywordCriteria("Topic","Topic 3");
Criteria[] topicCriterias = {topicCriteria1,topicCriteria2,topicCriteria3};
Criteria OrCriteria = CriteriaFactory.Or(topicCriterias);
//Create Author Criteria
KeywordCriteria AuthorCriteria= new KeywordCriteria("Author","Author 1");
//And both results
mainCriteria =CriteriaFactory.And(AuthorCriteria, topicCriterias);
//Query
query.Criteria=mainCriteria;
For selecting all the Keywords related to topic, you can write a method instead of writting individually. Hope this helps.
Upvotes: 0
Reputation: 10163
I believe you will need to make 2 KeywordCriteria
Criteria #1: Author = "Chris"
Criteria #2: Topic = "Topic1" or "Topic2" or "Topic3"
Then create a new AND criteria to combine the two
Hope that helps, please specify if you are using .NET or Java if you need some examples
Chris
Upvotes: 2