It is quite possible that I may not have got the point, but I really can't figure out how ASP.NET MVC's HTML Helpers can help me. Here's a sample: -
HTML:
Click Me
HTML Helper:
<%= Html.ActionLink("Click me", "ActionName", null, new {target="blank"}) %>
My eyes are reading HTML more easily, and it seems counter-intuitive to use the HTML Helpers.
Look at the following arguments:
A lot of people (even novices) know how to read HTML. The HTML Helper syntax can confuse easily.
In many cases you need to do more typing writing an HTML 'helper', then you need to write the actual HTML.
The HTML Helper is going to spew real HTML anyway, so why not write HTML directly?
Writing HTML gives you more control over the syntax, and the standards. You can make it conform to whatever HTML standard you want.
Are there any special compelling reasons that I have not understood (since I am self-educated in MVC and there could be gaps) that should make me want to prefer HTML Helpers?
Or are they just code noise?
The primary reason you don't use <a> tags directly is that you don't want to hardcode URLs in your application. The Html.ActionLink method will abstract away the URL generation and you'll specify the controller, action, and other parameters.
So, basically, the two lines you posted in your question are not really equivalent. You should consider adding the dynamic URL generation code to the <a> tag to make them functionally equivalent. Beside that, if you output HTML directly, you'll have to be extremely careful about HTML encoding stuff. Html.ActionLink will do this job for you too.
Let's say that you have many query parameters in the URL like
site.com?a=1&b=2&c=3&d=4&e=1&f=1
<%= Html.ActionLink("Click me", "ActionName", null, new {a=1, b=2, c=3, d=4, e=1, f=1}) %>
The actionlink can build this URL for you. If you didn't have the helper you would have to manually add keys and vlaues to the URL. And this is a real pain. The URL helper can also match URL routes too.
Even better, use MvcContrib and ditch the error prone "magic strings" and replace them with lambdas.
<%= Html.ActionLink<MyController>(x => x.ActionName() ,"Click me",new {target="blank"}) %>
Actually, there's no big difference between
Click Me
and
<%= Html.ActionLink("Click me", "ActionName", null, new {target="blank"}) %>
because in both cases you're hardcoding (URL in the first, action name in the latter).
That's why I create specific helper methods for links, and then I use
<%= Html.LinkSomeAction("Click me") %>
This way I'm sure that when I'll change my mind on which name the action should have, I'll be fine; also, I'll never have to worry about misstyping action names or links.
The solution proposed by mxmissile is also good.
Related
I was wondering if there is a way to upload images in rails 4 not using erb. I have my html code in quotations in my model (so that i can use it as a default for when creating a page). SO I cant put erb in the quotes, cuz if i do it'll come out as the erb code and not the actual view. (i.e. the upload image form. itll come out as the actual f.image_tag instead of the actual upload button).
So I am just seeing if there another way i could implement image uploading into the quotations that wont require erb. But, uses Rails 4.
If you have plain HTML code inside the string, and just want it to be displayed, you need to call .html_safe in your view, like:
'<div id="foo">bar</div>'.html_safe()
Note that normally is a bad practice: that doesn't mean it is always bad, but it means that it is always an attention point to make sure it is the best way to do it.
If you want to do image upload without using form.image_tag, you can just put that in your view and see the generated code (Ctrl+U in Chrome), that, in this case, will be something like:
<input type="file" id="something" />
And add that to the string. Probably some finer validation and options are added too via JS, that would be a pain to add this way - one way to be to add a script tag to the html with the code.
If, however, your string already contains code like this, and you are asking way it is not working, then you need to add an eval to the caller, e.g.:
eval('form.image_tag :image')
Not that this is an even worse smell, and it should be avoided at all costs.
Maybe it would be better to add some flags in your section.rb model, and then use that in a helper or in the view render the html; for example, a has_upload? field, and then you can do something like this:
if #section.has_upload?
form.image_tag :imagem
end
my question concerns about Rails + HAML
I would like to conditionally set a class atribute to a HTML tag. I figured out that the best way to do this is by setting controller variables that are used to set a class of the appropriate HTML tag.
The only solutions I found googling tell me to use a conditional in HAML. But I don't think this is the best approach, since Views shouldn't have any logic control.
So, how could I do this directly from the controller? Which are those controller variables that can set a class of a html tag?
Haml indeed discourages using logic in views and makes it easy to create helpers instead. So one solution would be to create your helper method with any logic inside.
You can't control html markup from controllers, the views are for this purpose.
If you don't want to create a separate helper (it's too much for your requirements), use existing tag helper that comes with rails. It accepts a hash of options which can be intialized from your controller if you like.
But again, I'd go for helper.
For simple logic (like setting a class) you can use haml_tag that exposes class attribute value as a string:
- haml_tag :th, class: "#{'hilite' if params[:order_by]=='title'}" do
- haml_concat link_to 'Movie Title', movies_path(order_by: 'title')
This way you still have conditional logic in the view but resorting to helper in this case may be an overkill.
If you don't want logic in your haml templates then you should move it into a helper. There's really no way for a controller to set the class for a specific html tag; that's not what controllers are for.
Can someone explain why I woud use rails link_to etc instead of straight HTML code? Given that they will render the same once they get to the browser - what is the actual benefit here?
<img id="logo" src="images/logo.png" alt="logo" />
<%= link_to image_tag("logo.png", :alt => "logo", :id => "logo"), root_path %>
Background - I was changing this in a template and stopped to think why am I doing this?
In Rails 3.1, using the helper method would make use of the asset pipeline. For the URLs, that means that the images are postfixed with a checksum (this is called fingerprinting, at least in the Rails guide linked above). That allows to set the HTTP server cache expiration to a maximum - if the file content changes, it will result in another filename and thus force redownloading the file. Otherwise it'll be served from the browser cache.
Also, if you specify an asset host in your configuration, the helper methods will use this information - check out the documentation for image_url.
As for link_to, well, I suppose you could also do something like Link, but using the ruby code is more elegant in my opinion.
You should never hardcode the URL in HTML - it might change, and you really don't want to go through your source code and change all references to index.html to home.html or anything like that.
This is a great question. I consider it better practice to use the rails link_to method as well as the other html helper methods. In this case, it may not have an clear advantage, but more times than not it does. Here are some cases where it is helpful:
Changing Routes
If you have a named route, say foo_path which directs to /foo. You can use <a href='/foo'>, but if you wanted to change foo_path to route to /foo_bar - you would have to go through each view and manually change the links.
Variables
It is common to need a variable for a link. It is more elegant to have <%= link_to #foo.name, foo_path %> than <a href='/foo'><%= #foo.name %></a>
Look and maintainability
In my experience, view code that utilizes helper methods tends to look better and is easier to refactor and maintain.
The helpers expose functionally you don't necessarily always use, like ":remote => true", or automatically including an app context, or bringing in the asset pipeline.
For the simplest use cases there is often little or no benefit, but that's not where helpers shine-they're for when things go cows-legs-up and the "raw" form includes logic too bulky to remain in the mainline template.
Using them for the simple use-cases keeps things consistent, and makes templates more resilient to change.
I have this extension method I created and it returns a string of all the categories in my database as hyperlinks. Great!
#Html.MyMenu()
The problem is that the links are being displayed as text and not rendered as hyperlinks.
When viewing the source code I see:
<div id="menucontainer">
<a href="/Anuncio/Electronics">Electronics</a><a href="/Anuncio/Clothes">Clothes</a><a href="/Anuncio/Domestic">Domestic</a><a href="/Anuncio/Garden">Garden</a>
</div>
I think I may be wrong but I remember that in MVC2 (using the default view engine) you had:
<%: this is rendered, right? %>
Or am I mistaken? Anyways, I'm using MVC3 and the Razor engine. Thanks a lot for your help guys. I'm really enjoying learning as much as I can about this.
Razor escapes HTML by default.
To avoid that, please do something like this:
Writing/outputting HTML strings unescaped
In RC2 a new method called #HTml.Raw should to this.
Or you can change MyMenu to return HtmlString or MvcString rather than just string.
well your extension method should be returning an MvcHtmlString in order to properly display on your page using the <%: %> If it returns a string, all angle brackets and other html special characters will be html-encoded.
RC2 supports #Html.Raw() to output raw HTML
From Scott Guthrie's RC2 anouncement
With RC2 we are adding a Html.Raw() helper method that you can use to explicitly indicate that you do not want to HTML encode your output, and instead want to render the content “as-is”
I have HTML code edited by FCKEditor stored in a database and would like to display (well render) it onto a view. So, for instance, something stored as:
<>pre<>This is some sample text<>pre</>
Will be displayed to the user as:
This is some sample text
(With the appropriate style for pre-formatted-text)
The view already has the required string to display from ViewData, I'm just not sure what the best way to show it to the user is.
Try this:
<%= System.Web.HttpUtility.HtmlDecode(yourEncodedHtmlFromYouDatabase) %>
More info here.
The answer provided by Pure.Krome is flawless for MVC2, but consider Razor syntax:
#Html.Raw(System.Web.HttpUtility.HtmlDecode(Model.yourEncodedHtmlFromYourDatabase))
Alternatively,
#Html.Raw(Server.HtmlDecode(Model.yourEncodedHtmlFromYourDatabase))
You want to use #Html.Raw(str).
See MSDN for more information.
Returns markup that is not HTML encoded.
This method wraps HTML markup using the IHtmlString class, which renders unencoded HTML.