This project is read-only.

Change theme in Controller Action?

Topics: Writing themes
Apr 24, 2013 at 8:02 PM
I'm looking at the code for Vandelay Theme Picker and also Bertrand's blog post. I'd like to use a different theme for certain Controller Actions within my module or possibly use a different theme when the URL starts with* (since my Route file will determine the Controller/Action)

Which would you recommend as the better option?

If it's via Controller Action, how would that be implemented?

If it's via URL, can I drop a file similar to the one in Bertrand's blog post into the root folder of my module instead of the Theme?

Thanks for the assistance.
Apr 24, 2013 at 8:06 PM
Use an ActionFilter. You could then place a corresponding attribute on these actions, or have other rules in the filter.
Apr 24, 2013 at 8:10 PM
Never thought of that...great idea. Thanks. I haven't had to write an ActionFilter before...time to learn something new.
Apr 24, 2013 at 9:13 PM
Just about there...small question regarding how to actually change the theme.

The code examples I'm looking at in Framework and Betrand's blog return a ThemeSelectorResult, but the OnActionExecuting method for an ActionFilter is a void and doesn't return anything. So I can't use
return new ThemeSelectorResult { Priority = 100, ThemeName = "MyTheme" };
How would I actually apply the theme in the ActionFilter instead of returning something?

Thanks again for the pointers
Apr 24, 2013 at 9:50 PM
Edited Apr 24, 2013 at 10:16 PM
I created a MyThemeSelector class that returns a ThemeSelectorResult specifying my theme.

Am I able to call that in my ActionFilter by doing the following?
var result = _mythemeSelector.GetTheme(filterContext.RequestContext);


Doing that changes the theme for all I can't drop MyThemeSelector in the root folder of my module otherwise it gets picked up on every page and overrides the theme.
Apr 25, 2013 at 12:42 AM
The trick is to do the same thing the AdminThemeFilter is doing. In your selector you define a static accessor which will set a HttpContext flag to true, called by the action. In the selector itself you check for the flag.
Apr 25, 2013 at 5:47 AM
Edited Apr 25, 2013 at 5:49 AM
I was heading down that path, but was having a difficult time figuring out how to define and retrieve the static accessor you're speaking about. This is what I came up with and it works. If you see any issues with it, can you let me know? Thanks

using System.Web.Mvc;

namespace Raptor.SpatifyMe {
    public class ProThemeAttribute : ActionFilterAttribute, IActionFilter {
        public override void OnActionExecuting(ActionExecutingContext filterContext) {
            filterContext.RequestContext.HttpContext.Items.Add("ProTheme", true);
using System.Web.Routing;
using Orchard.Themes;

namespace Raptor.SpatifyMe {
    public class ProThemeSelector : IThemeSelector {
        public ThemeSelectorResult GetTheme(RequestContext context) {
            if (context.HttpContext.Items["ProTheme"] != null && (bool)context.HttpContext.Items["ProTheme"]) {
                return new ThemeSelectorResult { Priority = 1, ThemeName = "Raptor.DetailAdmin" };

            return null;