Referring to current HTML-Element in Razor? - asp.net-mvc

In Razor (MVC 4) can I do something like the following (pseudo)code?
<div id="One" #if(THIS_ID_IS("One")) {WRITE_SOMETHING_HERE} ></div>
<div id="Two" #if(THIS_ID_IS("One")) {WRITE_SOMETHING_HERE} ></div>
My intention is, that in DIV "One" an additional attribute will be written, but not in DIV "Two"
So, the THIS_ID_IS(string id) should determine, if the Razor-Parse is INSIDE the given DIV with id="xyz"
Is this possible?

You can use single line if statement to overcome this situation
<div id="One" #(THIS_ID_IS("One") ? "write something" : "") ></div>

Since ids are unique values. All divs will have diffrent ids.
So I dont think there is any need for Conditional Check in razor.
You can Directly add the extra attributes to your Div as follows
<div id="One" attribute-name="Value"></div>

In situations like this I tend to write a helper method to output the markup. This way you a not constrained by the 'rules' of razor. I did a similar thing to output jQuery slider html inside a div.
It also depends on your target audience, I rarely produce the actual views as our designer does most of that. I don't like handing over stuff to the 'creatives' that requires them to write/understand the logic.
It may not be the ideal solution or maybe even overkill in your situation but may be worth a look.
http://www.asp.net/mvc/tutorials/older-versions/views/creating-custom-html-helpers-cs

As much as I would like it to be possible. It looks like it's not the case.
Based on these two articles :
Simple
In depth
It would seem that the Razor engine combines a code and a markup parser.
The main parser decides to use one or the other.
So the parsers are not aware of one another.
Simply put, in your example, <div id="One"></div> and #if(THIS_ID_IS("One")) would be parsed in different scopes and then just concatenated together.

Related

How do I conditionally parse formatting with Thymeleaf?

Is there an alternate way I can get this to process with Thymeleaf? Thymeleaf doesn't like the open tag, but I want to only render it for ROLE_A.
<span sec:authorize="hasRole('ROLE_A')">
<div class="col-xs-10">
</span>
bunch of text not specific to ROLE_A
<span sec:authorize="hasRole('ROLE_A')">
custom text specific to ROLE_A
</div>
</span>
I tried using
<sec:authorize="hasRole('ROLE_A')">
and
<div sec:authorize="hasRole('ROLE_A')">.
The former also doesn't run due to the same open tag issue and the latter is mixing up the closed div tags.
I have numerous blocks like this, so duplicating sections for different roles is not a great solution.
Not in the style you want. You need to close those elements.
My advice is then consider using fragments and load them as required with the needed data/
That way you reuse existing code thus making it cleaner and smaller.
For more examples and way you can do the above check out the Thymeleaf page http://www.thymeleaf.org/doc/springsecurity.html.

Going from Webforms to MVC 4

So I'm converting a WebForms application into ASP.NET MVC 4 and I would like to make sure that I'm making correct coding choices and assumptions.
1). Is the MVC equivalent of a user control a partial view?
2). In an aspx page you have a control like
<asp:Label id="X" runat="server">
with the following code in the code behind:
X.Visible = some_condition ? true : false;
Ok so, for MVC is this code equivalent?
View:
<label id="X" style="display: #Model.IsViewable">
Model:
IsViewable = some_condition ? "inline-block" : "none";
1.) Well, kinda, sorta, but no not really. Very different things - a detailed explanation would be lengthy.
2.) Equivalent maybe, but not really a good thing to do. Your model should contain data only. But yes, you can use this data in your razor views to conditionally do things including show or not show things. However, putting the css strings straight into your model data is klunky at best as well as it's usually a good idea to avoid inline styles whenever possible. IsViewable as a boolean would be better, and you can still handle showing or hiding elements (in a different way).

How to loop through properties in a tab and display them using Razor?

I have a Document Type, that has a tab with some properties.
The properties are Upload types, and Simple Editor types.
(Users are supposed to upload images with some image text).
I have not grouped the "Upload" and "Simple Editor" properties, so how do i do this?
Next question,
I want to loop through each group (there should be 3 currently) and display them on my website.
The markup should look like the following:
<div>
<img src="PATH-TO-UPLOAD-TYPE" />
<div>"TEXT FROM SIMPLE EDTIOR TYPE"</div>
</div>
..
<div>
<img src="PATH-TO-UPLOAD-TYPE" />
<div>"TEXT FROM SIMPLE EDTIOR TYPE"</div>
</div>
...
I would like to use Razor for this. Thanks in advance!
For the first part, using the Razor model, you can't. The content object that you get on the front end only contains the properties, the tabs are not included, as they're only really for organising things in the back office.
You CAN get that information using the Umbraco API, but it's pretty database intensive and could potentially be quite slow if you have a lot of properties/tabs.
You'd be better grouping them yourself in your Razor Macro.
for the second part, you can acces the properties of a page via #Model.property. For example:
<div>
<div>#Model.simpleProperty</div>
</div>

Designer-friendly views in Asp.Net MVC

I'm enjoying Asp.Net MVC and am looking to use it in an upcoming project. Part of the project, however, is an emphasis on being able to expose the project Views to designers for things like theming and so on. One problem I'm anticipating is that Asp.Net MVC views are rather developer-centric. I really don't want to have to educate designers on the intracies of <% vs. <%= let alone something like <% foreach ...
Take a typical MVC menu structure, for example.
<div id="menu">
<ul>
<li><%= Html.ActionLink("Home", "Index", "Main")%></li>
<li><%= Html.ActionLink("About", "About", "Main")%></li>
<li><% Html.RenderPartial("LogOnUserControl"); %></li>
</ul>
</div>
I'd much rather be able to tell designers to go with something like
<div id="menu">
<ul>
<li>{ActionLink "Home", "Index", "Main"}</li>
<li>{ActionLink "About", "About", "Main"}</li>
<li>{Partial "LogOnUserControl"}</li>
</ul>
</div>
Or
<div id="menu">
<ul>
<li><my:ActionLink text="Home" action="Index" controller="Main" /></li>
<li><my:ActionLink text="About" action="About" controller="Main" /></li>
<li><my:Partial name="LogOnUserControl" /></li>
</ul>
</div>
Yes, that last looks suspiciously like a raft of UserControls. Personally, I'm not a fan of actually using UserControls to do this if only because the rendering of those controls happens after pretty much everything else (as I understand it) and I'd prefer something that fits more in line with the MVC lifecycle. All I really need is a set of placeholders and a way to replace them with the relevant rendering.
So where's the best place to do so and what kind of trade-offs am I looking at here. I can imagine a couple of angles to come at this:
A custom ViewPage class where I can override something relevant. ViewPage.RenderView or ViewPage.FrameworkInitialize, maybe, but how you get at the text from there I don't know.
Create a custom TextWriter and override ViewPage.CreateHtmlTextWriter that I can then intercept the text output for replacing stuff. This is pretty late in the cycle, though, and will mess with other custom filtering if I'm not careful.
Create my own IView and ViewEngine classes. I didn't get far down this path before wondering if I was headed to a very bad place.
Custom UserControls that can mimic the functionality needed.
Opinions? Other options? Is my own ViewEngine my best option? My own ViewPage? Or are UserControl objects going to be adequate (please say no)?
Take a look at Spark. It's syntax is similar to your example.
As Charles Conway said, Spark is definitely way to go. Look at example. First, you create partial view in _ActionLink.spark with code:
<viewdata text="String" action="String" controller="String">
${ Html.ActionLink(controller, action, text) }
Then you use it like that in other views:
<ActionLink text="Home" action="Index" controller="Main" />
You just have to prepare partial views for your designers and then they an create view in prefered style. Isn't it easy?
EDIT:
Sorry, that was wrong. <ActionLink text="Home" action="Index" controller="Main" /> will not work, because Home, Index and Main are treates as variables. It may not be that easy to do it as you wish.
I have a similar requirement for a current project, except my 'designers' are more or less end users (people that know their way around html, but it's not their job) which leads to some additional challenges. My implementation is probably too specific for your needs but I'll quickly explain it lest it be useful to anyone else.
I wanted to totally avoid any kind of code in the views for the pages they would be designing so I decided to go with a templating system that does something similar to your point #2, but not at runtime. I am also using spark, although it's not for the benefit of the users as they won't be touching anything that looks like code.
Basically the users create a full html-only template that has placeholder tags for user controls and partial views. The users then upload the template through an interface that parses it and turns it into a spark view.
eg.
For a picture gallery, <gallery /> is parsed into something like !{Html.Gallery(Model)} or <use file="Gallery"/>. For a description field, <desc name="Kitchen" /> is parsed into !{Html.Description(Model, x => x.Descriptions.Kitchen)}. It also checks that "Kitchen" is in fact a property for the object/page that is being templated, or that the Model being passed in for a gallery actually contains a collection of images to avoid runtime errors.
Further properties can be specified in the tag to pass additional parameters to the parsed controls. If the control specified requires Javascript, then it is also included in the view. If there are any problems parsing, output is return specifying which placeholder is invalid and why.
While answered and accepted, I don't see the example of this: why don't you just use:
<li><a href='<%= Url.Action("Home", "Index")%>'>Main</a></li>
Similar in Spark. I prefer this to Html.ActionLink, Html.BeginForm, etc, whenever possible (almost always except for form controls where it's easier to have automatic name encoding with Html helpers).
And your designers do see the link.

Is there a benefit to using the HtmlHelper in MVC?

Is there a specific reason why I should be using the Html.CheckBox, Html.TextBox, etc methods instead of just manually writing the HTML?
<%= Html.TextBox("uri") %>
renders the following HTML
<input type="text" value="" name="uri" id="uri"/>
It guess it saves you a few key strokes but other than that. Is there a specific reason why I should go out of my way to use the HtmlHelpers whenever possible or is it just a preference thing?
Another benefit is that if your ViewData contains a value matching the name of the field it will be populated.
e.g.
ViewData["FirstName"] = "Joe Bloggs";
<%=Html.TextBox("FirstName") %>
will render
<input type="text" value="Joe Bloggs" id="FirstName" />
There are huge benefits:
It has overloaded methods to pre-populate the values (formatted, and safe for HTML) just like the ViewState.
It allows built in support for the Validation features of MVC.
It allows you to override the rendering by providing your own DLL for changing the rendering (a sort of "Controller Adapter" type methodology).
It leads to the idea of building your own "controls" : http://www.singingeels.com/Articles/Building_Custom_ASPNET_MVC_Controls.aspx
One thing is for consistency...I for one always forget the name attribute. Plus, you can extend the functions for your own projects. They're not called helpers for nothing!
The upside to using an abstraction layer is future proofing your code in a pluggable way. Maybe today, you create HTML 4 pages but tomorrow you want to create XHTML pages or XAML or XUL. That's a lot of changes if you just hard code the tags everywhere, especially if you've got hundreds of pages. If everything is calling this library, then all you've got to do is rewrite the library. The downside is that it is usually considered to be slightly less readable by humans. So, it most probably increases the cognitive demand on your maintenance programmers. These advantages and disadvantages really have nothing to do with MVC.
It actually auto populates your textbox based upon first your ViewData.Model.uri and second by ViewData["uri"]. Doing it manually you'd need to do <input value="<%Html.Encode(ViewData.Model.Uri"%>" />
I haven't been doing MVC too long, but I've already written some extension methods to generate menu tabs based on Html.ActionLink. It allows me to be consistent with my usage and, if I decide to change how my CSS menus work, only modify a single method to output the new tab format.
The other use that I have made of them is in conditional output using ViewData to supply values to the controls.

Resources