Creating the master list view

You use the master list view to display the list of published items on the website. To create the master list view, perform the following:

  1. From the context menu of folder Web » UI » Public, click Add » Class.

  2. In the Name input field, enter MasterListView.

  3. Open the file in Visual Studio and add the following namespaces:

    using ProductCatalogSample.Data;
    using ProductCatalogSample.Model;
    using Telerik.Sitefinity;
    using Telerik.Sitefinity.Abstractions;
    using Telerik.Sitefinity.GenericContent.Model;
    using Telerik.Sitefinity.Model;
    using Telerik.Sitefinity.Modules;
    using Telerik.Sitefinity.Web.UI;
    using Telerik.Sitefinity.Web.UI.Comments;
    using Telerik.Sitefinity.Web.UI.ContentUI.Contracts;
    using Telerik.Sitefinity.Web.UI.ContentUI.Views;
    using Telerik.Sitefinity.Web.UI.ContentUI.Views.Backend;
    using Telerik.Sitefinity.Web.UrlEvaluation;
    using Telerik.Web.UI;

  4. Change the class definition to:

    public class MasterListView : MasterViewBase
    {
     
    }
  5. Mark the class with the following attribute:

    [ControlTemplateInfo("ProductsResources", "MasterListViewFriendlyName", "ModuleTitle")]
  6. Define the following constants:

    internal const string titlesOnlyLayoutTemplateName = "Telerik.Sitefinity.Resources.Templates.Frontend.News.TitlesOnlyListView.ascx";
    internal const string titlesDatesLayoutTemplateName = "Telerik.Sitefinity.Resources.Templates.Frontend.News.TitlesDatesListView.ascx";
    internal const string titlesDatesSummariesLayoutTemplateName = "Telerik.Sitefinity.Resources.Templates.Frontend.News.TitlesDatesSummariesListView.ascx";
    internal const string titlesDatesContentsLayoutTemplateName = "Telerik.Sitefinity.Resources.Templates.Frontend.News.TitlesDatesContentsListView.ascx";

    They are the names of the embedded resources that represent the templates of the MasterListView control of the News module. Because the Products module has a similar functionality as the News module, you can reuse the templates. The logic of choosing a template is implemented in the control designer for the ProductsView control.

  7. Reference one of the embedded templates by pasting the following code into the class body:

    protected override string LayoutTemplateName
    {
        get
        {
            return null;
        }
    }
     
    public override string LayoutTemplatePath
    {
        get
        {
            return "~/SFRes/" + titlesDatesLayoutTemplateName;
        }
        set
        {
            base.LayoutTemplatePath = value;
        }
    }

    The ~/SFRes/ virtual path is registered in the module class.

  8. Provide properties for accessing the controls in the template in the following way:

    protected internal virtual RadListView NewsList
    {
        get
        {
            return this.Container.GetControl<RadListView>("NewsList", true);
        }
    }
     
    protected internal virtual Pager Pager
    {
        get
        {
            return this.Container.GetControl<Pager>("pager", true);
        }
    }
  9. Override the InitializeControls method to retrieve and display the items by pasting this code:

    protected override void InitializeControls(GenericContainer container, IContentViewDefinition definition)
    {
        var masterDefinition = definition as IContentViewMasterDefinition;
        if (masterDefinition != null)
        {
            var manager = ProductsManager.GetManager(this.Host.ControlDefinition.ProviderName);
            var query = manager.GetProducts();
     
            if (masterDefinition.AllowUrlQueries.HasValue && masterDefinition.AllowUrlQueries.Value)
            {
                query = this.EvaluateUrl(query, "Date", "PublicationDate", this.Host.UrlEvaluationMode, this.Host.UrlKeyPrefix);
                query = this.EvaluateUrl(query, "Author", "Owner", this.Host.UrlEvaluationMode, this.Host.UrlKeyPrefix);
                query = this.EvaluateUrl(query, "Taxonomy", "", typeof(ProductItem), this.Host.UrlEvaluationMode, this.Host.UrlKeyPrefix);
            }
     
            int? totalCount = 0;
            int? itemsToSkip = 0;
            if (masterDefinition.AllowPaging.HasValue && masterDefinition.AllowPaging.Value)
            {
                itemsToSkip = this.GetItemsToSkipCount(masterDefinition.ItemsPerPage, this.Host.UrlEvaluationMode, this.Host.UrlKeyPrefix);
            }
     
            CultureInfo uiCulture = null;
            if (AppSettings.CurrentSettings.Multilingual)
            {
                uiCulture = System.Globalization.CultureInfo.CurrentUICulture;
            }
            //the filter is udpated to the implementation of ILifecycleDataItemGeneric, so the culture is taken in advance when filtering published items.
            this.FilterExpression = ContentHelper.AdaptMultilingualFilterExpression(this.FilterExpression);
            var filterExpression = DefinitionsHelper.GetFilterExpression(this.FilterExpression, this.AdditionalFilter);
            query = Telerik.Sitefinity.Data.DataProviderBase.SetExpressions(
                query,
                filterExpression,
                masterDefinition.SortExpression,
                uiCulture,
                itemsToSkip,
                masterDefinition.ItemsPerPage,
                ref totalCount);
     
            this.IsEmptyView = (totalCount == 0);
     
            if (totalCount == 0)
            {
                this.NewsList.Visible = false;
            }
            else
            {
                this.ConfigurePager(totalCount.Value, masterDefinition);
                this.NewsList.DataSource = query.ToList();
                this.NewsList.PreRender += new EventHandler(NewsList_PreRender);
            }
        }
    }
     
    private void NewsList_PreRender(object sender, System.EventArgs e)
    {
        // In ItemDataBound NavigateUrl property of the link is still not set. That is the reason why this logic is implemented in PreRender.
        foreach (var item in this.NewsList.Items)
        {
            if (item.ItemType == RadListViewItemType.DataItem || item.ItemType == RadListViewItemType.AlternatingItem)
            {
                var itemCommentsLink = item.FindControl("itemCommentsLink") as CommentsBox;
                if (itemCommentsLink != null)
                {
                    var dataItem = item.DataItem as Telerik.Sitefinity.GenericContent.Model.Content;
                    if (dataItem != null)
                    {
                        var query = this.GetCommentsQuery(dataItem);
                        var commentsCount = query.Count();
                        itemCommentsLink.CommentsCount = commentsCount;
                    }
                }
            }
        }
    }
     
    private IQueryable<Comment> GetCommentsQuery(Content dataItem)
    {
        var id = dataItem.Id;
        IQueryable<Comment> query = null;
        var commentsSettings = new CommentsSettingsWrapper(dataItem, this.MasterViewDefinition.CommentsSettingsDefinition);
        if (commentsSettings.HideCommentsAfterNumberOfDays)
        {
            var numberOfDaysToHideComments = commentsSettings.NumberOfDaysToHideComments;
            var duration = new TimeSpan(numberOfDaysToHideComments, 0, 0, 0);
            var manager = ProductsManager.GetManager(this.Host.ControlDefinition.ProviderName);
            query = manager.GetComments().Where<Comment>(c => c.CommentedItemID == id &&
                                                                    c.CommentStatus == CommentStatus.Published &&
                                                                    c.DateCreated > DateTime.UtcNow.Subtract(duration));
        }
        else
        {
            var manager = ProductsManager.GetManager(this.Host.ControlDefinition.ProviderName);
            query = manager.GetComments().Where<Comment>(c => c.CommentedItemID == id && c.CommentStatus == CommentStatus.Published);
        }
     
        return query;
    }
  10. Configure the pager by pasting this code:

    protected virtual void ConfigurePager(int virtualItemCount, IContentViewMasterDefinition masterDefinition)
    {
        if (masterDefinition.AllowPaging.HasValue &&
            masterDefinition.AllowPaging.Value &&
            masterDefinition.ItemsPerPage.GetValueOrDefault() > 0)
        {
            this.Pager.VirtualItemCount = virtualItemCount;
            this.Pager.PageSize = masterDefinition.ItemsPerPage.Value;
            this.Pager.QueryParamKey = this.Host.UrlKeyPrefix;
        }
        else
        {
            this.Pager.Visible = false;
        }
    }
  11. Save the file.

The master list view is loaded by the Products view to display the list of published items on the website. It inherits from MasterViewBase. You create the Products view in Creating the products view.

In the markup, first, you register the necessary assemblies, so that they can be used in the template. You create a RadListView to display all items.

In MasterListView.cs, you reference the controls from the MasterListView.ascx by calling GetControl. Then, you override the InitializeControls method to retrieve and display the items and add support for paging results by configuring the pager.

Next steps

+1-888-365-2779
sales@sitefinity.com

Related topics:

Feedback

How useful is this article?

Tell us more

Submit
Your message was successfully sent.

We appreciate your feedback.

Your message could not be sent.

OK