Themes with the View Engine

The ASP.NET Web Forms already supports themes so this section applies only if you are using the Razor view engine.

Theme Visuals

Let's say you want your website to support 4 themes: Default, Green, Purple and Red as follows:
  • The Default theme uses the standard Layout fo the original MVC template project, in other words a content that spans the whole width of the content area.
  • The Green theme is a variation of the default that has a sidebar to the left of the content section
  • The Purple theme is a variation of the default that has a sidebar to the right of the content section.
  • The Red theme is another variation of the default that has two sidebars, one to the left and the other to the right of the content section.

So as you can see all four themes have a different color palette, namely light blue, green, purple and red. Additionally the green, purple and red themes also define their own layout variation.

Creating Themes

If the theme has no layout variation then don't define a Layout.cshtml inside its theme folder. If it does then create a Layout.cshtml in the theme's folder and adjust the layout to your liking. If the theme does not redefine layout it uses the global layout in /Views/Shared/Layout.cshtml. For that reason you see that Green has a layout in /Views/Shared/Themes/Green/Layout.cshtml as does Red and Purple.

So:
  • Create the /Views/Shared/Themes folder and underneath create one folder for each theme that you will define. This will take care of the layouts regardless of whether the theme redefines is or not.
  • In the /Content/Themes folder create one subfolder for each theme. Therein place a CSS file named either Site.css or ThemeName.css.
  • In the global /Content/Site.css only define layout classes but specify no colors, colors belong to the theme. In the ThemeName.css file redefine global CSS classes if you need to add color information. Remember CSS is cascading so it inherits from previous definitions.

The CSS inheritance chain defined in the layout is:
  1. Include global stylesheet /Content/Site.css
  2. Override global with theme stylesheet /Content/Themes/ThemeName/ThemeName.css

Localization with View Engine

As mentioned none of the original sources supported localization in a transparent manner. This derivative work does and has been already used in a live site.

Fitting your View Engine

For it to work, in other words, locate your localized (partial)views you also have to register the Localizable Theme Engine in your Global.asax file:

public static void RegisterViewEngine(ViewEngineCollection viewEngines)
{
// We do not need the default view engine
viewEngines.Clear();

var themeableRazorViewEngine = new ThemeableRazorViewEngine
{
DefaultLanguageCode = "en",
CurrentTheme = httpContext => httpContext.Session["theme"] as string ?? string.Empty
};

viewEngines.Add(themeableRazorViewEngine);
}

And in your Application_Start method of Global.asax add the following line:

RegisterViewEngine(ViewEngines.Engines);

Do notice the new setting (v1.3) where you tell the view engine the language used in your default views. So if your Index.cshtml for example is in English you use that property to tell the view engine that if the visitor requests an English language content, that it should use the default views unless a specific locale is found.

Creating Resources

Create them just as you did in the ASP.NET Web Forms web applications. So for each resource file in the default language do the following:
  • Create a /Resources folder at the root of your web application project
  • For each localized resource create the default language file, the demo project already contains Themes.resx.
  • For each resource file make sure that its Access Modifier is set to Public, the default is Internal which will not work.
  • Create a localized resource, for example Themes.es.resx, Themes.de.resx and also make sure their access modifier is Public.

Remember that these resources have the root namespace of your web application. So if your web application root namespace is "EuropeanHolidays.Mvc" and your resource file is named "Themes.resx" and therein there is a resource named "SelectThemeLabel" you would access the resource as "EuropeanHolidays.Mvc.Resources.Themes.SelectThemeLabel"

Localizing a View

Now let's assume you want to localize the Index and About pages of the default Home Controller created by the default MVC Visual Studio template. They are located in the /Views/Home folder. We will localize them to Spanish.
  • Add the view /Views/Home/Index.es.cshtml
  • Add the view /Views/Home/About.es.cshtml
  • Translate the views with text
  • If necessary also access the localized resources using the Razor syntax

Localizing a Partial View

By default the partial views in the standard template are located in the /Views/Shared/ folder. Localize the partial views just as you would with a normal view.

The demo project contains both a /Views/Shared/LogOnPartial.cshtml and a /Views/Shared/LogOnPartial.es.cshtml.

Last edited Dec 3, 2015 at 8:20 PM by lordofscripts, version 3

Comments

akrogers Sep 23, 2013 at 6:11 PM 
This worked great for me using the Theme Switcher. What if I want to switch the theme based on the URL (either a sub-domain, or parameter passed in the url)? Thanks for your great code!