Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A problem with string interpolation in HTML attributes #48

Closed
thawatchai opened this issue Jul 19, 2015 · 19 comments
Closed

A problem with string interpolation in HTML attributes #48

thawatchai opened this issue Jul 19, 2015 · 19 comments

Comments

@thawatchai
Copy link

A statement like this

%link(rel="stylesheet" href="#{ static_path(@conn, "/p/css/responsive.css") }")

produces this

<link rel="stylesheet" href="#{ static_path(@conn "/p/css/responsive.css">}")

while we expect the result should be similar to EEx like this

<link rel="stylesheet" href="<%= static_path @conn, "/p/css/responsive.css" %>">

Could you help?

BTW, Thank you very much for this excellent library. It helps us (and many others) switch from Ruby to Elixir easier. 😄

@nurugger07
Copy link
Owner

Glad it's helping! I'll see what I can do to get this fixed. This was reported in issue #44 but I was trying to fix it as part of a major overhaul. I don't think it can wait so I'll see about getting a fix out sooner.

@thawatchai
Copy link
Author

Thanks @nurugger07 👍

@leikind
Copy link

leikind commented Sep 1, 2015

interesting. I also have a problem with this, but a different one:

%link{rel: "stylesheet" href: "#{static_path(@conn, "/css/app.css")}" }

produces

== Compilation error on file web/views/layout_view.ex ==
** (ArgumentError) cannot set attribute @conn inside function/macro
    (elixir) lib/kernel.ex:2025: Kernel.do_at/4
    (elixir) expanding macro: Kernel.@/1
    (swotter) web/views/layout_view.ex:1: Swotter.LayoutView."app.html"/1
    (phoenix) /Users/leikind/projects/learning_phoenix/swotter/web/views/layout_view.ex:1: Phoenix.Template.__before_compile__/1

Is there any workaround?

@dcarneiro
Copy link

Issue #45 is quite similar to this and they have a okeish workaround

    - css_path = static_path(@conn, "/css/app.css")
    %link{rel: "stylesheet" href: css_path}

@etaiklein
Copy link

bump!
I'd love to get the snippet below behaving properly.

    <a href='mailto:#{row["Email"]}' ><%= row["Email"] %></a>

@mgwidmann
Copy link
Contributor

Having problems with this too

chrismccord/phoenix_haml#28

@mgwidmann
Copy link
Contributor

Another workaround is to use <%= %> inside the quotes like:

iex(1)> Calliope.Render.precompile ~s(%a{href: 'http://<%= "www.google.com" %>'}= title)
"<a href='http://<%= \"www.google.com\" %>'><%= title %></a>\n"

But it doesnt always work 😞

iex(2)> Calliope.Render.precompile ~s{%link(rel: "stylesheet" href: "<%= static_path(@conn, "/css/app.css") %>")}
"<link rel=\"stylesheet\" href=\"<%= static_path(@conn \"/css/app.css\") %>\">\n"

Notice the missing , 😢

mgwidmann added a commit to mgwidmann/calliope that referenced this issue Jan 20, 2016
mgwidmann added a commit to mgwidmann/calliope that referenced this issue Jan 20, 2016
@asymmetric
Copy link

@dcarneiro The actual workaround from #45 invloves doing interpolation: href: "#{css_path}"

@smpallen99
Copy link
Collaborator

I started working on a fix for this issue a while ago. Will try to finish it soon. As mentioned above, set a local variable on the line above, then use that variable for the attribute without string interpolation.

@smpallen99
Copy link
Collaborator

Fixed

@jfeaver
Copy link

jfeaver commented Feb 2, 2016

This is still broken @smpallen99. The tests in PR #60 are not passing on master branch. I tried it myself with this snippet:

%a{href: sessions_path(@conn, :create), method: "post"} Sign In

I got a compile error:

== Compilation error on file web/views/sessions_view.ex ==
** (CalliopeException) Invalid attribute 'href: sessions_path(@conn :create) method="post"} Sign I' on line number 2`
    lib/calliope/parser.ex:180: Calliope.Parser.raise_error/3
    lib/calliope/parser.ex:137: Calliope.Parser.merge_attributes/2
    lib/calliope/parser.ex:37: Calliope.Parser.parse_line/2
    lib/calliope/parser.ex:22: Calliope.Parser.parse_lines/1
    lib/calliope/parser.ex:22: Calliope.Parser.parse_lines/1
    lib/calliope/parser.ex:18: Calliope.Parser.parse/1
    lib/calliope/render.ex:7: Calliope.Render.precompile/1
    lib/phoenix_haml/engine.ex:9: PhoenixHaml.Engine.compile/2
    (phoenix) lib/phoenix/template.ex:321: Phoenix.Template.compile/2
    (phoenix) lib/phoenix/template.ex:154: Phoenix.Template."-MACRO-__before_compile__/2-fun-0-"/3
    (elixir) lib/enum.ex:1473: Enum."-reduce/3-lists^foldl/2-0-"/3
    (phoenix) expanding macro: Phoenix.Template.__before_compile__/1
    web/views/sessions_view.ex:1: Pirate.SessionsView (module)
    (elixir) lib/kernel/parallel_compiler.ex:100: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/8

Note that I'm specifying a local copy of Calliope master branch in my local copy of phoenix-haml which is specified in my Phoenix app :)

@smpallen99
Copy link
Collaborator

It should work with string interpolation. Try

%a{href: #{sessions_path(@conn, :create)}", method: "post"} Sign In

I'll see if I can remove the string interpolation when I do the fix for #52.

@mgwidmann
Copy link
Contributor

Is there any current work to make this project use leex and/or yecc? It seems that would make this a much more stable project...

@jamesnolanverran
Copy link

jamesnolanverran commented Apr 24, 2017

I'm going through the phoenix book. This doesn't seem to be working:

%p.alert.alert-info{role = 'alert'}= get_flash(@conn, :info)

The following works, but it also makes an empty bootstrap alert box visible:

%p.alert.alert-info{role = 'alert'}
    = get_flash(@conn, :info)

@smpallen99
Copy link
Collaborator

@jamesnolanverran The problem might be that your mixing attribute types. You should use either one of these:

%p.alert.alert-info(role='alert') ...
or
%p.alert.alert-info{role: "alert"} ...

I'm not saying that will fix the issue, but it might.

I've also noticed issues with @something in places. So, I usually convert them to a variable at the top of the file

- conn = @conn

This does not happen all the time. I remember the exact patterns when when it breaks.

@jamesnolanverran
Copy link

Hi perfect thanks - I switched to using {role: "alert"} and it works fine now. The equals sign doesn't seem to work for me so I'll just use the keyword style for now on.

@smpallen99
Copy link
Collaborator

I find the (role="...") more reliable. I'm using a lot of haml on my new slack clone project. I'm only using (). I found string interpolation to be a little problem with {}. The parse is too aggressive with the curly matching.

I spent a better part of a day a week ago working on the parse. got a few things fixed and broke others. This was when I was trying to fix the broke stuff in 0.4.2. I gave up and rolled back, to 0.4.1. I wish I had the time to get the tokenizer and parse working better, but I'm swamped with my Coherence and ExAdmin projects right now.

@jamesnolanverran
Copy link

Ah, I see I was using curly brackets with the equals sign instead of parentheses.

Another minor issue - surrounding html text in parenthesis:

%p
  (text)

%p (text) will work, but not in this case:

%p 
  %b bold text
  (text)

Workarounds:

%p 
  %b bold text
  %span (text)

or

%p 
  %b bold text
  &#40;text&#41;

@smpallen99
Copy link
Collaborator

@jamesnolanverran Would be great if you add issues for these parsing issues. I want to make sure we are tracking them. Having them buried in comments will be easy to miss :)

Another option that I believe works:

%p
  %b bold text
  = "(#{text})"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants