Custom Control with Custom Template / Resources (if availabl

Posted by Community Admin on 03-Aug-2018 12:30

Custom Control with Custom Template / Resources (if available)

All Replies

Posted by Community Admin on 20-Oct-2010 00:00

Greetings,


I have my own Custom Controls each with their own embedded Templates and Resource files (.ascx, .css). What I need to do is that if there's a Custom Template available inside the ControlTemplates folder of the current Template in use by the page that hosts the Custom Control then have the control use that one instead of the embedded one. Also trying to achieve this for CSS files as well.

For example, using a Custom Control named Test, I would override the LayoutTemplatePath of the Control and check if the file 'App_Data/Sitefinity/WebsiteTemplates/<Current Template>/ControlTemplates/Teste.ascx' existed and if so, return it, otherwise return null, making the control use the LayoutTemplate instead of the LayoutTemplatePath which would cause him to use the embedded .ascx template file.

Is there a way on code-behind to get the current Page Template directory?

I would also need a way to include an external CSS file, if available, otherwise use the embedded one. 

For example, on the InitializeControls method I could verify if the file 'App_Data/Sitefinity/WebsiteTemplates/<Current Template>/App_Themes/<Current Theme>/Styles/Test.css' and if so, then include it on the ResourceLinks present on the Custom Control, otherwise include the embedded one.

Is there a way on code-behind to obtain the current Page Theme directory?

Also, is this the correct procedure of achieving this (load external resources, css, ascx, images, if they are available, otherwise load the embedded ones) or is there a more convenient way that I'm missing?

Thanks in advance,
Daniel

Posted by Community Admin on 26-Oct-2010 00:00

Hi Daniel,

Thank you for using our services.

Unfortunately such functionality does not come out of the box with Sitefinity and your idea of implementing this seems like the most convenient. The problem however is that you would have to override each control you want to achieve this for. For example you would need to override the news view control and get the current page. From the current page you can extract its template path and theme name:

protected override void CreateChildControls()
    SiteMapNode currentNode = SiteMapBase.GetCurrentProvider().CurrentNode;
    PageSiteNode node = (PageSiteNode)currentNode;
    PageNode page;
    if (node != null)
    
        page = App.WorkWith().Pages().Where(p => p.UrlName == node.UrlName).Get().First();
        string masterPage = page.Page.Template.MasterPage;
        string theme = page.Page.Template.Theme;
        PageManager manager = PageManager.GetManager();
    
    this.MasterViewDefinition.TemplatePath = "~/App_Data/Sitefinity/WebsiteTemplates/DefaultTemplate/ControlTemplates/News/ListView.ascx";
    base.CreateChildControls();


Regards,
Radoslav Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 26-Oct-2010 00:00

Greetings,


I've sorted this out using the following solution:

First I still keep an embedded .ascx for each of my custom controls with the required controls on it but without styling.

Secondly I create an external .ascx for them with a ResourceFile pointing to the external .css file, this works since then the resourcemanager will make use of the current theme directory to locate that file. It's basically a fallback system, the external .ascx with the required .css and images should actually be theme-dependent and as such only the external ones should be styled. At least this is how I consider it working good for me. If an external view ain't found then it uses an internal one which still provides functionality without any styling (although you could also include embedded styling if you wanted).

Then I also created a CustomSimpleView class which extends the SimpleView since I wanted to hide most of the properties from the Advanced Designer. On this class I overrided the LayoutTemplatePath to the following:

[Browsable(false)]
        public override string LayoutTemplatePath
        
            get
            
                 if (Page.Master == null)
                
                     return null;
                

                 var customTemplateFile = String.Format("0ControlTemplates/1.ascx", Page.Master.AppRelativeVirtualPath.Substring(0, Page.Master.AppRelativeVirtualPath.IndexOf("App_Master")), ResourcesAssemblyInfo.Name);

 
                return File.Exists(HttpContext.Current.Server.MapPath(customTemplateFile)) ? customTemplateFile : null;
            
        

All my Custom Controls implement this CustomSimpleView and as such if a Template named 'ControlClassName.ascx' is found it uses it, otherwise the LayoutTemplatePath returns null making the control use the LayoutTemplateName instead which points to the embedded .ascx file. There's a few Custom Controls where I use several views in which the active one will vary depending on a configured designer property. In this case I just override this LayoutTemplatePath property in the control itself and provide a custom  location method.

This thread is closed