Background: I want to avoid creating an Alternate Layout for my home-page and I'd like to keep the "The Theme Machine" zones and layout next to intact, and actually "theme" most of everything using pure CSS. So I need to selectively target CSS to specific "pages", including, and most importantly, the homepage. The simplest way to do that would be to add a class to the layout-wrapper "div" that wraps the entire layout. I could add a class to the "body" element by overriding the Document.cshtml file, but I really think it is cleaner to just work inside the Layout.chstml file and capitalize on the Model.Classes to add the needed CSS classes to the "opening" tag.
I' currently doing something like this:
string area = Model.DesignatedAreaField;
Model.Classes.Add(string.IsNullOrWhiteSpace(area) ? "home" : area);
Model.Id = "layout-wrapper";
var tag = Tag(Model, "div"); // using Tag so the layout div gets the classes, id and other attributes added to the Model
I know that the Area will not cut, because the homepage, and other pages are all in the same area, and Model.DesignatedAreaField actually returns an empty string for either the homepage or other pages. So, in the end, the code above will ALWAYS generate the following markup (I'm showing the 3 tripels on the homepage):
<div class="home tripel-123" id="layout-wrapper">
I would like to be able to add the "home" CSS class only when the homepage is being displayed. Some pseudo-code would be as follow:
string wrapperCss = IsHomepage ? 'home' : Model.GetUrlPathOrSomethingUniqueForThePath();
Model.Classes.Add(wrapperCss);
This will allow me to, for example, make the main content shrink and float to the right, and put the tripels on its left (that's how the home page design should look like, but I don't want to write an entire different layout for the home if I could do the same with simple, targeted CSS).
UPDATE: Wiring up Bertrand's answer
Bertrand's answer allowed me to add a class to the wrapping DIV depending on the URL. He didn't mention it (since Orchard is second nature to him :-) but you'll have to add an include into the Layout.cshtml file and change "my" code accordingly:
@using Orchard.Utility.Extensions;
{
/* omitted for brevity, everything in between is the same as in the Theme's Machine layout file */
string area = WorkContext.HttpContext.Request.Path.HtmlClassify();
area = string.IsNullOrWhiteSpace(area) ? "home" : area;
Model.Classes.Add("url-" + area);
It results in the following class being added to the enclosing div:
1) When the homepage gets shown:
<div class="url-orchard-local- tripel-123" id="layout-wrapper">
2) When a page named Products get shown:
<div class="url-orchard-local-products" id="layout-wrapper">
My URL reads like this on my dev machine, running inside Visual Studio's webserver:
http://localhost:30320/OrchardLocal/ or
http://localhost:30320/OrchardLocal/Products
I'm not betting my life, but I strongly believe that the "OrchardLocal" part will change in production once it is published, let me say, to Azure servers... So I've preemptivelly change the code to this:
string area = WorkContext.HttpContext.Request.Path.HtmlClassify();
if (area.LastOrDefault() == '-') {
area = "home";
}
Model.Classes.Add("url-" + area);
Which results in this class when the "homepage" gets shown:
<div class="url-home tripel-123" id="layout-wrapper">
(Actually I've made the code above a one-liner abusing some ternary mixed with lambda operators :-)
I'm inferring that the only time the HtmlClassify will return a "class" ending with '-' is when it is the homepage... Or the "root" for the site... I may well be wrong! :-)
(Anyway I'm loving Orchard more than anything I've used in the past couple of years other than nHibernate, but, hey, Orchard uses it too! Perfect!)
Something like this should do the trick:
Model.Classes.Add("url-" + WorkContext.HttpContext.Request.Path.HtmlClassify())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With