slime-lang / phoenix_slime

Phoenix Template Engine for Slime
MIT License
310 stars 64 forks source link

String interpolation in tags nested in variables does not work #55

Open MajronMan opened 7 years ago

MajronMan commented 7 years ago

Environment:

p "#{foo}"

= form_ok

Renders
```html
<p>bar</p>
<form>
  <input name="test" value="val">
</form>

Actual behaviour

- foo = "bar"

- form_not_ok = Phoenix.HTML.Tag.content_tag(:form) do
  input name="test" value="#{foo}"

p "#{foo}"

= form_not_ok

Renders

<input name="test"<p>bar</p>
<form>
  <input name="test" value="bar">
</form>     
doomspork commented 7 years ago

@MajronMan it may be that I don't have much ☕️ in me yet but are these two examples not different? The first doesn't appear to include interpolation.

Do you have code somewhere I can peek at? If not, I'll try to throw together a simple Slime application (sans Phoenix) and see if we can narrow it down. @Rakoth I think this may be an issue with the parser, wanted to give you a heads up 👍

MajronMan commented 7 years ago

@doomspork You might be right and it's not a perfect example, I just wanted to show that the case is certainly the interpolation since it's the only difference between those two pieces of code.

I stumbled upon this bug in rather complex circumstances and I doubt they are worth describing in detail, but the main idea was to reuse a form created by my own function (to add CSRF token etc.) with inputs populated with values passed to the template by Phoenix View's assigns. Investigation enabled me to produce this simple example above.

doomspork commented 7 years ago

@MajronMan do you have that code public?

Rakoth commented 7 years ago

@MajronMan Hi! Could you reproduce this issue with slime 1.0?

MajronMan commented 7 years ago

@doomspork Unfortunately I can't share this code :(

@Rakoth I don't know how to do it without using Phoenix Tag and I used this library, but I will try to do so tomorrow (I am in different timezone so it's evening for me)

Rakoth commented 7 years ago

@MajronMan you could just add {:slime, "~> 1.0", override: true} into your project's deps

MajronMan commented 7 years ago

@Rakoth I created a repo with slime 1.0 and the bug is still there https://github.com/MajronMan/slime_bug

Rakoth commented 7 years ago

Thanks @MajronMan it helped a lot! I narrowed it down to a very strange behaviour of EEx:

<h1>header</h1>
<% foo = "bar" %>
<% form_not_ok = Phoenix.HTML.Tag.content_tag(:form) do %>
  test
  <% a = "baz" %>
  <div id="<%= a %>"></div>
<% end %>
<%= form_not_ok %>

renders to


  test
<form>
  test
  <div id="baz"></div>
</form>

Note repeated test string and missing <h1>. There is some problem with <% a = "baz" %> part. Since Slime uses eex representation underhood and attribute interpolation code compiles to similar eex template we are affected by this issue. I will try to find a workaround for this case.