I am having difficulty getting my helper to display a list item. The markup looks like the following:
- #bars.each do |bar|
<% display_bar(bar) %>
The actual helper looks like the following:
module MyHelper
def display_bar(bar)
type = bar.type
concat(%li.type)
concat(%b some text)
concat(%i some more text)
end
end
What am I doing wrong here?
Such things has to be implemented via partials. Or see 5.
<% won't show you anyting. You're in Haml. It's ERb stuff (but even there it wouldn't have shown anything: you'd forgotten the = sign, it should have been <%=).
About concat(%li.type): you cant put your markup inside your Ruby code. Ruby knows nothing about your %li "code".
Amokrane Chentir already mentioned.
You're trying to reinvent the wheel. Rails already provides magnificent helper for such simple cases.
Take a look:
= content_tag_for(:li, #bars) do |bar|
%b= bar.title
%i= bar.id
UPD: content_tag_for sets styles/ids for each li tag based on the current model instance that makes it easy to implement styling/scripting in the future.
The name of your helper is display_bar not display_event.
You should use = instead of <% %>
- #bars.each do |bar|
= display_event(bar)
EDIT
Oops didn't read carefully the content of display_bar method, as #jdoe mentioned you can't use Haml markup syntax in your Ruby code.
Related
My goal is to be able to include a helper method in my Rails 4 project that will list all images in a particular directory in a view so that I don't have to manually add image_tags each time I add a new image.
I've come across several examples of this, but for my purposes I'd like to allocate this job to a helper method, and I can't for the life of me understand why this isn't working.
myapp_helper.rb
module MyAppHelper
def list_logos(clss)
logos = Dir.glob("engines/myapp/app/assets/images/myapp/logos/*.{gif,png,jpg}")
logos.each do |logo|
content_tag("li", class: clss) do
image_tag logo.gsub("engines/myapp/app/assets/images/", "")
end
end
end
end
show.html.erb
<%= list_logos("companies__company") %>
This just prints out the Dir.glob array. Before, I had tried image_tag("myapp/logos/#{image.split('/').last}" to no avail, and so I thought I might have better luck with the gsub method. Nope.
Funny thing is, if, in my helper method, I just write:
logos = Dir.glob("engines/myapp/app/assets/images/myapp/logos/*.{gif,png,jpg}")
image_tag logos.sample.gsub("engines/petitions/app/assets/images/", "")
the image renders fine, which leads me to believe that it's the logos.each iteration which is failing.
I'm stumped. I'll add that this is an engines-based project that I've inherited, and I'm a relative newbie when it comes to Ruby and Rails, so I very well could be missing something simple. Yay! Thanks in advance.
You need to concatenate and return the tags. Try something like this:
module MyAppHelper
def list_logos(clss)
logos = Dir.glob("engines/myapp/app/assets/images/myapp/logos/*.{gif,png,jpg}")
logos.map do |logo|
content_tag("li", class: clss) do
image_tag logo.gsub("engines/myapp/app/assets/images/", "")
end
end.join
end
end
Also, since you're constructing HTML in the helper, you'll need to use html_safe in the template:
<%= list_logos("companies__company").html_safe %>
Oh, and the reason you saw the result of Dir.glob is that each returns the object it's called on.
module MyAppHelper
def list_logos(clss)
logos = Dir.glob("engines/myapp/app/assets/images/myapp/logos/*.{gif,png,jpg}")
list_items = logos.map do |logo|
content_tag("li", class: clss) do
image_tag logo.gsub("engines/myapp/app/assets/images/", "")
end
end
list_items.join
end
end
Is there any standard or emerging standard to document the parameters that can be passed into a Rails partial ?
When _my_partial.html.erb expects a title and an elements local var passed with render 'my_partial', title: t, elements: e, there must be a common way to document their names, expected types and roles, without reading the whole partial code. Something like RDoc or Tomdoc for methods and classes. Isn't there ?
Edit: I've found a post whose author advocates initializing parameters with <% var ||= 'default_val' %> in the first lines of the partial, which is indeed a safe practice and a kind of in-code doc. Is there really no comment/parameter-declaration solution for this ?
At the beginning of your partial, simply call all the variables that are referenced.
# _my_partial.html.erb
<% title %> <--- first line of file
<% elements[0] %>
<h3><%= title %></h3>
<% elements.each do |element| %>
<p> etc ... </p>
Reasons why this is good for your project:
it does not rely on comments or non-code files
any developer on the project can quickly find out which variables are needed by looking at the top of the file in question
by calling the variables, you ensure that a missing variable will result in an exception.
elements is called with square brackets because we also want it to blow up if it's not an enumerable, right?
The practice of using <% var ||= 'default_val' %> is actually unsafe because it allows bugs to hide. You want your code to immediately blow up the moment something isn't done right. And if these variables should be passed, then you want the code to blow up when they're not there.
<li<% if #flits.first == flit %> class="first" <% end %>>
I created css for #flits_list and #flits_list :hover in application.css in Rails 3 but I would like the first flit in the list (flits_list.first) to have different css so I created a class, but this code returns the error
no method error in home#index. you have a nil object when you didn't expect it! You might have expected an instance of array. the error occurred while evaluating nil.first
Any help would be greatly appreciated.
The problem is that #flits is nil, presumably because your all_flits method is returning nil.
However, I'd recommend not putting that logic in the view, breaking up a tag like that. You have several options to make it cleaner:
Option 1: Use the CSS pseudo-class first-child like so:
li:first-child {
...
}
This has the advantage of not requiring any back-end logic or special markup. The only downside is that it has spotty older browser support, e.g. IE6.
Option 2: Use the Rails tag helpers.
<%= content_tag :li, :class => #flits.first==flit?"first":"" %>
Option 3: Tuck it away in a helper method
<%= li_for_flit %>
Then in the helper:
def li_for_flit
#spit out your tag here
end
I am using syntax highlighter "albino" i my rails project ,but it is not displaying any thing
below i have written the code
in helper model
def highlight(text)
Albino.new(text, :ruby)
end
In the view
<% #codes.each do |code| %>
<%= highlight(code) %>
<% end %>
so can any one help me where i am going wrong
or suggest any good highlighter gem for rails?
Which errors do you get?
You are missing a . after #codes:
<% #codes.each do |code| %>
<%= highlight(code) %>
<% end %>
It looks to me like your helper is creating a new Albino instance but not using actually asking it to syntax highlight.
Change your helper as follows:
def highlight(text)
Albino.colorize(text, :ruby)
end
Have you considered using Google Code Prettify? It's the syntax highlighter used on both Google Code and Stack Overflow, which is likely to mean it's reasonably robust.
I don't normally like putting too much functionality in JavaScript, but it seems to me that syntax highlighting is a reasonable feature to add in this way - after all the code will still be readable without the highlighting.
This is a bit of an old problem, but I just came across it myself.
The problem is that Albino is outputting HTML directly as it's being parsed (I think that's the right word, I'm quite new to this).
For example:
highlight(text)
And text is:
def hello_world
puts "Hello World!".to_s
end
Will result in:
<div class="highlight"><pre><span class="k">def</span> <span class="nf">hello_world</span> <span class="nb">puts</span> <span class="s2">"Hello World!"</span><span class="o">.</span><span class="n">to_s</span> <span class="k">end</span> </pre> </div>
What needs to be done is add .html_safe into your highlight method.
Albino.colorize(text).html_safe
That should work.
I have this code
<% if approved %>
<td>Flow Number</td>
<% end %>
and I'd like to shorten it using statement modifiers. Of course I can use
<%="<td>Flow Number</td>" if approved -%>
but is there a shorter way? I'd also like to get the markup out of quotes.
You could use "content_tag", which isn't actually shorter, but may be more appealing, keeping HTML out of your ruby blocks:
<%= content_tag :td, "Flow Number" if approved %>
Otherwise, you could consider writing a helper - which may be appealing if you need to reuse similar logic throughout the page (or over several pages).
Maybe HAML?
That'd be:
- if approved?
%td Flow Number
Not exactly what you're after I know.
Yeah, I think a helper method using content_tag internally would be the best short way.
Using a helper method, you could also yield to the desired output like this:
# in view helper
def show_if(condition, wrapper_tag)
condition ? content_tag(wrapper_tag, yield) : ''
end
# in view
<%= show_if(approved, :td) {'Flow Number'} %>
or
# in view helper
def show_if(condition)
condition ? yield : ''
end
# in view
<% show_if(approved) do %>
<td>Flow Number</td>
<% end %>
I like this last method for a nice generic way to show or hide whole blocks based on a condition. Hope that helps!