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

Forums / Developing with Sitefinity / Filtering ContentLocationInfo items in custom widget

Filtering ContentLocationInfo items in custom widget

2 posts, 0 answered
  1. Matthias
    Matthias avatar
    1 posts
    Registered:
    11 Aug 2011
    14 Nov
    Link to this post
    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
  2. Telerik Admin
    Telerik Admin avatar
    188 posts
    Registered:
    02 Oct 2004
    24 Nov
    Link to this post
    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
2 posts, 0 answered