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

Forums / Developing with Sitefinity / Public and admin searches for documents in sitefinity

Public and admin searches for documents in sitefinity

13 posts, 0 answered
  1. Derrick
    Derrick avatar
    7 posts
    Registered:
    20 Feb 2009
    23 Apr 2009
    Link to this post

    I am using SiteFinity 3.6. I have a project in which the client wants each document to belong to an access group (committee #1, committee #2, etc), meaning only visitors in the group may view the document.

    He also wants to attach about 15 items of information to each document. 

    Things such as Meeting, Year, Author, etc. I was thinking of using the Images & Documents Module and adding these items as custom fields.

    However, the client wants sitefinity admins to be able to search for documents based on multiple (1-15) fields.  For example, all the documents for a certain year and author.

    A colleague mentioned filter expressions as a possibilty.  Can filter expressions be used to perform multiple custom-field searches?  If so, can you give me an example?   

     

    Also, public users of the website will need to be able to do multiple (1-10) field searches on the documents, can filter expressions be used for this as well?

     

    Also the client wants to have public users request access to protected documents by submitting a form (name, address, email, etc.) in this form they will also request access

    to the access groups mentioned earlier (committee #1, committee #2, etc.).  Can this be done in siteFinity 3.6  or will a need to build custom user controls for this?

     

    Thanks, Derrick

  2. Dido
    Dido avatar
    149 posts
    Registered:
    24 Sep 2012
    27 Apr 2009
    Link to this post
    Hi Derrick,

    You can do without writing a new module, but it will be quite the hack :)

    Here are my ideas of how I would do it, categorized.

    How to make different libraries visible only by a given role?
    I would add a new metafield, which would be the name of the role. For example, ViewableByRole. Because groups are not IContent items, this will obviously have to be applied to every document in a library. When listing all libraries, I would check for the first item in the library (if there are no items, the group will be visible to all users), and see its ViewableByRole metafield. If there is no such field, the user is of the administrators group, or it is equal to the logged user's group, then I will show the library, otherwize, I would not bind it (practically remove it).

    This you will do in a View based on LibraryList<THost>. There, you will make the following changes:
    • Add the following methods with the exact same signature:
      • public IList GetAllLibraries(int from, int max, string sortExp)
        Here is where you will apply your filter. Call the same method from the provider and perform your filtering
      • public int GetLibrariesCount()
        Here you return the number of items returned by your GetAllLibraries method
      • public void DeleteLibrary(ILibrary library)
        Here you simply call the same method from your LibraryManager
    • In InitializeControls do something like
      protected override void InitializeControls(Control viewContainer) 
         base.InitializeControls(viewContainer); 
         ObjectDataSource odsLibraries = new ObjectDataSource { 
            ID = "LibrariesDataSource"
            TypeName = "YOUR_VIEW_NAME_WITH_NAMESPACE"
            SelectMethod = "GetAllLibraries"
            SelectCountMethod = "GetLibrariesCount"
            MaximumRowsParameterName = "max"
            StartRowIndexParameterName = "from"
            SortParameterName = "sortExp"
            DeleteMethod = "DeleteLibrary"
            EnablePaging = this.currentViewMode == LibrariesViewMode.Boxes 
         }; 
         odsLibraries.ObjectCreating += new ObjectDataSourceObjectEventHandler(this.odsLibraries_ObjectCreating); 
         odsLibraries.Selecting += new ObjectDataSourceSelectingEventHandler(this.odsLibraries_Selecting); 
         this.Controls.Add(odsLibraries); 
         this.AllLibrariesGrid.DataSourceID = odsLibraries.ID; 
         this.AllLibrariesGrid.MasterTableView.DataKeyNames = new string[] { "ID" }; 
         this.AllLibrariesGrid.ItemCommand += new GridCommandEventHandler(this.AllLibrariesGrid_ItemCommand); 
         this.AllLibrariesGrid.ItemCreated += new GridItemEventHandler(this.AllLibrariesGrid_ItemCreated); 
         this.AllLibrariesGrid.ItemDataBound += new GridItemEventHandler(this.AllLibrariesGrid_ItemDataBound); 
         if (!this.LibManager.GetPermission(CrudRights.Modify).CheckDemand()) 
         { 
            this.AllLibrariesGrid.Columns[5].Visible = false
         } 
         this.AllLibrariesRepeater.DataSourceID = odsLibraries.ID; 
         this.AllLibrariesRepeater.ItemCreated += new RepeaterItemEventHandler(this.AllLibrariesRepeater_ItemCreated); 
         this.AllLibrariesRepeater.ItemDataBound += new RepeaterItemEventHandler(this.AllLibrariesRepeater_ItemDataBound); 
    • Finally, replace the default view with your view in ControlsConfig
    I haven't tested this code, but there is no reason for it not to work. As a note - don't implement those event handlers, just call the base class' implementation.

    There is another easiest way. You should map the external template and on ItemDataBound for the repeater you can get all libraries and check the current user:

    Sample:

     
        protected void allLibraries_ItemDataBound(object sender, RepeaterItemEventArgs e) 
        { 
     
            if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) 
            { 
                ILibrary library = e.Item.DataItem as ILibrary; 
                if(library != null && library.Name == "MyLib" && UserManager.IsCurrentUserInRole("Visitors")) 
                { 
                    HtmlGenericControl libraryPanel =(HtmlGenericControl)e.Item.FindControl("libraryPanel"); 
                    libraryPanel.Visible = false
                } 
            } 
        } 


    Searching by multible meta fields

    Well, this is going to be problematic. You will have to implement searching for the Libraries module yourself.
    Again, I would use a rather "quick" hack here (bad performance). As your colleague suggested, you do not really search cached data (good performance), you get all the data and then filter it (implementing a search index for your module is the better approach). However, there is a good change that FilterExpression won't work due to limitations in Nolics.NET and OR clauses. Since IN is essentialy an OR clause, it will not work. You will have to implement filtering yourself, both the UI and logic.
    Here is what I would do:
    • Create a new provider based on Telerik.Libraries.Data.DefaultProvider
    • Add two methods that look something like:
      • public IList GetDocuments(string[] metaFields, Guid[] parentIds)
        This would filter non-image documents
      • public IList GetImages(string[] metaFields, Guid[] parentIds)
        This would filter images
    • Call these methods when you "search"
    • Register and use your new provider in web.config

    All the best,
    Dido
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  3. Garry Clark
    Garry Clark avatar
    26 posts
    Registered:
    27 Jan 2005
    15 Jul 2009
    Link to this post
    Dido,
    I am trying to do something similar, but what I want to do is store Crystal Report files in a custom library, which I already have working,
    <add name="Report" title="Report Library" defaultExtenstions=".rpt" metaKeys="Author, Description, Extension, Name, Size, Category">  
                    </add> 
    but now I am trying to decide how to display the listing to the user. Something very similar to the Download List would be great, but I need to be able to redirect a user to another page containing the Crystal Report Viewer instead of just downloading the report file, unless the download link was clicked. The page containing the Crystal Viewer would need to be able to grab the correct Report file from the library and load it into the viewer.

    Should I just create a new view altogether and implement a WebEditor of some sort or can I use a similar approach you describe here?  

    Thanks!
  4. Georgi
    Georgi avatar
    3583 posts
    Registered:
    28 Oct 2016
    21 Jul 2009
    Link to this post
    Hello Garry Clark,

    I think that you should go with a Custom ContentView based control. It should be initialized with the Libraries provider and work similar to the ContentView control - when you click on the item, you should be taken to a details page. The Images and Modules and Generic Content use one architecture, so the items are basically the same - IContent items.

    You can also prepare a custom view if you need this functionality for the backend, but in case you need it for the front end, you would better go with a custom control.
     
    Best wishes,
    Georgi
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  5. Garry Clark
    Garry Clark avatar
    26 posts
    Registered:
    27 Jan 2005
    22 Jul 2009
    Link to this post
    Georgi,
    I think I'm communicating more with you than I am most of my friends here lately :).

    Thank you for replying and I have already started work on my custom module. However is there a quick and easy way I can just inherit the ControlDesigners from the other Library public controls so that when someone places my control onto a page listing all of the reports in the library, just like the download list does for forms, that they can pick and choose the library and set filters for that paticular list or do I have to do all of that from scratch?

    Thanks again!
  6. Garry Clark
    Garry Clark avatar
    26 posts
    Registered:
    27 Jan 2005
    22 Jul 2009
    Link to this post
    Sorry Georgi,
    Apparently I am just being lazy. I did find a good article in the onlien manual describing implementing a Custom ContentView control http://www.sitefinity.com/help/developer-manual/extending-built-in-controls-example--extending-content-view-control.html. I will work my way through this and get back to you. I am assuming that the ContentView templates already have the ControlDesigners in them.

    Thanks and sorry for posting before I explored everything.
  7. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    22 Jul 2009
    Link to this post
    Hi Garry Clark,

    Just to let you know that the article is prepared under 3.5 versions of Sitefinity although there are not sensible backward changes. I suggest that you should take a look at our chm dev manual to gather more information about Sitefinity's 3.6 architecture.

    However, below are the steps that you should follow creating ContentView based control.

    1. Create a new class that inherits from ContentView
    2. Override LocalizationAssemblyInfo, AssemblyInfo, ItemListTemplatePath, ItemListTemplateName

    If you are going to use a custom designer you should also implement it.

    [Telerik.Framework.Web.Design.ControlDesigner("Telerik.Samples.WebControls.Admin.CustomDesigner")]
    public class CustomView : ContentView


    3. Your custom designer should inherit from ContentViewDesignerBase. Here override DesignerTemplateName

    4. In the designer template set the presentation modes of your control - for instance ListPageMaster and ListPageDetails.

    The same logic is used for all Sitefinity's controls.

    All the best,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  8. Garry Clark
    Garry Clark avatar
    26 posts
    Registered:
    27 Jan 2005
    23 Jul 2009
    Link to this post
    Georgi,
    Thanks for getting back to me. I had figured out that I needed to override ItemListTemplatePath, SingleTemplatePath, ItemListTemplateName, and ItemSingleTemplateName. At this point I am not sure if I will need the ItemSingleTemplate stuff, but wasn't a huge deal to override. My controls are all embedded so I had to deviate a little from the examples, but I believe this should work. I am not sure why I need to override the LocalizationAssemblyInfo and AssemblyInfo though. Can you explain this to me and provide an example if necessary because I could find none that demonstarted exactly what went into those?
     
     /// <summary>  
            /// Gets or sets the path of the template used by this control when control is displaying  
            /// list of content items  
            /// </summary>  
            /// <remarks>  
            /// The reason we are overriding this property is to set different default value  
            /// </remarks>  
            /// <summary>  
            /// Gets or sets the path to a custom layout template for the control.  
            /// </summary>          
            [WebSysTemplate(ReportListing.SettingsIListTemplateName  
                , "ListItemDescription""/Sitefinity/"false"2009-03-15")]  
            public override string ItemListTemplatePath  
            {  
                get 
                {  
                    return base.ItemListTemplatePath;  
                }  
                set 
                {  
                    base.ItemListTemplatePath = value;  
                }  
            }  
     
            /// <summary>  
            /// Gets of sets the path of the template used by this control when control is displaying  
            /// one single content item.  
            /// </summary>  
            /// <remarks>  
            /// The reason we are overriding this property is to set different default value  
            /// </remarks>  
            [WebSysTemplate(ReportListing.SettingsSingleTemplateName  
                , "SingleItemDescription""/Sitefinity/"false"2009-03-15")]  
            public override string SingleItemTemplatePath  
            {  
                get 
                {  
                    return base.SingleItemTemplatePath;  
                }  
                set 
                {  
                    base.SingleItemTemplatePath = value;  
                }  
            }  
     
            /// <summary>  
            /// Gets the name of the embedded layout template.  
            /// </summary>  
            public override string ItemListTemplateName  
            {  
                get 
                {  
                    return ReportListing.SettingsIListTemplateName;  
                }  
            }  
            /// <summary>  
            /// Gets the name of the embedded layout template.  
            /// </summary>  
            public override string SingleItemTemplateName  
            {  
                get 
                {  
                    return ReportListing.SettingsSingleTemplateName;  
                }  
            } 

    Another question I have is in a SimpleControl, which 99% of my Sitefintiy modules are based off of give me the ability to define control references in my embedded Template as such:
    #region Control References  
     
            protected virtual Label labelStatus  
            {  
                get 
                {  
                    return base.Container.GetControl<Label>("labelStatus"true);  
                }  
            }  
            protected virtual MultiView multiView  
            {  
                get 
                {  
                    return base.Container.GetControl<MultiView>("multiView"true);  
                }  
            }  
            protected virtual Telerik.Web.UI.RadGrid GridListing  
            {  
                get 
                {  
                    return base.Container.GetControl<Telerik.Web.UI.RadGrid>("gridListing"true);  
                }  
            }  
     
            protected virtual Label labelMessage  
            {  
                get 
                {  
                    return base.Container.GetControl<Label>("labelMessage"true);  
                }  
            }
            #endregion 

     and then I initialize them like so

    /// <summary>  
            /// Initializes the controls.  
            /// </summary>  
            /// <param name="controlContainer">The control container.</param>  
            protected override void InitializeControls(Control controlContainer)  
            {  
                base.InitializeControls(controlContainer);  
                manager = new ReportManager();  
                  
                labelMessage.Text = "";  
                if (this.Page != null)  
                {                  
                    multiView.SetActiveView(multiView.Views[1]);                         
                }  
                else 
                {  
                    multiView.SetActiveView(multiView.Views[0]);  
                    labelMessage.Text = Messages.DesignerMessage;  
                }             
            } 
    however since the ContentView seems to be based off of the CompositeControl I do not have these methods to override nor do I even have a Container to work with. How do I go about getting references to my controls in the embedded template or better yet how do I implement a mechanisim that when a user clicks on a Title Link, as done by the Download List, it redirects them to the page containing the Crystal Report Viewer and passes it the Library Object that was selected.

    I've already implemented a property that allows the user to select the page containing the report viewer,
    [Category("Settings")]  
            [TypeConverter("Telerik.Cms.Web.UI.GuidTypeConverter, Telerik.Cms")]  
            [WebEditor("Telerik.Cms.Web.UI.DhlIdEditor, Telerik.Cms")]  
            [DefaultValue(typeof(Guid), "00000000-0000-0000-0000-000000000000")]  
            public Guid PageId   
            {   
                get { return pageId; } set { pageId = value; }   
            }  
            [Category("Settings")]  
            [UrlProperty]  
            [WebEditor("Telerik.Cms.Web.UI.DhlUrlEditor, Telerik.Cms")]  
            [Bindable(true)]  
            [DefaultValue("")]  
            public string NavigateUrl   
            {   
                get { return navigateUrl; }  
                set { navigateUrl = value; }   
            } 

    but now I'm kind of stuck on how to proceed since I can not get a reference to the link and do a

    HyperLink view = (HyperLink)e.Item.FindControl("View");  
                    CmsManager manager = new CmsManager();  
                    ICmsPage profilePage = (ICmsPage)manager.GetPage(pageId);  
                    if (profilePage != null && view !=null)  
                    {  
                        string profileUrl = profilePage.DefaultUrl.Url;  
     
                        view.NavigateUrl = profileUrl + "?ID=" + solicitation.Id;  
                    }  

    Any guidance you can offer Georgi I would greatly appreciate.

    Thanks as always!
  9. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    23 Jul 2009
    Link to this post
    Hello Garry Clark,

    Use the link below to gather more information about AssemblyInfo and LocalizationAssemblyInfo

    http://blogs.sitefinity.com/SearchResults.aspx?IndexCatalogue=SitefinityBlog&SearchQuery=AssemblyInfo
    http://blogs.sitefinity.com/SearchResults.aspx?IndexCatalogue=SitefinityBlog&SearchQuery=LocalizationAssemblyInfo

    In ContentView based controls you can work with listContainer and singleContainer. Another option is implementing custom controls with custom containers. Then you can InstantiateIn your container. In the container you can add references as the sample below illustrates.

     public class MyContainer : GenericContainer 
            { 
     
                public RadTreeView RTV 
                { 
                    get 
                    { 
                        if (rtv == null
                            rtv = base.GetControl<RadTreeView>("TreeView1"true, TraverseMethod.DepthFirst ); 
                        return rtv; 
                    } 
                } 
     
                private RadTreeView rtv; 
            } 
     


    Best wishes,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  10. Garry Clark
    Garry Clark avatar
    26 posts
    Registered:
    27 Jan 2005
    23 Jul 2009
    Link to this post
    Ivan,
    Thank you for responding and I have read the AssemblyInfo overrides and LocalizationAseemblyOverrides blogs so I believe I got those covered, however something is still not clicking with the control references.

    Here is my ContentView based control. Can you give me an example on how to access the Downloadink in the template below so that when a user clicks it it simply navigates them to the page selected and passes the library GUID or something so I can access it on that page. I guess my issue is that even if I implemented a custom control or used the ListContainer to get a reference to the Hyperlink to set it I have no idea what method to override to do that on. I am guessing maybe OnLoad or usually I would use ItemDataBound to do this type of work, but there appears to be no ItemDataBound to use. As you can see I think I am almost there, yet I am still completely lost.

    I mean really all I am after is exactly the same behavoir as the current DownLoad List public control except when a user clicks the Download Link I need it to navigate to another page and load the file in the Viewer rather than just downloading it or displaying it.

    As always thanks for your help and sorry my brain is not grasping the ContentView concept.
    using System;  
    using System.Web.UI;  
    using System.ComponentModel;  
    using Telerik.Web.UI;  
    using Telerik.Cms.Web.UI;  
    using Telerik.Cms;  
    using Telerik.Cms.Engine.WebControls;  
    using Telerik.Cms.Engine;  
    using GambitCreations.Sitefinity.ReportModule.Resources;  
     
    namespace GambitCreations.Sitefinity.ReportModule.WebControls.Public  
    {  
       //[Telerik.Framework.Web.Design.ControlDesigner("SolicitationListDesigner")]  
        [DefaultProperty("Settings")]  
        public class ReportListing : ContentView  
        {
            #region Properties  
            [Category("Settings")]  
            [TypeConverter("Telerik.Cms.Web.UI.GuidTypeConverter, Telerik.Cms")]  
            [WebEditor("Telerik.Cms.Web.UI.DhlIdEditor, Telerik.Cms")]  
            [DefaultValue(typeof(Guid), "00000000-0000-0000-0000-000000000000")]  
            public Guid PageId  
            {  
                get { return pageId; }  
                set { pageId = value; }  
            }  
            [Category("Settings")]  
            [UrlProperty]  
            [WebEditor("Telerik.Cms.Web.UI.DhlUrlEditor, Telerik.Cms")]  
            [Bindable(true)]  
            [DefaultValue("")]  
            public string NavigateUrl  
            {  
                get { return navigateUrl; }  
                set { navigateUrl = value; }  
            }  
            /// <summary>  
            /// Gets or sets the CSS Class  
            /// </summary>  
            /// <value></value>  
            /// <returns></returns>  
            [Category("Appearance")]  
            public string StatusCSSClass  
            {  
                get;  
                set;  
            }  
            /// <summary>  
            /// Gets or sets the url of the page where ReportListing control is located  
            /// </summary>  
            [WebEditor("Telerik.Cms.Web.UI.UrlEditorWrapper, Telerik.Cms"),  
            Category("Behavior")]  
            public virtual string ReportListingPage  
            {  
                get 
                {  
                    object obj = this.ViewState["ReportListingPage"];  
                    if (obj != null)  
                        return (string)obj;  
                    Telerik.Cms.Web.ICmsUrlContext urlContext = Telerik.Cms.Web.CmsUrlContext.Current;  
                    if (urlContext != null)  
                    {  
                        return urlContext.Path;  
                    }  
                    return String.Empty;  
                }  
                set 
                {  
                    this.ViewState["ReportListingPage"] = value;  
                }  
            }  
            /// <summary>  
            /// Gets or sets the path of the template used by this control when control is displaying  
            /// list of content items  
            /// </summary>  
            /// <remarks>  
            /// The reason we are overriding this property is to set different default value  
            /// </remarks>  
            /// <summary>  
            /// Gets or sets the path to a custom layout template for the control.  
            /// </summary>          
            [WebSysTemplate(ReportListing.SettingsIListTemplateName  
                , "ListItemDescription""/Sitefinity/"false"2009-03-15")]  
            public override string ItemListTemplatePath  
            {  
                get 
                {  
                    return base.ItemListTemplatePath;  
                }  
                set 
                {  
                    base.ItemListTemplatePath = value;  
                }  
            }  
     
            /// <summary>  
            /// Gets of sets the path of the template used by this control when control is displaying  
            /// one single content item.  
            /// </summary>  
            /// <remarks>  
            /// The reason we are overriding this property is to set different default value  
            /// </remarks>  
            [WebSysTemplate(ReportListing.SettingsSingleTemplateName  
                , "SingleItemDescription""/Sitefinity/"false"2009-03-15")]  
            public override string SingleItemTemplatePath  
            {  
                get 
                {  
                    return base.SingleItemTemplatePath;  
                }  
                set 
                {  
                    base.SingleItemTemplatePath = value;  
                }  
            }  
     
            /// <summary>  
            /// Gets the name of the embedded layout template.  
            /// </summary>  
            public override string ItemListTemplateName  
            {  
                get 
                {  
                    return ReportListing.SettingsIListTemplateName;  
                }  
            }  
            /// <summary>  
            /// Gets the name of the embedded layout template.  
            /// </summary>  
            public override string SingleItemTemplateName  
            {  
                get 
                {  
                    return ReportListing.SettingsSingleTemplateName;  
                }  
            }
            #endregion  
     
            #region Control References   
             
           //protected virtual MultiView multiView  
           // {  
           //     get  
           //     {  
           //         return base.Controls.GetControl<MultiView>("multiView", true);                  
           //     }  
           // }          
           // protected virtual Label labelMessage  
           // {  
           //     get  
           //     {  
           //         return base.Container.GetControl<Label>("labelMessage", true);  
           //     }  
           // }  
            #endregion
            #region Methods  
     
            /// <summary>  
            /// Raises the <see cref="E:System.Web.UI.Control.Init"/> event.  
            /// </summary>  
            /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>  
            protected override void OnInit(EventArgs e)  
            {  
                base.OnInit(e);  
                if (base.Page != null)  
                    base.Page.RegisterRequiresControlState(this);  
            }  
     
            /// <summary>  
            /// Gets the <see cref="T:System.Web.UI.HtmlTextWriterTag"/> value that corresponds to this Web server control. This property is used primarily by control developers.  
            /// </summary>  
            /// <value></value>  
            /// <returns>One of the <see cref="T:System.Web.UI.HtmlTextWriterTag"/> enumeration values.</returns>  
            protected override HtmlTextWriterTag TagKey  
            {  
                get 
                {  
                    return HtmlTextWriterTag.Div;  
                }  
            }  
     
            /// <summary>  
            /// Adds HTML attributes and styles that need to be rendered to the specified <see cref="T:System.Web.UI.HtmlTextWriterTag"/>. This method is used primarily by control developers.  
            /// </summary>  
            /// <param name="writer">A <see cref="T:System.Web.UI.HtmlTextWriter"/> that represents the output stream to render HTML content on the client.</param>  
            protected override void AddAttributesToRender(HtmlTextWriter writer)  
            {  
                base.AddAttributesToRender(writer);  
                if (!String.IsNullOrEmpty(this.CssClass))  
                    writer.AddAttribute(HtmlTextWriterAttribute.Class, this.CssClass);  
            }  
     
            /// <summary>  
            /// Restores control-state information from a previous page request that was saved by the <see cref="M:System.Web.UI.Control.SaveControlState"/> method.  
            /// </summary>  
            /// <param name="savedState">An <see cref="T:System.Object"/> that represents the control state to be restored.</param>  
            protected override void LoadControlState(object savedState)  
            {  
                if (savedState != null)  
                {  
                    object[] state = (object[])savedState;  
                    base.LoadControlState(state[0]);  
                }  
            }  
     
            /// <summary>  
            /// Saves any server control state changes that have occurred since the time the page was posted back to the server.  
            /// </summary>  
            /// <returns>  
            /// Returns the server control's current state. If there is no state associated with the control, this method returns null.  
            /// </returns>  
            protected override object SaveControlState()  
            {  
                return new object[] {    
                    base.SaveControlState()   
                };  
            }  
     
            /// <summary>  
            /// Overrides AssembyInfo  
            /// </summary>  
            /// <param name="controlContainer">The AssemblyInfo</param>          
            public override Type AssemblyInfo  
            {  
                get 
                {  
                    return base.AssemblyInfo;  
                }  
                set 
                {  
                    base.AssemblyInfo = value;  
                }  
            }  
            /// <summary>  
            /// Overrides Localization  
            /// </summary>  
            /// <param name="controlContainer">Localization</param>          
              
            public override Type LocalizationAssemblyInfo  
            {  
                get 
                {  
                    return base.LocalizationAssemblyInfo;  
                }  
                set 
                {  
                    base.LocalizationAssemblyInfo = value;  
                }  
            }  
     
            public string GetLoadingPanelImageUrl(string name)  
            {  
                return RadAjaxLoadingPanel.GetWebResourceUrl(this.Page, name);  
            }
            #endregion  
     
            #region Private methods
            
            #endregion  
     
            #region Private Fields  
            private string defaultStatus = null;  
            private ReportManager manager;  
            private Guid pageId;  
            private string navigateUrl; 
            #endregion  
     
            #region Constants  
            protected const string SettingsIListTemplateName = "GambitCreations.Sitefinity.ReportModule.Resources.ControlTemplates.Public.ReportListing.ascx";  
            protected const string SettingsSingleTemplateName = "GambitCreations.Sitefinity.ReportModule.Resources.ControlTemplates.Public.ReportViewer.ascx";  
            protected const string SettingsLocalizationFile = "GambitCreations.Sitefinity.ReportModule.Resources.Messages.resx";
            #endregion  
        }  
    }  
     

    DownloadList Template
    <%@ Register Assembly="Telerik.Cms.Engine" Namespace="Telerik.Cms.Engine.WebControls" 
        TagPrefix="sfWeb" %> 
    <telerik:CssFileLink ID="CssFileLink1" FileName="" Media="screen" runat="server" 
        EmbeddedFileName="Telerik.Libraries.Resources.ControlTemplates.Frontend.librariesCommonLayout.css" /> 
    <asp:HyperLink ID="backLink" runat="server" Text="<%$Resources:Items_GoBack %>" /> 
    <asp:Repeater ID="repeater" runat="server">  
        <HeaderTemplate> 
            <ol class="sf_libraryList">  
        </HeaderTemplate> 
        <ItemTemplate> 
            <li> 
                <dl> 
                    <dt id="TitleWrap" runat="server">  
                        <asp:HyperLink ID="DownloadLink" runat="server">  
                            <asp:Literal ID="Title" runat="server"></asp:Literal> 
                        </asp:HyperLink> 
                    </dt> 
                    <dd> 
                        <asp:PlaceHolder ID="ExtWrap" runat="server"><strong class="sf_fileExtension">  
                            <asp:Literal ID="Extension" runat="server"></asp:Literal></strong>  
                            <asp:Literal ID="Literal3" runat="server" Text="<%$Resources:Items_File %>" /> 
                        </asp:PlaceHolder> 
                        <asp:PlaceHolder ID="SizeWrap" runat="server">(<asp:Literal ID="Size" runat="server"></asp:Literal>)  
                        </asp:PlaceHolder> 
                    </dd> 
                    <dd> 
                        <asp:Literal ID="Description" runat="server"></asp:Literal> 
                    </dd> 
                    <dd id="AuthorWrap" runat="server">  
                        <asp:Literal ID="Author" runat="server"></asp:Literal> 
                    </dd> 
                    <dd id="UploadDateWrap" runat="server">  
                        <asp:Literal ID="UploadDate" runat="server" /> 
                    </dd> 
                    <dd id="TagWrap" runat="server">  
                        <asp:Repeater ID="Tags" runat="server">  
                            <HeaderTemplate> 
                                <strong> 
                                    <asp:Literal ID="Literal2" runat="server" Text="<%$Resources:Items_Tags %>" /></strong>  
                            </HeaderTemplate> 
                            <ItemTemplate> 
                                <asp:HyperLink ID="tagLink" runat="server"></asp:HyperLink> 
                            </ItemTemplate> 
                        </asp:Repeater> 
                    </dd> 
                    <dd id="DownloadLinkWrap" runat="server">  
                        <asp:HyperLink ID="FileDownloadLink" runat="server" Text="<%$Resources:Items_Download %>" /> 
                    </dd> 
                </dl> 
            </li> 
        </ItemTemplate> 
        <FooterTemplate> 
            </ol> 
        </FooterTemplate> 
    </asp:Repeater> 
    <telerik:Pager ID="pager1" runat="server">  
        <LayoutTemplate> 
            <asp:Repeater ID="PageRepeaterLinkButton" runat="server">  
                <HeaderTemplate> 
                    <ol class="sf_pager">  
                        <li> 
                            <asp:LinkButton ID="PreviousPage" runat="server" Text="<%$Resources:Items_PreviousPage %>"></asp:LinkButton></li>  
                </HeaderTemplate> 
                <ItemTemplate> 
                    <li> 
                        <asp:LinkButton ID="SingleItem" runat="server" /> 
                    </li> 
                </ItemTemplate> 
                <FooterTemplate> 
                    <li> 
                        <asp:LinkButton ID="NextPage" runat="server" Text="<%$Resources:Items_NextPage %>"></asp:LinkButton></li>  
                    </ol> 
                </FooterTemplate> 
            </asp:Repeater> 
            <asp:Repeater ID="PageRepeaterHyperLink" runat="server">  
                <HeaderTemplate> 
                    <ol class="sf_pager">  
                        <li> 
                            <asp:HyperLink ID="PreviousPage" runat="server" Text="<%$Resources:Items_PreviousPage %>"></asp:HyperLink></li>  
                </HeaderTemplate> 
                <ItemTemplate> 
                    <li> 
                        <asp:HyperLink ID="SingleItem" runat="server" /> 
                    </li> 
                </ItemTemplate> 
                <FooterTemplate> 
                    <li> 
                        <asp:HyperLink ID="NextPage" runat="server" Text="<%$Resources:Items_NextPage %>"></asp:HyperLink></li>  
                    </ol> 
                </FooterTemplate> 
            </asp:Repeater> 
        </LayoutTemplate> 
    </telerik:Pager> 
     
  11. Georgi
    Georgi avatar
    3583 posts
    Registered:
    28 Oct 2016
    29 Jul 2009
    Link to this post
    Hi Garry Clark,

    I will show you an example of the a Custom DownloadList control. The base control is inheriting from ContentView as well. In my custom downloadlist control, I am chaning the DownloadLink:
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Web; 
    using Telerik.News.WebControls; 
    using Telerik.News; 
    using System.Collections; 
    using Telerik.Cms.Engine; 
    using Telerik.Libraries; 
    using System.Web.UI.WebControls; 
    using Telerik.Framework.Web.Design; 
    using System.Web.UI; 
    using System.ComponentModel; 
     
    /// <summary> 
    /// Summary description for CustomDownloadList 
    /// </summary> 
    namespace Telerik.Samples 
        [ToolboxItem(typeof(CustomDownloadList))] 
        public class CustomDownloadList : DownloadList 
        { 
            public CustomDownloadList() 
            { 
     
     
            } 
     
            protected override void SetListMetadata(System.Web.UI.Control itemContainer, IContent contentItem) 
            { 
                base.SetListMetadata(itemContainer, contentItem); 
                HyperLink downloadLink = itemContainer.FindControl("DownloadLink"as HyperLink; 
                string script = @"javascript: something............."
                downloadLink.Attributes.Add("onClick", script); 
     
            } 
            public override Type LocalizationAssemblyInfo 
            { 
                get 
                { 
                    return typeof(DownloadList); 
                } 
                set 
                { 
                    base.LocalizationAssemblyInfo = value; 
                } 
            } 
            public override System.Type AssemblyInfo 
            { 
                get 
                { 
                    return typeof(DownloadList); 
                } 
                set 
                { 
                    base.AssemblyInfo = value; 
                } 
            } 
     
        } 
     

    If you want your download link to navigate the browser to other page, change the href property.
    I hope the example will point you in the right direction.

    Best wishes,
    Georgi
    the Telerik team

    Instantly find answers to your questions on the newTelerik Support Portal.
    Check out the tipsfor optimizing your support resource searches.
  12. Garry Clark
    Garry Clark avatar
    26 posts
    Registered:
    27 Jan 2005
    29 Jul 2009
    Link to this post
    Georgi,
    That worked beautifully. However I was not successful in doing the following overrides for my embedded templates.
            /// <summary>  
            /// Gets or sets the path to a custom layout template for the control.  
            /// </summary>  
            [WebSysTemplate(ReportListing.SettingsTemplateName  
                , "ReportListingDescription""/Sitefinity/"false"2009-03-15")]  
            public override string ItemListTemplatePath  
            {  
                get 
                {  
                    return base.ItemListTemplatePath;  
                }  
                set 
                {  
                    base.ItemListTemplatePath = value;  
                }  
            }  
     
            /// <summary>  
            /// Gets the name of the embedded layout template.  
            /// </summary>  
            public override string ItemListTemplateName  
            {  
                get 
                {  
                    return ReportListing.SettingsTemplateName;  
                }  
            } 

    It kept throwing the following message. 
    Server Error in '/KCDC' Application.  
    --------------------------------------------------------------------------------  
     
    Invalid resource name (GambitCreations.Sitefinity.ReportModule.Resources.ControlTemplates.Public.ReportListing.ascx) for assembly (Telerik.Libraries, Version=3.6.1936.2, Culture=neutralPublicKeyToken=dfeaee0e3978ac79) or empty template.   
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.   
     
    Exception Details: System.ArgumentException: Invalid resource name (GambitCreations.Sitefinity.ReportModule.Resources.ControlTemplates.Public.ReportListing.ascx) for assembly (Telerik.Libraries, Version=3.6.1936.2, Culture=neutralPublicKeyToken=dfeaee0e3978ac79) or empty template.  
     
    Source Error:   
     
    An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.    
     
    Stack Trace:   
     
     
    [ArgumentException: Invalid resource name (GambitCreations.Sitefinity.ReportModule.Resources.ControlTemplates.Public.ReportListing.ascx) for assembly (Telerik.Libraries, Version=3.6.1936.2, Culture=neutralPublicKeyToken=dfeaee0e3978ac79) or empty template.]  
       Telerik.Framework.Web.ControlUtils.GetTemplate(String virtualPath, String resourceFileName, Type assemblyInfo, Type localizationAssemblyInfo) +852  
       Telerik.Framework.Web.ControlUtils.GetTemplate(String virtualPath, String resourceFileName, Type assemblyInfo, Type localizationAssemblyInfo, Type templateMapType, String additionalTemplateKey) +426  
       Telerik.Libraries.DownloadList.get_ItemListTemplate() +184  
       Telerik.Cms.Engine.WebControls.ContentView.get_ListContainer() +82  
       Telerik.Cms.Engine.WebControls.ContentView.CreateContentList() +69  
       Telerik.Cms.Engine.WebControls.ContentView.CreateChildControls() +5556  
       Telerik.Libraries.WebControls.LibraryViewBase.CreateChildControls() +29  
       Telerik.Libraries.DownloadList.CreateChildControls() +53  
       System.Web.UI.Control.EnsureChildControls() +87  
       System.Web.UI.Control.PreRenderRecursiveInternal() +44  
       System.Web.UI.Control.PreRenderRecursiveInternal() +171  
       System.Web.UI.Control.PreRenderRecursiveInternal() +171  
       System.Web.UI.Control.PreRenderRecursiveInternal() +171  
       System.Web.UI.Control.PreRenderRecursiveInternal() +171  
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +842  
     
       
     
     
    --------------------------------------------------------------------------------  
    Version Information: Microsoft .NET Framework Version:2.0.50727.3074; ASP.NET Version:2.0.50727.3074  

    However that is not that big of an issue. If you know off the top of your head why that does not work in a ContentView then great if not no worries. I did verify that resource does exist at that path. The other Reportviewer control which inherits from SimpleControl works just fine with that same path except ReportViewer.ascx as the template.

    Thank you as always Georgi and Ivan!
  13. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    16 Jun 2017
    29 Jul 2009
    Link to this post
    Hi Garry Clark,

    You can check whether you have overridden AssemblyInfo and LocalizationAssemblyInfo. Try using return this.GetType();

    public override Type LocalizationAssemblyInfo 
            { 
                get 
                { 
                    return this.GetType(); 
                } 
                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 this.GetType(); 
                } 
                set 
                { 
                    base.AssemblyInfo = value; 
                } 
            } 

    If the problem persists you can post the code of your PublicView for review.

    Regards,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
Register for webinar
13 posts, 0 answered