vascop
vascop

Reputation: 5212

Rails content_tag inserts extra "<" and ">" characters

When doing this:

def user_log
    if logged_in? == false
        form_tag session_path, :id => "mform" do
            content_tag(:span, content_tag(text_field_tag :email, "[email protected]"), :class => "memail")+
            content_tag(:span, content_tag(password_field_tag :password, "12345678912"), :class => "mpass")+
            content_tag(:span, content_tag(submit_tag 'Login'), :class => "mbutton")
        end
    else
        ...     
        end
    end
end

I get this:

stack overflow doesn't let me post pictures

Since I don't want the extra "<" and ">", what am I doing wrong?

EDIT: As extra information, on my view I am just doing:

<%= user_log %>

Upvotes: 0

Views: 1242

Answers (3)

vrish88
vrish88

Reputation: 21437

The fundamental problem is that you are using content_tag twice when you don't need to. content_tag essentially calls content_tag_string. Here's content_tag_string's source:

def content_tag_string(name, content, options, escape = true)
  tag_options = tag_options(options, escape) if options
  "<#{name}#{tag_options}>#{content}</#{name}>".html_safe
end

Calling content_tag(text_field_tag :email, "[email protected]") looks like:

"<#{text_field_tag :email, "[email protected]"}>"

and text_field_tag already produces a full HTML tag (it includes the "<" and ">").

All you need to do to get rid of the extra angled brackets is to leave out the second content_tag:

content_tag(:span, text_field_tag(:email, "[email protected]"), :class => "memail")+

Upvotes: 3

DigitalRoss
DigitalRoss

Reputation: 146073

As a first guess, I might try something like:

if logged_in? == false
  ...
else
  ...
end.html_safe

Update: Ok, back to the drawing board.

As a second guess, try this. (And note the extra parameter to content_tag, which required putting the hash in explicit { }...)

def user_log
    if logged_in? == false
        form_tag session_path, :id => "mform" do
          (
            content_tag(:span, content_tag(text_field_tag :email, "[email protected]"),   {:class => "memail"},   false)+
            content_tag(:span, content_tag(password_field_tag :password, "12345678912"), {:class => "mpass"},    false)+
            content_tag(:span, content_tag(submit_tag 'Login'),                          {:class => "mbutton"},  false)
          ).html_safe
        end
    else
        ...     
        end
    end
end

Upvotes: 0

Trotter
Trotter

Reputation: 1270

Though I haven't tried it locally, the problem is likely that Rails is html escaping your handy helper method. To see if I'm right, try throwing this in your view:

<%= raw(user_log) %>

If that works, you can throw raw in your helper method instead:

def user_log
    if logged_in? == false
        raw(form_tag session_path, :id => "mform" do
            content_tag(:span, content_tag(text_field_tag :email, "[email protected]"), :class => "memail")+
            content_tag(:span, content_tag(password_field_tag :password, "12345678912"), :class => "mpass")+
            content_tag(:span, content_tag(submit_tag 'Login'), :class => "mbutton")
        end)
    else
        ...     
    end
end

raw tells Rails that this code is safe and doesn't need to be html escaped.

Upvotes: 0

Related Questions