6

Basically, I'd like to define a MVC layout in Sitecore, and have that layout be linked to both a controller and a razor file. Currently there are only options to set the Razor file, not the controller.

Goal: have the controller on the layout, set the properties that define the header and footer links. The properties are passed through to the header/footer renderings Sitecore render or MVC partial. The goal is to only call the controller once to pull the necessary data for the header and footer links, instead of twice, once in the header and footer controllers.

Example:

  • HomeController.LayoutActionResult
    • Create instance of View Model
    • Set ViewModel.Header.Info
    • Set ViewModel.Footer.Info
    • Return View(/layout/MainLayout, ViewModel)
  • Views//ayout/MainLayout.cshtml
    • stuff html
    • @Html()...(/static/path/to/header, Model.Header)
    • more html
    • @Html()...(/static/path/to/footer, Model.Footer)
    • more html
4
  • 1
    Why not just separate out the logic to generate the Header and Footer properties of the model, and statically bind to a controller rendering + cache them?'
    – jammykam
    Oct 24, 2017 at 16:05
  • Are you just looking to call a controller and get a view in return, from inside of a razor file?
    – Chris Auer
    Oct 24, 2017 at 16:13
  • A lot of the data that's needed on the header and footer is on a single "root" item. So it would be great to call that logic once, to pull the list of say links that are on the root, but displayed on the header and footer sections, just a little different CSS. @jammykam, define "them" in cache them
    – Nona Drake
    Oct 24, 2017 at 16:16
  • "them" being the renderings, in HTML cache. Items will be cached by Sitecore anyway.
    – jammykam
    Oct 24, 2017 at 16:21

3 Answers 3

2

Unfortunately, this is not currently possible OOTB with Sitecore's MVC engine. Because, as you point out, for a Layout Sitecore only allows for a Razor file. And it uses that files extension to determine that it is a razor view and then uses the MVC engine.

Here is an older question asking basically the same thing (although not as elegantly worded) on regular stackoverflow: https://stackoverflow.com/questions/27006580/how-to-use-mvc-controllers-for-layours-in-sitecore

That said, as with practically anything else in Sitecore, you could probably create a new Layout template - Controller Layout, that has a Controller and Action field, like a Controller rendering. Then, using Sitecore's pipeline architecture, patch into the appropriate pipeline (most likely the httpRequestBegin) to then detect and handle your new Layout type.

In my humble opinion, it seems like a lot of work without much to gain. As, you are simply moving the logic from two separate Controller Renderings for the Header and Footer into a single controller for the Layout and should still keep the actual logic for the header and footer separated anyway.

3
  • Yea, but a lot of the data that's needed on the header and footer is on a single "root" item. But I get what you're saying.
    – Nona Drake
    Oct 24, 2017 at 16:14
  • I see what you are saying. You could pass the root item as the data source to the header and footer renderings. But, I would advise to not do so statically, as ideally, you would allow the content editors to be able to specify the data source, which would also allow for testing, personalization, etc. Another option, that could meet in the middle, is to follow the Habitat example of a "Data Source item" that points to the single item that both the header and footer use. Oct 24, 2017 at 16:19
  • The header and footer items will be statically defined in the layout.
    – Nona Drake
    Oct 24, 2017 at 16:49
0

If the function is not complicated ,maybe you can code in layout file directly.

For example:

enter image description here

1
  • @gary - logic such as this belongs in the controller per MVC convention.
    – Nona Drake
    Jun 12, 2019 at 22:57
0

I just ran across this problem. My solution was to make a view file containing only the following, and link my sitecore layout to it:

@{
    Layout = null;
    Html.RenderAction("Index", "RealLayout");
}

That then uses all 3 of my MVC files:

  • /Controlers/RealLayoutController.cs
  • /Models/RealLayoutViewModel.cs
  • /Views/RealLayout.cshtml

In my case I'm using this line in the controler to get my root item the layout uses rather than passing it through sitecore:

Sitecore.Context.Database.GetItem("/sitecore/content/" + Sitecore.Context.Site.StartItem);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.