MVC Areas Overlayed Shared Layouts - asp.net-mvc

I'm using Visual Studio to make an MVC App with sub-apps in Areas. In the root _Layout.cshtml I have a navbar-fixed-top that will have navigation to the different areas. I want this perpetuated on every single view. Then I modified the css to create a navbar-fixed-left where I will have navigation within just the particular area and that needs to be unique per area, but used on all views within that area.
So my question is, is there a way to use a shared layout within a shared layout so I don't redundantly copy and eventually screw up the top nav?

You can use the RenderSection('leftNavigation', false) in the html of your _layout page.
from the view that has left navigation you can fill the section
#section leftNavigation
{
<ul>
Some line
</ul>
}
you can use the #section in the _viewStart.cshtml of the area is you have navigation that is valid for the complete area.

Related

Shared content between templates

I would like to share content (essentially blocks of html) between templates.
For example, suppose I have a common footer section with a graphic or two, text and links to 'about us', 'contact us' and so on.
I have different templates for different page layouts, but they all require this footer.
So far I can think of three ways :
Nesting templates : ie have a master one which has the footer content, then a child one for each layout, then the actual page template, but this could get tricky if some pages need a different footer
Using a Partial View to hold the footer content and using #Html.Partial() to pull in the partial view on the various templates
Create a settings document with the footer content and use Umbraco.Content() to fetch the footer property
Is any of these the recommended process (and are there any pitfalls?) or is there a better way?
I would normally do one of the following:
Have properties on the homepage for the footer links etc (in a separate tab) and pull in the values into the footer partial, this way you only have to set it once, rather than having it on every page
Have a Site Settings node at the same level as the home page and pull the values from there into the footer partial
That seems to be fairly standard from most of the Umbraco sites that I've worked on. I wouldn't have all of the properties on each page, unless you need a unique footer each page for some reason.
For example, lets say you add a tab called "Footer Settings" to the Home Page DocType with a single string property with the alias "copyRightNotice" and then you want to display that in a partial, your partial might look something like:
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
var rootPage = Model.Content.AncestorOrSelf(1);
<h3>#rootPage.GetPropertyValue("copyRightNotice")</h3>
}

Left side is a treeview menu and right side need to be the content

I'm developing a ASP.NET MVC5 razor project and I have a cshtml divided into two parts, left part has a div with a treeview with options like a menu and the right part is a div that I would like to load cshtml that correspond to the option selected in treeview, ¿how can I do to achieve this?
Thanks
I am making the assumption that this is a simple navigation that is consistent amongst all pages, for which you can put the common navigation in the _Layout.cshtml. This file contains all the common , , tags used for each page. If you put your navigation in here then it will also be displayed on each page.
The navigation options can then link to your normal actions which display the corresponding views within the layout page.
In this tutorial the author discusses adding a simple navigation (in the section "Using a Layout for common site elements") in the _Layout with the difference that the navigation is at the top and not at the side. You can use css to style the page differently.

Extend element beyond _Layout container MVC ASP.NET (preferred method?)

I'm doing a little experimenting with MVC / Bootstrap / ASP.NET...
Specifically I'm trying to understand a best practice to allow an element to extend past its container based on a given logic, in this case based on the loaded view. (I've read through the threads on showing elements based on a Role membership as well).
I'm trying to replicating the layout shown here: URL To Sample. It has a bootstrap carousel and I like the placement extending the entire width but only showing on the Index (Home) page. Implementing this outside of the classic MVC structure is trivial.
With MVC we have the shared _Layout.cshtml and the container where views are loaded with ...
<div class="container body-content">
#RenderBody()
</div>
It seems the carousel needs either
be placed on the _Layout page and hidden if the loaded view is not the Index page or
be placed on the Index page and allowed to exceed the width of the container
I've tried what I've been able to find in threads but haven't been able to replicate this layout cleanly. Can someone please give a bit of direction?
You could stretch it with css, or a cleaner solution could be to put it in its own (optional) section:
in _Layout:
#RenderSection("carousel", required: false)
<div class="container body-content">
#RenderBody()
</div>
in your front page/home (index) file:
#section carousel {
// code for carousel
}
As commented by #Alex, if your home page is significantly different from the other pages, you can use a separate layout file. To do this, just set the "Layout" global string like this;
in your front page/home (index) file:
#{
Layout = "~/Views/Shared/_FrontPageLayout.cshtml"; // to use a separate file
Layout = null; // to not use a layout file
}

How do I force a view that is shared between areas to use the area layout?

I have an ASP.NET MVC 4 site with areas and I have some System views that I want to share between the areas. Each area has its own separate layout. When I access a System view (by explicitly specifying area = ""), it uses the layout page from the main _ViewStart.cshtml file. The problem is, I want to use the layout of the Area instead.
I have tried removing the Layout declaration from the main _ViewStart.cshtml file and even removing the _ViewStart.cshtml file altogether, but all that does is make my System view render with no layout at all.
I also ran across this post that explains you can put complex logic in your _ViewStart.cshtml file to do this. I tried, but had problems when trying to render partial views on the same page (that are area specific). It would seem that I need to "reset" the area parameter within _ViewStart.cshtml, but I haven't figured out how to do that.
How do I make a main view (from /Views/ folder) take on the layout of the area that called the view? Keep in mind, I don't want to hard code it to the layout of a specific area.
The obvious thing to do would be to make a copy of the System views and their controller in each area, but I am trying to avoid having duplicated files (DRY).
I managed to get this working by using a customized _ViewStart.cshtml that sets the area back to where it was via ViewContext.RouteData.DataTokens. In my case, the area is determined by the TenantType enum in the ApplicationContext (a set of values stored in HttpContext.Current.Items), so getting at it wasn't too difficult.
var appContext = new ApplicationContext();
var area = appContext.CurrentTenant.TenantType.ToString();
this.ViewContext.RouteData.DataTokens["area"] = area;
Layout = "~/Areas/" + area + "/Views/Shared/_Layout.cshtml";
So basically, we are calling a shared controller named SystemController which simply returns View(). That directs it to look for a controller in the common /Views/ControllerName folder, which is where my shared view is.
When it calls _ViewStart.cshtml, it sets the Area back to the current area (which in my case is determined by looking up the domain name in the database). This allows the Area _Layout.cshtml page to use the partial views that are stored in the Area/Shared folder.
Finally, we set the layout page explicitly to the current area's layout.

Applying a common layout to ascx controls in ASP.NET MVC

What would be the best way to implement visual inheritance for partial ascx views in MVC?
I have the main Site.Master file which provides a header, footer, sidebar and main content area. Then i have an Info.Master which uses Site.Master as it's master page and which provides a common layout for almost identical pages. Then all these similar "info" pages on the site have Info.Master set as their master page.
Now i would like to do the same for the ascx partial views that appear on the side bar, as I have a handful of controls that all "look" the same, with headers, footers etc?
You could use normal ASPX views as partials, and create another master page for them with your common partial layout elements. Check out this post from Jeffrey Palermo for more information on this technique.
Another option would be to put your common partial layout elements in one of your main master pages, and take advantage of the view locations. For example, if you had a partial called "Sidebar" with content that only changes for each controller, you could create a general partial in the Views/Shared directory, and more specific partials in each Views/<controller name> directory, and the partial will be overridden.
<div id="sidebarheader">...</div>
<% Html.RenderPartial("Sidebar"); %>
<div id="sidebarfooter">...</div>

Resources