+1-888-365-2779
Try Now
More in this section

Forums / General Discussions / Query library items by tag

Query library items by tag

21 posts, 0 answered
  1. Daniel Plomp
    Daniel Plomp avatar
    952 posts
    Registered:
    18 Feb 2004
    18 Feb 2011
    Link to this post
    Hi all,

    I want to query some items from an image library.
    I have this code:

    var images = App.WorkWith().Images().Where((w) => w.Album.Title == "Visuals" &&
                       w.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live).Get();

    ... which works.

    Now I'd like to get only images that are having a specific Tag.
    I want to do something like this, but that isn't allowed, because an Library.Model.Image cannot be cast to a ContenItem.

    List<Telerik.Sitefinity.Libraries.Model.Image> filteredImages = new List<Telerik.Sitefinity.Libraries.Model.Image>();
    foreach (Telerik.Sitefinity.Libraries.Model.Image item in images)
    {
       ContentItem i = item as ContentItem;
       if (i.TagsText.IndexOf("Visual") > -1)
          filteredImages.Add(item);
    }

    An Image doesn't have the TagsText as property.
    How should I do this?

    Regards,
    Daniel
  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    09 Dec 2016
    18 Feb 2011
    Link to this post
    Hi Daniel,

    Please take a look at this post.

    Regards,
    Ivan Dimitrov
    the Telerik team
  3. Daniel Plomp
    Daniel Plomp avatar
    112 posts
    Registered:
    14 Jun 2012
    18 Feb 2011
    Link to this post
    Hi Ivan,

    Thanks for the help.
    I don't know the GUID of the Taxon.

    I have to do it by name/title.

    Regards,
    Daniel
  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    09 Dec 2016
    18 Feb 2011
    Link to this post
    Hello Daniel,

    Use TaxonomyManager to get the taxon and then its ID.

    Best wishes,
    Ivan Dimitrov
    the Telerik team
  5. Daniel Plomp
    Daniel Plomp avatar
    112 posts
    Registered:
    14 Jun 2012
    28 Feb 2011
    Link to this post
    Thanks that worked.
  6. Basem
    Basem avatar
    131 posts
    Registered:
    22 Dec 2010
    15 Mar 2011
    Link to this post
    Here is the completed code for convenience:

    public partial class Test : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            var taxonomyManager = TaxonomyManager.GetManager();
     
            var taxon = taxonomyManager.GetTaxa<FlatTaxon>().Where(t => t.Name == "tag1").Single();
     
            string itemTypeName = "Telerik.Sitefinity.Libraries.Model.Image";
            Type itemType = TypeResolutionService.ResolveType(itemTypeName);
            var manager = ManagerBase.GetMappedManager(itemType, "");
     
            ContentDataProviderBase contentProvider = manager.Provider as ContentDataProviderBase;
            var items = GetItems(taxon, contentProvider, itemType);
     
            foreach (Telerik.Sitefinity.Libraries.Model.Image item in items)
            {
                Response.Write("ID: " + item.Id + "<br />");
                Response.Write("Url Name: " + item.UrlName + "<br />");
            }
        }
     
        private IEnumerable GetItems(ITaxon taxon, ContentDataProviderBase contentProvider, Type itemType)
        {
            TaxonomyPropertyDescriptor prop = 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;
        }
     
        private TaxonomyPropertyDescriptor GetPropertyDescriptor(Type itemType, ITaxon taxon)
        {
            return TaxonomyManager.GetPropertyDescriptor(itemType, taxon);
        }
    }

    Can't this be done with one line of Fluent API?
  7. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    09 Dec 2016
    18 Mar 2011
    Link to this post
    Hello Basem,

    There is a way through the fluent API, but again you should know the category/tag ID

    var categID = newGuid("");

    var content = App.WorkWith().NewsItems().Where(ci => ((IList<Guid>)ci.GetValue("Category")).Contains(categID));



    All the best,
    Ivan Dimitrov
    the Telerik team
  8. Michael
    Michael avatar
    4 posts
    Registered:
    23 Jan 2011
    06 May 2011
    Link to this post
    Hello,

    Does there exist a best practice for getting items by more than one Taxon.  I'm filtering NewsItems by Category and Tag.  I've been able to get a collection filtered by Category and another collection filtered by Tag and taking the intersection to get the result I want.  

    Thanks!

    Michael
  9. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    09 Dec 2016
    09 May 2011
    Link to this post
    Hi ,

    You can add logical operands to the LINQ condition.

    Best wishes,
    Ivan Dimitrov
    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
  10. Michael
    Michael avatar
    4 posts
    Registered:
    23 Jan 2011
    09 May 2011
    Link to this post
    Thanks for the reply Ivan.

    I'm not sure how I could apply logical operands here.  Here's how I got this to "work".  I know there's got to be a better way.  

    #region News
            {
                List<NewsItem> cItemsCatFilter = new List<NewsItem>();
                List<NewsItem> cItemsTagFilter = new List<NewsItem>();
                // Get Category Taxon
                HierarchicalTaxon taxonCat = _resourceCats.SingleOrDefault(rc => rc.Title.ToLower() == "news");
                 
                // Get Items
                string itemTypeName = "Telerik.Sitefinity.News.Model.NewsItem";
                Type itemType = TypeResolutionService.ResolveType(itemTypeName);
                IManager manager = ManagerBase.GetMappedManager(itemType, "");
                ContentDataProviderBase contentProvider = manager.Provider as ContentDataProviderBase;
                // Get collection filter by Category
                IEnumerable n1 = GetItems(taxonCat, contentProvider, itemType);
                cItemsCatFilter.AddRange(n1.OfType<NewsItem>());
                // Get collection filter by Tag
                IEnumerable n2 = GetItems(_tagTaxon, contentProvider, itemType);
                cItemsTagFilter.AddRange(n2.OfType<NewsItem>());
                // Filter by Tags and LifeCycle
                var items = cItemsCatFilter.Intersect<NewsItem>(cItemsTagFilter, new Utility.NewsItemComparer())
                                            .Where(ci => ci.Status != ContentLifecycleStatus.Live)
                                            .OrderBy(ci => ci.PublicationDate)
                                            .Take(5)
                                            .ToList();
     
                if (items.Count != 0)
                {
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < items.Count; i++)
                    {
                        // Create link with Title
                        sb.AppendLine("<p>" + items[i].Title + "</p>");
                        sb.AppendLine("<div style='height: 1px; background-color: #E2EBE9; margin: 5px 0;'></div>");
                    }
                     //add More Link
                    sb.AppendLine("<a href='#' style='color: Black;'><p>More News »</p></a>");
                    ltlNews.Text = sb.ToString();
                }
                else
                {
                    phNews.Visible = false;
                }
           }
      #endregion

    Thanks!

    Michael



  11. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    09 Dec 2016
    12 May 2011
    Link to this post
    Hello,

    You need to use the query as shown below

    var categID = newGuid("generate a guid here");
    var categID1 = newGuid("generate a guid here");                
     
    var content = App.WorkWith().ContentItem().Where(ci => ((IList<Guid>)ci.GetValue("Category")).Contains(categID) && ((IList<Guid>)ci.GetValue("Category")).Contains(categID1));


    Kind regards,
    Ivan Dimitrov
    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
  12. Michael
    Michael avatar
    4 posts
    Registered:
    23 Jan 2011
    12 May 2011
    Link to this post
    Hello,

    This doesn't work for filtering by TAG (taxonomy [nme] = 'Tags').  The News object does not have a property TagsText.

    Thanks!

    Michael
  13. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    16 May 2011
    Link to this post
    Hi Michael,

    The objects contain only a refence to the ID of the tag. You have to first get the Tag's ID using the taxonomy manager, then use Ivan's approach for filtering.

    Kind regards,
    Radoslav Georgiev
    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
  14. Michael
    Michael avatar
    4 posts
    Registered:
    23 Jan 2011
    24 May 2011
    Link to this post
    Hello,

    I stumbled upon the solution below after considering writing my own sprocs to get this data.  
    In using GetValue(this IDynamicFieldsContainer dataItem, string fieldName), I'm wondering where I can find all of the "fieldName" options.  

    Get News items by Tag:
    var items = App.WorkWith().NewsItems().Where(ci => ((IList<Guid>)ci.GetValue("Tags")).Contains(tagTaxonID))
                               .Get();

    Get News Items by Category:
    var items = App.WorkWith().NewsItems()
                                        .Where(ci => ((IList<Guid>)ci.GetValue("Category")).Contains(taxonCatID)).Get();

    My Example creating a list of NewsItems filltering by Category and Tag
    items = App.WorkWith().NewsItems()
                                        .Where(ci => ((IList<Guid>)ci.GetValue("Tags")).Contains(tagTaxonID))
                                        .Where(ci => ((IList<Guid>)ci.GetValue("Category")).Contains(taxonCatID))
                                        .Get()
                                        .Where(ci => ci.Status == ContentLifecycleStatus.Live)
                                        .OrderByDescending(ci => ci.PublicationDate)
                                        .ToList();

    Thanks!

    Michael
  15. Basem
    Basem avatar
    131 posts
    Registered:
    22 Dec 2010
    10 Aug 2011
    Link to this post
    The Fluent API method doesn't work with ContentItems, just with NewsItem and probably other built in modules. It seems ContentItems is too generic for it. This is the error I get:

    Database mapped field does not exist.
    Parameter name: methodCallExpression
    Actual value was ci.FieldValue("Category").

    Stack Trace:

    [ArgumentOutOfRangeException: Database mapped field does not exist.
    Parameter name: methodCallExpression
    Actual value was ci.FieldValue("Category").]
       Telerik.OpenAccess.Query.ExpressionCompiler.PerformDatabaseQueryImpl(Type type, Int32 elementAt, Object[] groupResolutionParamValues, Boolean single, Boolean checkOid) +736
       Telerik.OpenAccess.Query.ExpressionCompiler.PerformDatabaseQuery(Type type, Int32 elementAt, Object[] groupResolutionParamValues, Boolean single, Boolean checkOid) +55
    
    [InvalidOperationException: An exception occured during the execution of '
    Extent<Telerik.Sitefinity.GenericContent.Model.ContentItem>.Where(item => (item.ApplicationName == value(Telerik.Sitefinity.Modules.GenericContent.Data.OpenAccessContentProvider+<>c__DisplayClass0).appName)).Where(ci => (ci.FieldValue("Category").Any(item => item.Equals(value(Telerik.Sitefinity.Data.Linq.OpenAccess.OpenAccessExpressionVisitor`2+<>c__DisplayClassa[Telerik.Sitefinity.GenericContent.Model.ContentItem,Telerik.Sitefinity.GenericContent.Model.ContentItem]).comparingObject)) AndAlso (Convert(Convert(Convert(ci.Status))) == 2)))'. See InnerException for more details.
    ]
       Telerik.OpenAccess.Query.ExpressionCompiler.PerformDatabaseQuery(Type type, Int32 elementAt, Object[] groupResolutionParamValues, Boolean single, Boolean checkOid) +244
       Telerik.OpenAccess.Query.ExpressionExecution.PerformDatabaseQuery(Piece`1 piece, Object[] grpVals) +444
       Telerik.OpenAccess.Query.Piece`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() +37
       Telerik.Sitefinity.Data.Linq.LinqQuery`2.GetEnumerator() +83
       System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +315
       System.Linq.Enumerable.ToList(IEnumerable`1 source) +58
       SitefinityWebApp.Custom.Categories.BuildCategory(String name) in C:\Data\IIS\...\Categories.ascx.cs:105
       SitefinityWebApp.Custom.Categories.Page_Load(Object sender, EventArgs e) in C:\Data\IIS\...\Categories.ascx.cs:67
       System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
       System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
       System.Web.UI.Control.OnLoad(EventArgs e) +91
       System.Web.UI.Control.LoadRecursive() +74
       System.Web.UI.Control.LoadRecursive() +146
       System.Web.UI.Control.LoadRecursive() +146
       System.Web.UI.Control.LoadRecursive() +146
       System.Web.UI.Control.LoadRecursive() +146
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2207
    
  16. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    10 Aug 2011
    Link to this post
    Hi Basem,

    Generic Content (now Shared Content) ContentItem type does not have Category field, nor Tags fields. Probably this is causing your problems.

    Regards,
    Radoslav Georgiev
    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
  17. Basem
    Basem avatar
    131 posts
    Registered:
    22 Dec 2010
    10 Aug 2011
    Link to this post
    I was actually trying to do this for the custom Products Module. I was thinking ContentItem was the base class, but you refreshed my memory it is Content that is the base class. For a custom type like Products, it seems the Fluent API is not an option?
  18. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    10 Aug 2011
    Link to this post
    Hi Basem,

    You can try working with the App.WorkWith().AnyContentItem<T>  facade if you want to use fluent API for custom modules. There you can pass the type of your custom class and work with it.

    Greetings,
    Radoslav Georgiev
    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
  19. Basem
    Basem avatar
    131 posts
    Registered:
    22 Dec 2010
    10 Aug 2011
    Link to this post
    Looks like this is only for retrieving a single item because there is no "where" clause. "AnyContentItems" (plural) would be sweet but doesn't exist
  20. Basem
    Basem avatar
    131 posts
    Registered:
    22 Dec 2010
    10 Aug 2011
    Link to this post
    This is what I ended up doing for reference:

    public 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;
    }

    Please add AnyContentItems to the Fluent API. It would really open up doors for custom modules I think. Thanks for all the help.
  21. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    12 Aug 2011
    Link to this post
    Hi Basem,

    I have logged this in PITS.

    Regards,
    Radoslav Georgiev
    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
21 posts, 0 answered