Using Alternatives for Document.cshtml in Orchard

2019-02-19 02:25发布

问题:

I am currently working on a website that requires the ability to overwrite the document.cshtml file so that I can apply a specific CSS-class based on the user's current location.

I have attempted to use URL alternatives such as:

  • Document.cshtml
  • Document-url-AreaA.cshtml
  • Document-url-AreaB.cshtml
  • Document.url-AreaC.cshtml

however it appears that all of them use the Document.cshtml as opposed to using one based on the URL. I could easily understand that this is the intended purpose, however I was wondering if it would be possible to implement the functionality above.


Update

I believe that I may have made some progress in this area, as opposed to using URL alternatives, and simply adding a field on the Model (for the document) to simply pull the current "Area" of the site and apply that class to the body.

(Within document.cshtml)

@using Orchard.Mvc.Html;
@using Orchard.UI.Resources;
@{
    RegisterLink(new LinkEntry {Type = "image/x-icon", ...});

    string title = Convert.ToString(Model.Title);
    string siteName = Convert.ToString(WorkContext.CurrentSite.SiteName);

     //Pull the Area here
    string area = Model.DesignatedAreaField;
}
<!DOCTYPE html> 
<html lang="en" class="static @Html.ClassForPage()"> 
<head> 
    <meta charset="utf-8" />
    <title>@Html.Title(title, siteName)</title> 
    @Display(Model.Head)
</head> 
<body class='@area'>
//Body goes here
@Display(Model.Body)
@Display(Model.Tail)
</body>
</html>

I believe that this may be an easier solution than the one previously suggested. However, I am wondering what the easiest method of actually placing a field that I could access from the Model of the Document, would be.

回答1:

Document.cshtml is a wrapper for the Layout shape. Wrappers don't support alternates. The only way to replace the document.cshtml template selectively is to remove the existing wrapper from the wrappers collection on the metadata of the layout shape and add your own.

But wait... I can't think of any good reason why you'd want to do that. What's in document.cshtml is boilerplate HTML that should be the same across the site. The solution described in your update is the way to go.



回答2:

You could also move the <body> tag into Layout.cshtml, and then use URL alternates of Layout.cshtml to set the <body>'s class attribute.



回答3:

You might want to take a look at this post: http://weblogs.asp.net/bleroy/archive/2010/12/14/switching-the-layout-in-orchard-cms.aspx. It shows how you can dynamically add your own alternates, but the same approach could work to add properties to the model or layout based on geolocation.

I think you can define some code within OnResultExecuting() to dynamically add a property to the Model class. Since it's of type dynamic you should just be able to set it, nothing special needed.