Filtering ContentLocationInfo items in custom widget

Posted by Community Admin on 04-Aug-2018 07:35

Filtering ContentLocationInfo items in custom widget

All Replies

Posted by Community Admin on 14-Nov-2016 00:00

Hi all,

We developed a custom accordion widget, that can display multiple accordion items (using bootstrap accordion) using Sitefinity Feather.

To manage the accordions and their items, we created a custom module, with a parent-child relationship (Accordion -> AccordionContent). In the backend view of the custom module, we now would like to show, on which pages the accordion/accordion content is used. For this, we  implemented IContentLocatableView in our AccordionController:

public class AccordionController : Controller, IContentLocatableView
    public Guid AccordionId get; set;
     
    public ActionResult Index()
    
        //get accordion by AccordionId with DynamicModuleManager and return view...
    
     
    public bool? DisableCanonicalUrlMetaTag get; set;
     
    [NonAction]
    public IEnumerable<IContentLocationInfo> GetLocations()
    
        var locations = new List<ContentLocationInfo>();
        var manager = DynamicModuleManager.GetManager();
         
        var accordionType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.Teasers.Accordion");
        var accordion = manager.GetItem(accordionType, this.AccordionId) as DynamicContent; //THIS fails, as this.AccordionId is not set.
 
        var accordionLocationInfo = new ContentLocationInfo()
        
            ContentType = accordionType,
            ProviderName = manager.Provider.Name
        ;
 
        //create a filter expression that only includes the accordion with the correct Id
        var filterExpression = string.Format("(Id = 0 OR OriginalContentId = 0)", accordion.OriginalContentId.ToString("D"));
        accordionLocationInfo.Filters.Add(new BasicContentLocationFilter(filterExpression));
 
        locations.Add(accordionLocationInfo);
 
        //also add all child items of accordion (= AccordionContent)
        var accordionContentType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.Teasers.AccordionContent");
        var accordionContentLocationInfo = new ContentLocationInfo()
        
            ContentType = accordionContentType,
            ProviderName = manager.Provider.Name
        ;
 
        //create a filter expression to filter the AccordionContent by parent Id
        var contentFilterExpression = string.Format("(Parent.Id = 0 OR Parent.OriginalContentId = 0)", accordion.OriginalContentId.ToString("D"));
        accordionContentLocationInfo.Filters.Add(new BasicContentLocationFilter(contentFilterExpression));
 
        locations.Add(accordionContentLocationInfo);
 
        return locations;
    

And at this point we are stuck: When saving a page, Sitefinity correctly calls GetLocations() but the call occurs before the AccordionId property is set. Therefore, we cannot load our dynamic content by id and GetLocations throws an exception.

Has anybody faced a similar problem and can give me a hint how to solve this?

Thanks in advance,
Matthias

Posted by Community Admin on 24-Nov-2016 00:00

Hello Matthias, Thank you for contacting Sitefinity support. In order the properties to be populated when the IContentLocatableView methods are executed, the properties should be part of the Model. Sample code Controller: using SitefinityWebApp.Mvc.Models; using System.Collections.Generic; using System.ComponentModel; using System.Web.Mvc; using Telerik.Sitefinity.ContentLocations; using Telerik.Sitefinity.Modules.News; using Telerik.Sitefinity.Mvc; using Telerik.Sitefinity.News.Model; namespace SitefinityWebApp.Mvc.Controllers [ControllerToolboxItem(Name = "NewsWidget", Title = "NewsWidget", SectionName = "MvcWidgets")] public class NewsWidgetController : Controller, IContentLocatableView [TypeConverter(typeof(ExpandableObjectConverter))] public NewsWidgetModel Model get if (this.model == null) this.model = new NewsWidgetModel(); return this.model; public bool? DisableCanonicalUrlMetaTag get; set; /// /// This is the default Action. /// public ActionResult Index() return View("Default"); public IEnumerable GetLocations() string itemTitle = this.Model.Title; if (string.IsNullOrEmpty(itemTitle)) return null; var locations = new List(); var providerName = NewsManager.GetManager().Provider.Name; var listItemsLocation = new ContentLocationInfo() ContentType = typeof(NewsItem), ProviderName = providerName ; string filter = string.Empty; filter = @"Title = """ + itemTitle + @""""; listItemsLocation.Filters.Add(new BasicContentLocationFilter(filter)); locations.Add(listItemsLocation); return locations; private NewsWidgetModel model; Model: using System; namespace SitefinityWebApp.Mvc.Models public class NewsWidgetModel public string Title get; set; For Ids use the OriginalContentId property. I have updated the forum thread as well. Regards, Nikola Zagorchev Telerik by Progress

This thread is closed