Change Theme at Runtime in 4.1

Posted by Community Admin on 03-Aug-2018 14:05

Change Theme at Runtime in 4.1

All Replies

Posted by Community Admin on 08-Jun-2011 00:00
Hello!  I wanted to change a page's theme at runtime but was having some trouble with the article in documentation located here : 
www.sitefinity.com/.../how-to-how-to-set-the-theme-of-a-page-at-runtime.html

From what I can tell PageRouteHandler no longer has a method called set page directives.  I was able to determine that the call could be something like this :

public class ThemeManagerRouteHandler : PageRouteHandler
    protected override void SetPageDirectives(Page handler, IPageData pageData)
    
        ((StaticPageData)pageData).SetPageDirectives(handler);
        //base.SetPageDirectives(handler, pageData);
 
        var themeName = "MyNew.Cool.Theme";
        ThemeController.SetPageTheme(themeName, handler);
    
    public static void RegisterType()
    
        ObjectFactory.Container.RegisterType<PageRouteHandler, ThemeManagerRouteHandler>();
    

Unfortunately I am at a loss as to what should have a function override since SetPageDirectives doesn't exist anymore, any chance we could get an updated working example?
Posted by Community Admin on 08-Jun-2011 00:00
Hello James,

There is an easy way to do this - through the query string. If there is the following query string in the url

theme="themename"

the theme you set will be loaded

Kind regards,
Ivan Dimitrov
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested 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 08-Jun-2011 00:00
That's extremely helpful for testing new themes, thank you!

We have need of changing the theme in code behind based on certain pieces of logic, is there no longer an event / handler capable of being overridden? 

What about the "asp.net" way of doing it in page_preinit?  Could someone put a user control of 'MyThemeManager' on a master page and just throw logic into the page_preinit function?
Posted by Community Admin on 08-Jun-2011 00:00
Hi James,

You can check, get/set the query string in the code behind. Passing the query string is the best way in this case, since you don't have to work with any objects form the Cms and  make database transactions. We have our own implementation for the way that the themes are set in a class ThemeController, so the way with Pre_Init, probably will not work.

Greetings,
Ivan Dimitrov
the Telerik team
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested 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 08-Jun-2011 00:00
I remembered after my initial questions that the preinit event does not exist for a masterpage or user control, so that approach wouldn't work.  Also the query string is read only so we wouldn't have much luck there.

I was able to look at the methods the PageRouteHandler class currently has and through some adjustments manually set the theme.  This assumes you are using an ASP.NET theme in the ~/App_Themes folder.

For example the following path :
Sitefinity/App_Themes/MyNew.Cool.Theme
contains the following sub folders :
Global
Images
Styles
per the theme design guidelines in Telerik documentation.  The following code would force any page to have that 'cool' theme.

If you have an embedded theme in an assembly this code might require adjustment.  We combine / minify all our images and CSS via build steps and don't include them in a separate resources assembly.

Hope this helps!

Code Snippet :

using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web;
using System.Web.Routing;
 
using Telerik.Sitefinity.Pages.Model;
using Telerik.Sitefinity.Web.UI;
using Telerik.Sitefinity.Abstractions;
using Telerik.Sitefinity.Web;
using Telerik.Sitefinity.Modules.Pages;
using Telerik.Sitefinity.Utilities;
using Telerik.Microsoft.Practices.Unity;
 
namespace ProjectName.Web.Util
    public class ThemeManagerRouteHandler : Telerik.Sitefinity.Web.PageRouteHandler
    
        public override IHttpHandler GetHttpHandler(RequestContext requestContext)
        
            var handler = (Page)base.GetHttpHandler(requestContext);
            handler.Theme = "MyNew.Cool.Theme";
            return handler;
        
 
        public static void RegisterType()
        
            ObjectFactory.Container.RegisterType<Telerik.Sitefinity.Web.PageRouteHandler, ThemeManagerRouteHandler>();
        
    

Posted by Community Admin on 14-Jul-2011 00:00
If you're talking about a URL like www.mysite.com/home then that doesn't work?

Actually it does, just couldn't find a way to delete my post.
Posted by Community Admin on 15-Jul-2011 00:00
Hi Ivan,

You mention "You can check, get/set the query string in the code behind.".

Which code behind?

Regards,
Jacques
Posted by Community Admin on 15-Jul-2011 00:00
Just checked this and you can't do as Ivan is suggesting: "You can check, get/set the query string in the code behind." because the QueryString object is read-only.

Ivan, how did you intend for James to be able to manipulate the query string value?

Regards,
Jacques
Posted by Community Admin on 15-Jul-2011 00:00
@J.Hoventer
As you pointed out, you cannot modify the querystring via code behind.  If you intercept it early enough you COULD do some serious tinkering around to make the querystring writable (google search for it) but it seems like a very big nasty hack.

We went with overloading the event that sets the page theme as seen in the code snippet I pasted above.  We haven't upgraded to 4.1 SP2 yet -- but during a test upgrade process the function :
public override IHttpHandler GetHttpHandler

can no longer be overridden.  My initial thought is to just replace the function completely -- while still calling the base implementation before we replace the theme with custom logic.

I remember reading somewhere that the "Page" class is now exposed via API -- but I haven't investigated if that makes this process any simpler.

Let me know if you have tried this in 4.1SP2 or if you have any further questions.

Best Regards,

James
This thread is closed