I have a website that will contain 2 type of layout.
With no columns
With 2 columns
Header, footer and lots of other parts are the same for both, but inside the main content, there 2 separate layouts and I'd like to choose between 2 site masters. How would I go about accomplishing this?
I was thinking about making a main site master and have the one with the 2 column inherit from that. If that is the correct method, what are the keywords to google for, or you are free to explain inheriting site masters here.
Thank you,
Master pages can inside a master page themselves just like any other view. Just specify the master's MasterPageFile directive as usual:
<%# Master Language="C#" MasterPageFile="~/Views/Shared/App.Master"
Inherits="System.Web.Mvc.ViewMasterPage" %>
Your views can choose to use the overall master page or the nested one as their masters.
Alternately, you can set the MasterPage of your views dynamically in several ways. The regular View() method has an overload to specify the master page:
return View("SomePage", "MasterPageFileHere");
or even better would be to specify an action method to do it for you globally. You can see a good walkthrough of that here.
Related
Being relatively new to MVC I have been struggling for the past several weeks getting my layout to work.
I have managed to get myself really twisted into knots. So instead of trying to explain and unravel my mess perhaps instead someone could explain how I would accomplish the following at a high level.
_Layout this would have all the css js etc. It would also have basic structure.
Of course HTML tags not allowed in code block....each render is in a div.
#RenderPartial(Header)</div>
#RenderBody()</div>
#RenderPartial(Footer)</div>
RenderBody is Index.cshtml and it would be broken into three pieces
#
#Html.Partial(NavMenu, model)</div>
#Html.Partial(SubNavMenu, model)</div>
#Html.Partial(MainContent, model)</div>
I have this basic layout and it looks fine until you click one of the menu items.
The menu items render as:
<a class="k-link" href="/stuffroute">Stuff</a>
That route goes to a controller that returns a view and that navigates away from the above arrangement in Index.cshtml. So I end up with the header, footer, and subdash nav....
So the question is...
How do I route / orchestrate my layout to not lose the differing pieces?
Partials don't do anything for you here. You're essentially asking about how to create SPA (single page application), although in this case your application will have other pages, it's just that the index view will act like a SPA.
That requires JavaScript, specifically AJAX, to make requests to endpoints that will return HTML fragments you can use to replace portions of the DOM with. For example, clicking "Stuff 1" causes an AJAX request to be made to the URL that routes to FooController.GetSubNav([stuff identifier]). That action then would use what was passed to it to retrieve the correct sub-nav and return a partial view that renders that sub-nav. Your AJAX callback will then take this response, select a portion of the DOM (specifically the parent of the sub-nav) and insert the new HTML as its innerHTML.
If you're going to be doing a lot of this, you'll want to make use of some client-side MVC-style JavaScript library, like Angular for example. These make it trivial to wire everything up.
I have a page object and various template objects in my application. pages have names, descriptions urls etc and each have a relationship with a template. templates have different numbers of content boxes and relationships with other controllers (like blogs, galleries etc.).
When I am rendering a page I can work out what template is attached to the page, and what the relevant content is based on that. but I am not sure what the best way is to render the nested Items.
Are you meant to somehow render the templates view from within the other view? Or would you have to just rewrite the view altogether? In this case would I have to create an extra template view for each different template, bundle it with the page views, and then only include it if it is the right one?
Would this be the same for galleries and blogs? do they all need to be bundled with the page? Or can it be called from its proper location?
I'm not sure what the best practice is here and haven't had any luck googling it. I'm suspecting that the key words im using aren't correct. Or this is common knowledge that isn't worth documenting.
You can use shared partials to render views. Check out this guide.
In the views, you can render the partials based upon whatever condition you want.
For example:
- if params[:page] == "my_page"
= render "shared/my_page"
Naturally, you will still need to set up the needed data in the controller.
Shared logic for this can be placed in the Application Controller.
Just to distinguish between a view used inside a dialog or used in a foreach loop (customer details) ?
You don't need an underscore. It's just a convention, and MVC is very keen on using conventions.
Mike Brind has put this nicely in the question Why does Razor _layout.cshtml have a leading underscore in file name?:
Since layout pages in Web Pages are not intended to be served directly, they are prefixed with the underscore. And the Web Pages framework has been configured not to allow files with leading underscores in their names from being requested directly.
Besides that, I find it very helpful to use this convention to differentiate between full views and partial ones.
#Marius Schulz gives a nice reference, but then misses the point. Yes, the underscore helps to differentiate between full views and partial ones, but more importantly, it prevents partial views from being loaded directly by their URL, which could provide some potentially ugly results! (Like no css, for starters.)
EDIT: Mystere Man is right...what was I thinking? URLs in MVC point to controller/action, not to view.
Also, it is possible to mess things up and display a partial in a seperate window, so the naming convention does not prevent that. #Marius Schulz and I had the same misinterpretation of his quote.
The leading underscore is a useful convention to differentiate full and partial views, and I will continue to use it, but is is just a convention, not a functional difference.
Can i have more than one layout per action -
What i want is - "show.html.erb" template to be contained in "layouts/users.html.erb" and this to be contained in "layouts/application.html.erb"
Basically I want application to be the global layout container, but i also want to use intermediate layouts containers between the action template & the final application layout.
If yes, can you point me to some help topics, links.
See the "Nested Layouts" section of the "Layouts and Rendering" guide.
You can use the Nested-Layout plugin:
http://nested-layouts.rubyforge.org
You can follow the instructions in "Sorta Nested Layouts":
http://mattmccray.com/archive/2007/02/19/Sorta_Nested_Layouts/
But what I would recommend is using named yield and content_for statements:
http://guides.rubyonrails.org/layouts_and_rendering.html#using-nested-layouts
This approach lets you specify content for specific parts of your page and generally results in much cleaner and more readable code.
Does anyone know how to pass Content/ContentPlaceholder information from a page, up through it's master page, to the parent master page?
Like this example, but with content defined in ChildFile (the page), being output in ParentMaster (q matster page one level higher in the nesting).
AFAIK this is not possible. I haven't found a perfect solution to this myself, but usually what works well for a little amount of possibilities (such as a 3-choice navigation bar) is a deriving secondary master pages from the master page and using those in your views. Another solution one is would be using javascript to manipulate the master page's content. A third one would be to isolate the content you want to change from the client page into a separate contentplaceholder and specify that on the client page.
Edit: With the arrival of Razor, this problem is now perfectly solved: Simply put your variables in the ViewBag in the child view and read it in the layout.
Use properties, pass them through and let the main master page decide what to do upon rendering