I encountered a problem while creating a theme for the upcoming asp.net mvc version of nopCommerce and wanted to discuss it. I noticed that the custom view engine allows to "override" views such that views with the same name will be found first in the current theme's folder. However, to use that feature with a master page, one must specify the name of the master page in a controller action's return statement (since hardcoding the path to the master view on the Layout attribute of the view does not process through the view engine).
However, I think this method doesn't work with nested layouts (for instance, I can specify
return View("Index", "_ColumnsThree");
in the HomeController to have the Index view load my custom _ColumnsThree master page. But _ColumnsThree will still load the default _Root view, unless I change the path in my custom _ColumnsThree to be relative to load my custom _Root. This would work until I just want to override _Root. Since _Root is never used as a direct master, I can't go and change the code in the controllers (as shown above).
One solution I came up with to make sure the themed version of a view is always used is to force the layout to go through the view engine to locate a view:
Layout = (ViewEngines.Engines.FindView(this.ViewContext.Controller.ControllerContext, "_ColumnsThree", "").View as RazorView).ViewPath;
This is the code I use in Index.cshtml. This code should be abstracted away in a helper and used on all Layout statements instead of hardcoding the paths to the master views. This way, someone can create a theme, override any view and be sure that it will be used.
Please let me know if it can be useful or if I overlooked something.
Thanks!