Embedded code blocks in masterpage and page - asp.net-mvc

Well I'm some what baffled!
'Simple problem'
I have parts of my master page that I want to render differently depending on whether or not a ContentPlaceHolder is empty.
So:
I have a master page that as some code like:
<% if (ContentPlaceHolder1.HasControls()) {%>
<div id="LittleDiv">
<% } else { %>
<div id="BigDiv">
<% } %>
some text
</div>
<% if (ContentPlaceHolder1.HasControls()) {%>
<div id="Div1">
yadda yadda yadda
[<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server"/>]
blah blah blah
</div>
<% } %>
I have a page that has some code along the lines of:
<asp:Content ID="Content1" runat="server" contentplaceholderid="ContentPlaceHolder1">
<% if (Model.SomeValue) { %>
hello!
<% } %>
</asp:Content>
(note: the logic in the example page's embeded code block may be unique, for each content place holder, for each page!)
Which seems nice however it doesn't work.
The problem is as I see it (warning I might be completely wrong!). The Embedded Code Blocks are evaluated in the objects Render. A little counter intuitively the page seems to control the master. So the master page's Render is called before the pages render. This means that the master page always sees content in the page's content control.
Is there a nice way round this?
(I have a bit of a solution but it is a monstrous hack! I won't post it yet coz I don't want to influence thinking.)

OK, here's another idea :). Instead of putting the logic in your master page...
<% if (ContentPlaceHolder1.HasControls()) {%>
<div id="LittleDiv">
<% } else { %>
<div id="BigDiv">
<% } %>
some text
</div>
Why not create a placeholder for it? e.g.
<asp:ContentPlaceHolder ID="LittleBigDivPlaceHolder" runat="server" />
You could then allow your concrete non-master pages to decide the content. You could also avoid repeating yourself by moving the logic into a Partial View that could be, say, parameterised by your different views.

Rather than looking for the resultant controls can your master page examine the contents of the ViewData dictionary and work its logic from there?

Alternatively, you could use javascript to show / hide divs on the client.

Related

rendering the yield statement depending on viewport?

I have the following HTML Markup:
<div id="site-wrapper" class="show-for-large-only">
<div id="site-canvas">
<%= yield %>
</div>
</div>
For Mobile Devices i want an additional section like:
<div class="show-for-small-only">
<%= yield %>
</div>
<div id="site-wrapper" class="show-for-large-only">
<div id="site-canvas">
<%= yield %>
</div>
</div>
With CSS i can hide the divs depending on the user's viewport.
Is there a way to avoid rendering the content of yield twice i.e. only to render the relevant div?
Server doesn't know about clients screen size and available viewport. Unless you specify it in the query string or separate ajax request I think it is impossible to determine.
In your place, I would make an additional ajax get request for desired mobile content.
EDIT:
In your controller, you can determine user-agent by http headers, using request object. I would write a helper for this. Save the result to an instance variable like #is_mobile_agent and in your view you would need an additional if statement before yield. Something like
yield if #is_mobile_agent

ASP.NET MVC - MasterPage cannot be applied to this page because the control collection is read-only. If the page contains code blocks

This error message doesn't make a lot of sense in the context of MVC:
MasterPage cannot be applied to this page because the control collection is read-only. If the page contains code blocks, make sure they are placed inside content controls (i.e. <asp:Content runat=server />)
What's it mean?
My view looks something like this:
<%# Page Inherits="System.Web.Mvc.ViewPage<Site.Controllers.ProductCategoryController.ProductListViewModel>" MasterPageFile="~/site.master" %>
<% foreach (var prod in Model.Products) { %>
<li><%=prod.Description%></li>
<% } %>
I figured it out, it is quite a simple mistake. The problem was my view code wasn't wrapped in a content control (which maps to a contentplaceholder in the master page).
Of course my view should be like this:
<%# Page Inherits="System.Web.Mvc.ViewPage<Site.Controllers.ProductCategoryController.ProductListViewModel>" MasterPageFile="~/site.master" %>
<asp:Content runat="server" ID="Content1" ContentPlaceHolderID="BodyContent">
<% foreach (var prod in Model.Products) { %>
<li><%=prod.Description%></li>
<% } %>
</asp:Content>
Pretty obvious but I just couldn't see it!
And the error message didn't really help me.

Split ruby on rails view correctly

playing around with rails and got a little problem with the layout.
I have a simple home mvc.
Content of the home view is just
<h3>Home</h3>
<p>content</p>
I have my application view for overall design with some partials and so on.
<section>
<header>
<div class="pull-right">
<a class="btn btn-small">Edit</a>
<a class="btn btn-small">Blurm</a>
</div>
<h3>Head goes here</h3>
</header>
<%= yield %>
</section>
Now I come to my main Part for displaying the different pages with yield.
How should i split up the template? Should I put the complete application part to the home view to display the Heading in the right place? Or is there a possibilty to get the Heading different from the yield?
Any Suggestions?
P.S.: If someone have a nice tutorial or website for explaining How to structure and plan the views. A comment below would be nice.
best regards
dennym
I think that you are asking about using named yields.
From your structure, we add a yield named header
<section>
<header>
<div class="pull-right">
<a class="btn btn-small">Edit</a>
<a class="btn btn-small">Blurm</a>
</div>
<h3><%= yield :header %></h3>
</header>
<%= yield %>
</section>
And then we set the content for that named yield:
<% content_for :header do %>
My header
<% end %>
<p> Rest of page ...</p>
If you are just trying to change you header periodically I would suggest either you have different layouts that have different headers which you could specify in your controller by
layout :layout_name, or dynamically change header content using js.

Filling Sidebar Implementation with Rails and Bootstrap

This is mostly an implementation question for a webapp I'm trying to develop. I'm relatively inexperienced so I want to check if my idea for implementation is decent or if there's a much easier way.
The Problem
I want to create a scrollable sidebar that automatically fills with small containers that hold a user profile photo and their name. The basic idea is that a user is a member of a class and the sidebar should hold all of their classmates. The sidebar should be a fixed size and the user should be able scroll down through their classmates and click on a user if they want visit their page.
My Ideas For Implementing
It seems to me that I will need to use some embedded ruby to direct the filling process. Some psuedocode would be something along the lines of "For every user in this class, create a container with their picture and name". I haven't given a lot of thought as to actually handle this step but I'm mostly concerned with the actual html structure.
My idea is to do something like this:
<div class="container-fluid">
<div class="row-fluid">
<div class="span2">
<!-- for each user in class -->
<div class="container-fluid">
<div class="row-fluid">
<div class="span">
<!-- Load appropriate user data -->
</div> where appropriate...
Is this the "proper" way to go about implenting this? I haven't been able to find much information on the idea and visit an example site's source code isn't all that helpful as the sidebar is already filled...
I would separate your sidebar HTML and logic into a partial, E.g. "app/views/shared/_sidebar.html.erb". From there on, you can accept a collection of data from whatever view you're rendering.
View file
<div class="container-fluid">
<div class="row-fluid">
<%= render "shared/sidebar", collection: #users %>
</div>
</div>
Sidebar partial
<div class="span2">
.....
<% #users.classmates.each do |e| %>
<%= e.name %>
<% end %>
.....
</div>

Html.Encode importance

I'm working through the NerdDinner MVC tutorial and came across this and was wondering about.
On page 62 of the pdf they have the following:
<asp:Content ID="Main" ContentPlaceHolderID="MainContent" runat="server">
<h2>Upcoming Dinners</h2>
<ul>
<% foreach (var dinner in Model) { %>
<li>
<a href="/Dinners/Details/<%=dinner.DinnerID %>">
<%= Html.Encode(dinner.Title) %>
</a>
on
<%= Html.Encode(dinner.EventDate.ToShortDateString())%>
#
<%= Html.Encode(dinner.EventDate.ToShortTimeString())%>
</li>
<% } %>
</ul>
</asp:Content>
They then state that instead of using an <a> tag that you can use the Html helper like so:
<%= Html.ActionLink(dinner.Title, "Details", new { id=dinner.DinnerID }) %>
The question is: Isn't it still important to Html.Encode the dinner.Title from the Model when using this approach? If not, why not? If so, is there a way to use the Html.ActionLink and still use Html.Encode?
Html.ActionLink already calls Encode, internally (see the source). You don't want to do it twice.

Resources