How do I make one View have different content from what's specified in its layout? - vb.net

Suppose I have many views, each displaying very similar content. Each view uses the same _Layout as defined in _ViewStart.
My _Layout might look like this:
<html>
<!-- some html -->
#ViewBag.SomeViewBagFun
<!-- more html -->
#RenderBody
<!-- more html -->
#SpecialFunction()
</html>
Helper SpecialFunction()
#Linky
#<!-- complex HTML -->
End Helper
Suppose 90% of my pages use the default SpecialFunction() as defined in the layout, but occasionally some views want a different SpecialFunction().
One way to resolve this is to use ViewBag and send each view content that way, but SpecialFunction() contains complex HTML and I want to use razor views.
How do I achieve this?

The best way to do this is to use a Section and when you render it make it NOT required.
See ScottGu's blog for some details: http://weblogs.asp.net/scottgu/archive/2010/12/30/asp-net-mvc-3-layouts-and-sections-with-razor.aspx

You can specify the layout in the actual View, as such,
#{
Layout = "/address/to/your/different/layout.cshtml"
}
Look at this question for further info.

You can add a condition to your viewbag and based on the value the layout would execute specialFfunction or someOtherFunction Scott Guthrie gives a great example of this technique in his blog

OP here.
It's been a while since I used ASP.NET MVC & Razor. I forgot about Sections. I feel silly ^^
Solution:
_Layout
<html>
<!-- some html -->
#ViewBag.SomeViewBagFun
<!-- more html -->
#RenderBody
<!-- more html -->
#If IsSectionDefined("SpecialFunction") Then
#RenderSection("SpecialFunction", False)
Else
#SpecialFunction()
End If
</html>
Helper SpecialFunction()
#Linky
#<!-- complex HTML -->
End Helper
Another View
Section SpecialFunction
<p>Very different HTML!</p>
End Section

Related

Pass (or inject) some HTML/JS or pass some model to shared Net Core Razor Class Library

I would like to have a shared UI project with common interface for other apps, so I don't have to copy/paste the same _Layout.cshtml between all apps which need same UI.
After using this question as reference and this article I have created shared Razor Class Library project. And when I reference this project via NuGet, the _Layout.cshtml in this shared project gets called and renders header with navigation.
But my problem comes then if I want to add some extra HTML to header. Let say I have drop down with some link to main landing page, to user setting, some administration page and etc. But how could I add some extra navigation links specific to concrete app next to all common links? Is there a way to inject HTML? Or maybe to pass some DTO model to this _Layout.cshtml?
Dump image below to help you to see what I try to achieve.
There's two possible approaches. First, you can simply call a partial in your layout:
<partial name="_HeaderExtra" />
Then, just add an empty partial view to the RCL, so it's satisfied, i.e. _HeaderExtra.cshtml. Finally, in your actual application, create the same partial view in the same location as the one in the RCL, and add whatever extra HTML you want there. When the partial is pulled into your layout, it will looking your project first, before falling back to the RCL.
The second option is to use sections. Sections are a little bit more strict, and you must remember to always reimplement them if you do any view inheritance. Essentially, in your layout, at something like:
#await RenderSectionAsync("HeaderExtra", required: false)
Then, in any sublayouts or views:
#section HeaderExtra
{
<!-- add something here -->
}
If you've got a sublayout and you want to be able to further customize this section in views, then you need:
#section HeaderExtra
{
#await RenderSectionAsync("HeaderExtra", required: false)
<!-- add something here -->
}

How can i render page without loading layout page in mvc?

In mvc project,recently I am working on project's performance improvement.I am facing problem for loading layout page.when I am rendering or changing page it should load only content on page,not the layout page.so, I want solution to render my content pages without loading of Layout page.
Set the Layout property of the content pages/views as null on which you don't want the layout page to be loaded.
#{ Layout = null; }
For this you have to use either ajax and partial views or any other javascript UI frameworks like knockoutJS or AngularJS
You would need to use Knockout, Knockout & jQuery can provide you with the postback you are looking for. Here is a link.
http://knockoutjs.com/
Your question is not very clear. Please elaborate it. From my understanding, you wanted a very basic layout for better performance.
This you can achieve by creating a new layout page and remove all the scripts and css files from it. Then use this layout page as your layout for the pages.
Your layout can be very minimal, something like
<!DOCTYPE html>
<html>
<head>
</head>
<body>
#RenderBody()
</body>
</html>

What is the best way to vary Javascript bundles per view?

Some of my views require jQueryUI, some do not.
Rather than adding logic to my _Layout.cshtml Razor view, what is the best way to conditionally add certain bundles.
Try to use the #section directive.
In your Layout.cshtml:
<head>
#Scripts.Render("~/bundles/jquery")
#RenderSection("CustomScripts", false)
</head>
Then somewhere in your View:
#section CustomScripts
{
#Scripts.Render("~/bundles/jquery.ui")
#Scripts.Render("~/bundles/jquery.templates")
}
This way even if you set CustomScripts later in your view, it will always appear in the head tag.
Just put the script link at the bottom of the views that need it?
#Scripts.Render("~/bundles/jqueryui")

#RenderBody() in MVC4 interfering with twitter bootstrap responsive css

Building a site using ASP.NET MVC 4.5, and using twitter's bootstrap-responsive. I noticed that on re-sizing the page, anything rendered by the _Layout view covers what I have rendered using the #RenderBody() statement. Is there any way to correct this?
I can't say for sure, but your problem probably isn't a consequence of #RenderBody. #RenderBody renders the content of your page that isn't in a section. The issue is probably a consequence of which twitter-bootstrap classes style the layout.
All I can do it point you to http://twitter.github.io/bootstrap/scaffolding.html (until the abbreviated html code is included).

Remove <div> generated around Shared Block in EPiServer 7

Episerver always wrap shared block in a tag. I would like to get rid of this. So if in my LinkBlock has a Template with only
link
I would not get a
<div>link</div>
in the view for a user.
If this is not possible how can I change <div> to any other tag, or put a CssClass on it. Like it is possible in not shared blocks:
<EPiServer:Property runat="server" PropertyName="RightContentArea" CustomTagName="aside" CssClass="column-2 sidebar"></EPiServer:Property>
I believe it is the rendering of the ContentArea property which adds the div tags around the blocks it contains.
EPiServer suggests that in order to preserve the editing functionality of the block elements themselves they need to have the div around them.
A possible solution might be for you to do your own custom rendering of content areas, but depending on the kind of block templates you're using it can be tricky to get editing to work. The example in the link is for rendering multiple blocks of the same type.
You can use the CustomTagName and CssClass properties of the Property control to format the container element.
You may also use RenderSettings to modify container elements of child elements (where applicable).
I use this trick in cshtml:
#RenderBlocks(Model.CurrentPage.Content1)
#* ---------------------------------------------------------------------------------- *#
#* Render ContentArea without addition DIVs that EpiServer embed. That breaks layout a lot. *#
#helper RenderBlocks(EPiServer.Core.ContentArea content) {
if(null != content){
var blocks = content.FilteredContents.ToArray();
foreach(var block in blocks){
#Html.PropertyFor(x => block)
}
}
}
You can choose the tag using the CustomTagName attribute on the Property Control
Alternatively, if you wanted to remove the tag, you could use a control adapter. A good example is found here
You can also create a custom content area that doesn't render the divs when edited in live mode and only renders them in edit mode.
If you only need to do this once or twice I would still recommend going with the ChildrenCustomTagName route as it's a bit mroe flexible. If you need to do this a lot and you can't change your CSS easily then I would go custom content area. If you are interested in how to remove the div's I wrote a blog post and a sample site on github here Extra divs in content area how to remove them ?
Since i wasn't able to remove the <div>'s i didn't want, i put my own CSS class on them. This did the trick for me in Webforms. (If anyone still uses it)
Use <RenderSettings ChildrenCssClass="yourCssClass" />
<EPiServer:Property runat="server" PropertyName="RightContentArea"CustomTagName="aside" CssClass="column-2 sidebar"><RenderSettings ChildrenCssClass="yourCssClass"></RenderSettings></EPiServer:Property>