views:

37

answers:

3

I have a method call in my view like this

<%= Navigation.with(params) do |menu| 
              if current_user && current_user.can_verify?
                menu.item("Listings", manage_listings_path())
                menu.item("Listing changes", needing_change_approval_manage_listings_path())
                menu.item("Flagged Items", flagged_manage_listings_path())
                menu.item("Transfers", manage_listing_transfers_path())
                menu.item("Reviews", manage_listing_reviews_path())
              end
              if current_user && current_user.admin?
                menu.item("Log", manage_verifications_path())
                menu.item("Indexer Compensations", manage_compensations_path())
                menu.item("Users", manage_users_path())
              end
            end%>

that splits out the below string

"<li><a href="/manage/listings" class="active">Listings</a></li> <li><a href="/manage/listings/needing_change_approval">Listing changes</a></li> <li><a href="/manage/listings/flagged">Flagged Items</a></li> <li><a href="/manage/listing_transfers">Transfers</a></li> <li><a href="/manage/listing_reviews">Reviews</a></li> <li><a href="/manage/verifications">Log</a></li> <li><a href="/manage/compensations">Indexer Compensations</a></li> <li><a href="/manage/users">Users</a></li>"

I just get this string in my page. I wanted them to be menus nicely styled by CSS. I am just getting the above raw text in my page. How do I convert this string to be treated as HTML by the browser.

Please help

Here is the navigation class

class NavigationMenu < ActionView::Base
  def initialize(params)
    @params = params
  end

  def item(title, path, options={})
    @items ||= Array.new
    unless (route = Rails.application.routes.recognize_path(path,:method => options[:method]|| :get))
      raise "Unrecognised path #{path}, are you sure it's in routes.rb?"
    end

    @items << content_tag(:li, link_to(title,path, :class => (@params[:controller] == route[:controller] && @params[:action] == route[:action])? 'active' : nil))

  end

  def output
    return '' if @items.blank?
    content_tag(:ul, @items.join("\n"), :id => 'navigation')
  end
end

class Navigation
  def self.with(params, &block)
    menu = NavigationMenu.new(params)
    yield menu
    menu.output
  end
end
+4  A: 

You have to add a call to the raw method:

<%= raw ... %>

This is necessary, because in Rails 3 every string is escaped by default, unless you use the raw method. It's like an inverse of the h method in Rails 2, where every string is unescaped by default, unless you use the h method.

Example:

This code in Rails 2...

<%= h "String which must be escaped" %>
<%= "String which must be output raw %>

... must be this in Rails 3:

<%= "String which must be escaped" %>
<%= raw "String which must be output raw %>

(Although an additional call to h doesn't do any harm in Rails 3)

DR
I enclosed the method call into raw()... the string is still not considered as html
lakshmanan
It might be possible that the `Navigation.with` method doesn't really return a string but instead writes it directly into the output. In that case only the original developer of `Navigation` can help.
DR
Or you going on an adventure into `Navigation`'s internals. Bring a machete.
Matchu
I have edited the question to include the Navigation class.. what should i do?
lakshmanan
A: 

You need to append .html_safe to the string - this will stop rails from escaping it when it's time to output text. Probably best to put it in the item method that you call repeatedly.

Jeriko
I have put the navigation class above. please help
lakshmanan
I'm not sure exactly where / how often you need to call it, but fiddle around with `html_safe`. Try change last line of your `Navigation` class to `menu.output.html_safe`. If that doesn't work, change the last line in your `item` method to this: `@items << content_tag().html_safe`. You might need to do the same anywhere a `content_tag` is. Untested- you should figure it out from there though.
Jeriko
A: 

Here is the new class. At last... I got that bug.

class NavigationMenu < ActionView::Base
  def initialize(params)
    @params = params
  end

  def item(title, path, options={})
    @items ||= Array.new
    unless (route = Rails.application.routes.recognize_path(path,:method => options[:method]|| :get))
      raise "Unrecognised path #{path}, are you sure it's in routes.rb?"
    end

    @items << content_tag(:li, link_to(title,path, :class => (@params[:controller] == route[:controller] && @params[:action] == route[:action])? 'active' : nil))

  end

  def output
    @items = @items.join("\n").html_safe
    return '' if @items.blank?
    content_tag(:ul, @items, :id => 'navigation')
  end
end

class Navigation
  def self.with(params, &block)
    menu = NavigationMenu.new(params)
    yield menu
    menu.output
  end
end
lakshmanan