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

Forums / Developing with Sitefinity / Question regarding public view control for generic content module

Question regarding public view control for generic content module

8 posts, 0 answered
  1. David van Geel
    David van Geel avatar
    59 posts
    Registered:
    19 Aug 2009
    02 Nov 2009
    Link to this post

    Hi all,

    As one of my first projects with Sitefinity I have created a new (generic content based) module for it. The module is called Persons. Most of the issues that I had I have been able to solve with the help of the documentation and examples posted in the forums.

    At the moment I am trying to solve an issue with the publc view control I created for this module. The control uses ContentViewItemList.ascx to list items and ContentViewSingleItem.ascx  to display a single item. These ascx files are used as external templates in the ~/sitefinity/controltemplates/persons directory. To get the system to display image tags correctly I have overruled the SetItemMetadata method and added some specific code to it.

    This works fine for the image tag (id = thumb) on the ContentViewItemList.ascx page but doesnot work for the image tag (id = picture) on the ContentViewSingleItem.ascx page. For some reason the system cannot find the image tag on the ContentViewSingleItem.ascx page.  I have double checked that the system uses the correct external template and that the SetItemMetadata method is used for the ContentViewSingleItem.ascx page.

    Can someone point me in the direction of a solution?

    The code of the public view control class

    using System;  
    using Telerik.Cms.Engine.WebControls;  
    using Telerik.Lists;  
    using System.Collections;  
    using System.Web.UI.WebControls;  
     
    namespace Estate.SitefinityModules.Persons.WebControls  
    {  
        /// <summary>  
        /// Public control for displaying jobs  
        /// </summary>  
        public class PersonsPublicView : ContentView  
        {  
            /// <summary>  
            /// Gets the type from the assembly containing the embedded localization resource.  
            /// Override if embedded templates are using ASP.NET localization.  
            /// </summary>  
            /// <value></value>  
            public override Type LocalizationAssemblyInfo  
            {  
                get 
                {  
                    return typeof(ContentView);  
                }  
                set 
                {  
                    base.LocalizationAssemblyInfo = value;  
                }  
            }  
     
            /// <summary>  
            /// Gets the type from the assembly containing the embedded resources.  
            /// Cannot be null reference.  
            /// </summary>  
            /// <value></value>  
            public override Type AssemblyInfo  
            {  
                get 
                {  
                    return typeof(ContentView);  
                }  
                set 
                {  
                    base.AssemblyInfo = value;  
                }  
            }  
     
            /// <summary>  
            /// If this property is empty the control will try to detect if a provider is specified   
            /// in the request or it will use the default provider.  
            /// </summary>  
            /// <value></value>  
            public override string ProviderName  
            {  
                get 
                {  
                    object obj = ViewState["ProviderName"];  
                    if (obj != null)  
                        return (string)obj;  
                    return PersonsManager.DefaultContentProvider;  
                }  
                set 
                {  
                    ViewState["ProviderName"] = value;  
                }  
            }  
     
            protected override void SetItemMetadata(System.Web.UI.Control itemContainer, Telerik.Cms.Engine.IContent contentItem)  
            {  
                base.SetItemMetadata(itemContainer, contentItem);  
     
                Image thumb = itemContainer.FindControl("Thumb"as Image;  
                if (thumb != null)  
                {  
                    String thumbReference = contentItem.GetMetaData("Thumb").ToString();  
                      
                    if (String.IsNullOrEmpty(thumbReference))  
                    {  
                        thumb.Visible = false;  
                    }  
                    else 
                    {  
                        thumb.ImageUrl = thumbReference;  
                        thumb.AlternateText = contentItem.GetMetaData("Name").ToString();  
                    }  
                }  
     
                Image picture = itemContainer.FindControl("Picture"as Image;  
                if (picture != null)  
                {  
                    String pictureReference = contentItem.GetMetaData("Picture").ToString();  
     
                    if (String.IsNullOrEmpty(pictureReference))  
                    {  
                        picture.Visible = false;  
                    }  
                    else 
                    {  
                        picture.ImageUrl = pictureReference;  
                        picture.AlternateText = contentItem.GetMetaData("Name").ToString();  
                    }  
                }  
            }  
        }  

    The code for the ContentViewSingleItem.ascx page
    <%@ Control Language="C#" %> 
    <%@ Register Assembly="Telerik.Cms.Engine" Namespace="Telerik.Cms.Engine.WebControls" TagPrefix="sfWeb" %> 
    <%@ Register Assembly="Telerik.Cms.Web.UI" Namespace="Telerik.Cms.Web.UI" TagPrefix="sfCtrl" %> 
    <%@ Register Assembly="Telerik.Cms.Web.UI" Namespace="Telerik.Web.UI.SpamProtection" TagPrefix="sfWeb" %> 
    <%@ Register Assembly="Telerik.Cms.Web.UI" Namespace="Telerik.Cms.Web.UI" TagPrefix="sfWeb" %> 
    <%@ Register TagPrefix="sfLib" Namespace="Telerik.Libraries.WebControls" Assembly="Telerik.Libraries" %> 
    <%@ Register TagPrefix="cc1" Namespace="RandomSFCode.MetaMaster2008" Assembly="App_Code" %>   
     
    <telerik:CssFileLink ID="CssFileLink1" EmbeddedFileName="Telerik.News.Resources.ControlTemplates.Frontend.newsCommonLayout.css" FileName="" Media="screen" runat="server" /> 
    <telerik:JsFileLink id="jsLink" runat="server" ScriptType="jQuery" /> 
     
    <cc1:MetaMaster ID="MetaMaster1" runat="server">       
        <Mappings>      
            <cc1:MetaMapping MetaKey="Gallery" TargetControlId="ImageGallery" TargetProperty="FilterExpression" TargetPropertyStringFormat="ParentID = {0}" />      
        </Mappings>      
    </cc1:MetaMaster>   
     
    <div class="sf_singleContent">  
        <class="sf_back">  
           <asp:HyperLink ID="backToList1" Text="<%$Resources:GoBack %>" runat="server"></asp:HyperLink>   
        </p> 
          
        <h2 class="sf_contentTitle">  
            <asp:Literal ID="Name" runat="server"></asp:Literal> 
        </h2>      
        <class="sf_personImage">  
            <asp:Image ID="Picture" runat="server" /> 
        </p> 
        <class="sf_personQuote">  
            <asp:Literal ID="Quote" runat="server"></asp:Literal> 
        </p> 
        <p> 
            <asp:Literal ID="content" runat="server"></asp:Literal> 
        </p> 
        <p> 
            <asp:Literal ID="Address" runat="server"></asp:Literal> 
        </p> 
        <p> 
            <asp:Literal ID="Comm" runat="server"></asp:Literal> 
        </p> 
          
        <class="sf_postCategory">  
            <asp:Literal ID="Literal1" runat="server" Text="<% $Resources:Category %>" />&nbsp;  
            <asp:HyperLink ID="Category" runat="server" /> 
        </p> 
        <asp:Repeater ID="Tags" runat="server">  
            <HeaderTemplate> 
                <class="sf_postTags">  
                <asp:Literal ID="Literal2" runat="server" Text="<% $Resources:Tags %>" />&nbsp;  
            </HeaderTemplate> 
            <ItemTemplate> 
                <asp:HyperLink ID="tagLink" runat="server" /> 
            </ItemTemplate> 
            <FooterTemplate></p></FooterTemplate> 
        </asp:Repeater> 
        <!--  
        <p>   
            <sfLib:ImageGallery id="ImageGallery" runat="server" GalleryTemplateMode="Lightbox" ItemsPerPage="1" ></sfLib:ImageGallery>    
        </p> 
        -->      
        <asp:Repeater ID="Bookmarks" runat="server">  
            <HeaderTemplate><p class="sf_postBookmark"></HeaderTemplate> 
            <ItemTemplate> 
                <asp:HyperLink ID="BookmarkLink" runat="server">  
                    <asp:Image ID="BookmarkImage" runat="server" /> 
                </asp:HyperLink> 
            </ItemTemplate> 
            <FooterTemplate></p></FooterTemplate> 
        </asp:Repeater> 
        <!--  
        <div id="comments" class="sf_contentComments">  
            <sfWeb:CommentsList id="commentsList" runat="server" cssclass="sf_commentsList" ValidationGroup="commentInfo"></sfWeb:CommentsList> 
        </div> 
        --> 
    </div> 
     
  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    02 Nov 2009
    Link to this post
    Hi David van Geel,

    Use ListPageMaster and ListPageDetail templates instead of ContentViewItemList and ContentViewSingleItem templates. However the itemContainer will search only for the controls inside the repeater that displays all IContent data. As I see it your control with ID="Picture" is outside this repeater. You could find the control recursively or create a a new container.

    Greetings,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  3. David van Geel
    David van Geel avatar
    59 posts
    Registered:
    19 Aug 2009
    02 Nov 2009
    Link to this post
    Hi Ivan,

    First of all, thanks for the answer. The first part of it raises a new question. Is there a specific reason why I should use the ListPageMaster and ListPageDetail templates?

    The second part is clear. The itemContainer refers to the repeater tag which is available on the ContentViewItemList.ascx page and not on the ContentViewSingleItem.ascx page. I'll look into your suggestions.
  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    02 Nov 2009
    Link to this post
    Hi David van Geel,

    The templates you use are added for backward compatibilities. In the past we do not have control designers ( as NewsViewControlsDesigner ) and Presentation mode templates.

    Best wishes,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  5. David van Geel
    David van Geel avatar
    59 posts
    Registered:
    19 Aug 2009
    02 Nov 2009
    Link to this post
    Hi Ivan,

    Sorry to bother you again byt what do you mean by "create a new container"?

    Regards,

    David
  6. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    02 Nov 2009
    Link to this post
    Hi David van Geel,

    The container is a class that is used to serve the controls for your template. So you can access each control from the container instead of searching for it recursively every time.

    protected class ItemListContainer : GenericContainer
    {
     
      // GET YOUR CONTROLS HERE
     
    }

    All the best,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  7. David Meyer
    David Meyer avatar
    13 posts
    Registered:
    29 Oct 2009
    02 Dec 2009
    Link to this post
    I'm not sure how to get to an asp hyperlink control to tweak the NavigateUrl. I have a customized Events Detail page, ListPageMaster.ascx,  I'm trying to set an asp hyperlink to be a link to a document from the document library.  I've already got the data saving on the admin side, the link to the document is saved in a meta field. Following this post I can get the link to show up. I need to reformat the url so it doesnt look like this : [Libraries]e0cd2f48-3a41-4fa4-a077-3c05e474c188. I've done it in another page for an image, but I was able to do it inside the override SetItemMetadata. Here I cant access the hyperlink control in a codebehind. Any ideas?

     

  8. David van Geel
    David van Geel avatar
    59 posts
    Registered:
    19 Aug 2009
    02 Dec 2009
    Link to this post
    Hi David,

    For this I would override the SetItemMetadata sub. The reason why you cannot access the control may be that it is not a direct descendant of the container identified in the itemContainer variable. Atleast that is something I noticed. Here is some example code I use in the SetItemMetadata sub.

     
    protected override void SetItemMetadata(Control itemContainer, IContent contentItem)  
    {  
        base.SetItemMetadata(itemContainer, contentItem);  
     
        // check if we are looking at the single item container or the item list repeater  
        if (itemContainer.ToString() == "Telerik.Cms.Engine.WebControls.ContentView+SingleItemContainer")  
        {  
            // single item container  
     
            // determine the "real" single item container  
            Control singleItemContainer = FindContainerRecursive(itemContainer, "sf_singleContent");  
            if (singleItemContainer != null)  
            {  
                SetItemMetadataExtracted(singleItemContainer, contentItem);  
            }  
        }  
        else 
        {  
            // item list repeater  
              
            SetItemMetadataExtracted(itemContainer, contentItem);  
        }  
    }  
     
    private static void SetItemMetadataExtracted(Control Container, IContent contentItem)  
    {  
        if (Container.FindControl("sf_postCategory") != null)  
        {  
            string category = contentItem.GetMetaData("Category").ToString();  
            if (String.IsNullOrEmpty(category))  
            {  
                Container.FindControl("sf_postCategory").Visible = false;  
            }  
        }  
     
        Literal addressReference = Container.FindControl("Address"as Literal;  
        if (addressReference != null)  
        {  
            String address = contentItem.GetMetaData("Address").ToString();  
            if (!String.IsNullOrEmpty(address))  
            {  
                addressReference.Text = address.Replace("\r\n""<br />");  
            }  
            else 
            {  
                Container.FindControl("sf_personsAddress").Visible = false;  
            }  
        }  
     
        // pictures section  
        ImageGallery galleryReference = Container.FindControl("ImageGallery"as ImageGallery;  
        if (galleryReference != null)  
        {  
            String gallery = contentItem.GetMetaData("Gallery").ToString();  
            if (String.IsNullOrEmpty(gallery))  
            {  
                Container.FindControl("sf_personsGallery").Visible = false;  
            }  
            else 
            {  
                galleryReference.FilterExpression = "ParentID = " + gallery;  
            }  
        }  
    }  
     
    private Control FindContainerRecursive(Control root, string id)  
    {  
        if (root.ID != null && root.ID == id)  
            return root;  
     
        foreach (Control c in root.Controls)  
        {  
            Control rc = FindContainerRecursive(c, id);  
            if (rc != null)  
                return rc;  
        }  
        return null;  

    This code determines the correct container (repeater or item container) and then uses a recursive search function to find some controls.

    Ok, this answers your question about which sub to override. In this case you should probably look at the use of the SitefinityImage tag in the ascx file instead. I have used a meta tag in a module we created to store a reference to an image in a single line text field. Subsequently all I needed to do to get this to display correctly was to use a SitefinityImage tag instead of the .net Image tag. Here is (part of) the ascx file I created.

    <%@ Control Language="C#" %> 
    <%@ Register Assembly="Telerik.Cms.Web.UI" Namespace="Telerik.Cms.Web.UI" TagPrefix="sf" %> 
    <%@ Register TagPrefix="sf" Namespace="Telerik.Cms.Engine.WebControls" Assembly="Telerik.Cms.Engine" %> 
    <%@ Register Assembly="Telerik.Cms.Web.UI" Namespace="Telerik.Cms.Web.UI" TagPrefix="sfWeb" %> 
     
    <telerik:CssFileLink ID="CssFileLink1" EmbeddedFileName="Telerik.News.Resources.ControlTemplates.Frontend.newsCommonLayout.css" FileName="" Media="screen" runat="server" /> 
     
    <asp:Literal ID="NoPersons" runat="server" Text="<%$Resources:NoPersons %>" Visible="false"></asp:Literal> 
    <asp:Repeater ID="repeater" runat="server">  
        <HeaderTemplate> 
            <ul class="sf_genericContentList">  
        </HeaderTemplate> 
        <ItemTemplate> 
            <li> 
                <h2 class="sf_newsTitle">  
                    <asp:HyperLink ID="fullContent1" runat="server" CssClass="personsList">  
                        <asp:Literal ID="Name" runat="server"></asp:Literal> 
                    </asp:HyperLink> 
                </h2> 
                <class="sf_personsThumbnail" id="sf_personsThumbnail" runat="server">  
                    <sf:SitefinityImage ID="Thumb" runat="server" /> 
                </p> 
                <class="sf_personsSummary" id="sf_personsSummary" runat="server">  
                    <asp:Literal ID="Summary" runat="server" /> 
                </p> 
     

    Hope this helps...

    David
Register for webinar
8 posts, 0 answered