Dynamically Changing Themes

Topics: Administration, General, Writing themes
Jun 10, 2012 at 11:05 PM

Hi,

I'm fairly new to Orchard although have experience of other CMS systems (DotNetNuke, N2, etc.). I am currently working on a small site and need to dynamically change the theme depending upon what page they are on.

Can someone explain how this is achieved? I'm a little confused about the relationship between Layers, Themes & Zones.

Thanks!

Coordinator
Jun 11, 2012 at 1:01 AM

Implement IThemeSelector

Jun 11, 2012 at 11:12 PM

Thanks! Could you give me a couple more pointers on this please?

I'm aware that I can create a new class that implements ithemeselector which has rules to change the theme. I'm just not sure where it should live in the orchard pipeline.

 

Thanks

Jun 12, 2012 at 1:50 AM

I always recommend putting your custom code in a module. Technically you can put custom code in a theme (or theme override) but it is hard to keep organized that way. You can use the following link to have Orchard create an empty module:

http://docs.orchardproject.net/Documentation/Command-line-scaffolding

Once you have your empty module, I would create a Services folder and implement IThemeSelector.  If you want an example (or maybe it will work for you as is but I don't think so) there is a module called Vandelay Industries (Bertrand built it - thanks Bertrand) here:

http://gallery.orchardproject.net/List/Modules/Orchard.Module.Vandelay.Industries

Once you have it downloaded, look in Vandelay.Industries.Services.ThemePickerThemeSelector and you will see an implementation of IThemeSelector.

Hope this gets you off and running, if you make the module controllale through the UI upload it on the gallery so everyone can utilize it.

Jun 12, 2012 at 10:35 PM

Thanks jao28! That really helped... I've created a new module and added a class that implements IThemeSelector as you suggested. This class simply forces the theme to be one called "blue". As follows....

using System.Web.Routing;
using Orchard.Themes;
 
namespace TestWidget.Drivers
{
    public class ThemeSelector : IThemeSelector
    {
        public ThemeSelectorResult GetTheme(RequestContext context)
        {
            return new ThemeSelectorResult { Priority = 1, ThemeName = "Blue" };
        }
 
    }
}
 
This module has a very simple migrations class which just makes the module attachable, as follows:-
        public int Create()
        {
            ContentDefinitionManager.AlterPartDefinition(typeof(ThemeSelector).Name,
             builder => builder.Attachable());
 
            return 1;
        }

But what is really odd is that my theme is getting forced to Blue even though I've not actually added the module to any Part. I've simply enabled it, that's all?
Any thoughts?? 
Thanks!
Coordinator
Jun 13, 2012 at 5:37 AM
Edited Jun 13, 2012 at 5:37 AM

Ah, it seems like you're confused about what a part and a theme selector are. A theme selector is not a content part, and you shouldn't add it to a content type. The theme selector will get executed just by virtue of the feature it's part of being enabled, and the fact that it implements the interface. Nothing more needs to be done for the system to pick it up, and you don't need to worry about where it will get executed in the lifecycle.

For a theme selector to make sense, it needs to only act on a certain condition. Otherwise, it's always going to be active and if its priority is high it will trump everything else. Again, Vandelay's theme selector is a good piece of code to look at to understand this.

Jun 13, 2012 at 11:54 AM

Thanks! Just out of interest (and to get more of a handle how this works...) what would happen if the Vandeley theme selector is enabled and running and I've also implemented my own iThemeSelector. Do they both get executed in a particular order?

I'm rapidly getting up to speed on Orchard and hope to participate much more on this forumn as I develop my Orchard applications.

Cheers!

Jun 14, 2012 at 2:54 AM
wadey wrote:

Thanks! Just out of interest (and to get more of a handle how this works...) what would happen if the Vandeley theme selector is enabled and running and I've also implemented my own iThemeSelector. Do they both get executed in a particular order?

I'm rapidly getting up to speed on Orchard and hope to participate much more on this forumn as I develop my Orchard applications.

Cheers!

see a blog from bertrandleroy

Coordinator
Jun 14, 2012 at 6:51 AM

They will both get executed, you can't know in what order, but the one that returns the highest priority will win.

Jun 28, 2012 at 2:07 PM

Thanks! I'm looking into the Vandelay Theme Selector and playing around with how it works. I'm trying to modify it so that I can select a theme based on what 'page' is selected. With this in mind I was thinking of showing a dropdown of all Content Types with a type of 'Page' and allowing the administrator to select a theme per chosen page. This is because I intend to have a site where lots of companies will have thier own page and I want to Theme/Brand it accordingly.

How do I create/attach a field in the custom module (View) that is populated with all 'pages'?

Many Thanks!

Feb 5, 2013 at 2:41 AM
Hi wadley,

I am looking to do the same thing, I am creating a 'demo' site where I want to set different themes for different pages. Were you able to get this implemented?

Thanks!