8

背景:我想避免为我的主页创建备用布局,我想保持“主题机器”区域和布局保持不变,实际上“主题”大部分使用纯 CSS。所以我需要有选择地将 CSS 定位到特定的“页面”,包括,最重要的是,主页。最简单的方法是向包装整个布局的布局包装器“div”添加一个类。我可以通过覆盖 Document.cshtml 文件向“body”元素添加一个类,但我真的认为只在 Layout.chstml 文件中工作并利用 Model.Classes 将所需的 CSS 类添加到“打开”标签。

我目前正在做这样的事情:

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

我知道Area不会剪切,因为主页和其他页面都在同一个区域中,而Model.DesignatedAreaField实际上为主页或其他页面返回了一个空字符串。因此,最后,上面的代码将始终生成以下标记(我在主页上显示了 3 个三元组):

<div class="home tripel-123" id="layout-wrapper">

我希望能够仅在显示主页时添加“主页”CSS 类。一些伪代码如下:

string wrapperCss = IsHomepage ? 'home' : Model.GetUrlPathOrSomethingUniqueForThePath();
Model.Classes.Add(wrapperCss);

例如,这将允许我使主要内容缩小并向右浮动,并将三元组放在左侧(主页设计应该是这样的,但我不想编写完全不同的布局如果我可以用简单的、有针对性的 CSS 做同样的事情,那么对于家庭来说)。

更新:连接伯特兰的答案

Bertrand 的回答允许我根据 URL 向包装 DIV 添加一个类。他没有提到它(因为 Orchard 是他的第二天性 :-) 但您必须在 Layout.cshtml 文件中添加一个包含并相应地更改“我的”代码:

@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);

它导致以下类被添加到封闭的 div 中:

1)当主页显示时:

<div class="url-orchard-local- tripel-123" id="layout-wrapper">

2) 当显示名为 Products 的页面时:

<div class="url-orchard-local-products" id="layout-wrapper">

我的 URL 在我的开发机器上是这样的,在 Visual Studio 的网络服务器中运行:

http://localhost:30320/OrchardLocal/ or 
http://localhost:30320/OrchardLocal/Products 

我不赌我的生命,但我坚信一旦“OrchardLocal”部分发布到 Azure 服务器,它就会在生产中发生变化……所以我先发制人地将代码更改为:

string area = WorkContext.HttpContext.Request.Path.HtmlClassify();
if (area.LastOrDefault() == '-') {
    area = "home";
}
Model.Classes.Add("url-" + area);

当显示“主页”时,这会导致此类:

<div class="url-home tripel-123" id="layout-wrapper">

(实际上,我已经在单行代码之上编写了一些三元与 lambda 运算符混合的代码 :-)

我推断 HtmlClassify 将返回一个以“-”结尾的“类”的唯一时间是它是主页......或者网站的“根”......我很可能是错的!:-)

(无论如何,我对 Orchard 的喜爱超过了我在过去几年中使用的除 nHibernate 之外的任何东西,但是,嘿,Orchard 也使用它!完美!)

4

2 回答 2

7

这样的事情应该可以解决问题:

Model.Classes.Add("url-" + WorkContext.HttpContext.Request.Path.HtmlClassify())
于 2012-09-11T00:06:11.830 回答
0

这是使用扩展方法执行此操作的一种方法:

public static string GetPageCssClass(this WorkContext workContext)
{
    string pageUrl = workContext.HttpContext.Request.Url.ToString();
    string baseUrl = workContext.CurrentSite.BaseUrl; //use BaseUrl to later get app relative page path

    string pageClass = workContext.IsHomePage()
        ? "home"
        : pageUrl.Substring(baseUrl.Length).HtmlClassify();

    return string.Format("{0}-page", pageClass);
}

public static bool IsHomePage(this WorkContext workContext)
{
    string pageUrl = workContext.HttpContext.Request.Url.ToString().TrimEnd('/');
    string baseUrl = workContext.CurrentSite.BaseUrl.TrimEnd('/');

    return pageUrl == baseUrl;
}

请注意,这基于与您在站点设置中设置的 BaseUrl 相关的类名称,因此如果您的 BaseUrl 是为您当前的环境设置的,则应该在本地或生产中工作。

然后,您只需要为扩展方法类的命名空间添加一个 using 语句到您的视图中,然后:

Model.Classes.Add(WorkContext.GetPageCssClass());

此处的另一个选项是为当前处于活动状态的每个图层添加一个 css 类,以下扩展方法将向您的页面添加 {xxx}-layer css 类的列表。这是另一个相关问题:Orchard CMS: Conditional CSS Class based on Layer

于 2014-08-05T02:00:40.870 回答