slim
slim copied to clipboard
Problem with escaped fields_for / simple_fields_for when used in a trailblazer cell
When transposing the trailblazer demo app Gemgem (which is using haml) to slim, we are facing a problem with slim escaping fields_for
or simple_fields_for
.
This seems to come from ActionView escaping everything and everywhere.
Haml has solved it with gem "haml", github: "haml/haml", ref: "7c7c169"
which should be merged soon.
That doesn't make %haml cooler than slim ;) Would be great if we could solve this for slim too in a future version!
The slim trailblazer demo app (reproducing the problem) can be seen here: https://github.com/sebabouche/traildemo/tree/1bd1c96e760c8811ef14ad50d784f3351774e667
Just for reference, the haml issue was resolved by haml/haml@297c0d9
This is impossible to debug for me without looking into trailblazer which I don't know. Could you help me with a minimal runnable example showing the undesired behaviour.
Hey, I created a mini project here : https://github.com/sebabouche/trb-slim-nested-form-issue.
I could explain you how things are working with TRB by chat?
And I pushed it on heroku here : https://trb-slim.herokuapp.com
Ok thx, I will take a look
@sebabouche This is not at all a minimal demo. I have limited time to debug such things which are not directly related to slim but more to framework integration. Also the haml fix is totally unrelated since it removes some haml monkey patch which slim doesn't have.
Did you already ask @apotonick about it? Is there something weird going on concerning the capturing?
Does it work correctly if you use == instead of = in the form? (This is not a fix, just to see if it would work)
Thanks @minad. The problem is that slim HTML-escapes a string even though it's turned off in cells-slim: https://github.com/trailblazer/cells-slim/blob/cce8e43924ec1d2c32f51dc426e20061e5723102/lib/cell/slim.rb#L13
@apotonick Ok, however I don't think this is a good idea. Is it not possible to just mark the strings html_safe and let slim do the work?
@apotonick You should probably also use the Slim::RailsTemplate
@minad , I'll shrink the mini project to refom + cell + slim. It seems that it's not related to trailblazer. And == doesn't solve the problem.
No way, Cells is completely decoupled from Rails, that's why it's so fast and popular. :grimacing:
We don't use html_safe
for the same reason - in Cells, it works differently: We don't need to escape every possible string a million times, since all data in the view is injected via reader methods on the cell instance. That in turn can be escaped by the cell - the template engine shouldn't do any escaping.
By having that strong interface, we are about 10x faster than Rails (and less code).
@sebabouche You don't even need Reform, just the form_tag
will do.
Ok I understand. Can you take a look at the code that slim generates since you say that it escapes despite being told not to do so? Just access the @src
variable of the compiled template.
See here: https://github.com/judofyr/temple/blob/master/lib/temple/templates/tilt.rb#L30
@output_buffer = []; _temple_html_pretty1 = /<code|<pre|<textarea/; @output_buffer << ("<h3 class=\"page-header\">\n What do you want to talk about ?\n</h3>".freeze);
;
; _slim_controls1 = simple_form_for contract, html: {class: css_class} do |f|; _slim_controls2 = '';
;
; _slim_controls2 << ((::Temple::Utils.indent_dynamic((f.error_notification), true, "\n", _temple_html_pretty1)).to_s);
;
; _slim_controls2 << ((::Temple::Utils.indent_dynamic((f.input :name, placeholder: "Name", label: false, readonly: contract.readonly?(:name)), false, "\n", _temple_html_pretty1)).to_s);
; _slim_controls2 << ((::Temple::Utils.indent_dynamic((f.input :description, placeholder: "Description", label: false), false, "\n", _temple_html_pretty1)).to_s);
; _slim_controls2 << ((::Temple::Utils.indent_dynamic((f.input :file, as: :file), false, "\n", _temple_html_pretty1)).to_s);
; _slim_controls2 << ("<br />\n<div class=\"panel panel-default\">\n <div class=\"panel-heading\">\n <h3>\n Do you know any authors?\n </h3>\n </div>\n <div class=\"panel-body\">".freeze);
;
;
;
;
;
; if signed_in?;
; _slim_controls2 << ((::Temple::Utils.indent_dynamic((f.input :is_author, as: :boolean, label: "I'm the author"), true, "\n ", _temple_html_pretty1)).to_s);
;
; end; _slim_controls3 = f.simple_fields_for :users do |ff|; _slim_controls4 = '';
; if @operation.instance_of? Thing::Create;
; _slim_controls4 << ((::Temple::Utils.indent_dynamic((ff.input :email), false, "\n ", _temple_html_pretty1)).to_s);
; else;
; _slim_controls4 << ((::Temple::Utils.indent_dynamic((ff.input :email, readonly: ff.object.readonly?), false, "\n ", _temple_html_pretty1)).to_s);
; if ff.object.removeable?;
; _slim_controls4 << ((::Temple::Utils.indent_dynamic((ff.input :remove, as: :boolean, input_html: {checked: false}), false, "\n ", _temple_html_pretty1)).to_s);
;
; end; end; _slim_controls4; end; _slim_controls2 << ((::Temple::Utils.indent_dynamic((_slim_controls3), false, "\n ", _temple_html_pretty1)).to_s); _slim_controls2 << ("\n </div>\n</div>".freeze); _slim_controls2 << ((::Temple::Utils.indent_dynamic((f.submit), true, "\n", _temple_html_pretty1)).to_s);
; _slim_controls2; end; @output_buffer << (::Temple::Utils.indent_dynamic((_slim_controls1), false, "\n", _temple_html_pretty1)); @output_buffer = @output_buffer.join("".freeze)
@minad @apotonick is this bug already fixed?
I have the same problem with fields_for
, cells and slim so the bug still exists.
Same problem over here
Same problem for me using Slim + fields_for
+ Spree CMS 3.1.1. Tried making a partial in Slim and it escapes the content. Is there a workaround at all? I hate to have to use ERB. Tried == form.fields_for
, but no dice. I'm not using cells at all, so I'm wondering if I should create another issue. It's just a simple form_for
with fields_for
Example:
= render partial: 'line_item', collection: order_form.object.line_items, locals: { order_form: order_form }
And in my partial, I had order_form.fields_for :line_items, line_item do |item_form|
, everything after that got escaped. My whole project is written in Slim except for this partial that uses fields_for
. I ended up just coding it in ERB (yuck), which is really unacceptable.
@tjjjwxzq - I appreciate you showing an example, but I wasn't able to get this to work properly in my project, not sure what I was doing wrong.
This is still an issue. In Rails (though I suppose this could be generalized), I figured a workaround which involves putting all the stuff under fields_for
in a separate view, then rendering it unescaped:
= form_for @object do |f|
...
= CGI::unescape_html(self.(:fields_for_something, f).to_str)
Note: I have to call to_str
here on the render output for reasons I don't entirely understand. Basically the output rendered by the cell is an ActiveSupport::SafeBuffer
(again, this is a Rails project), and calling CGI::unescape_html
on that seems to lead to some nil
error, so I convert it to a proper String
object first.
Same problem here.
Using rails 5.0.1
Using cells 4.1.5
Using cells-slim 0.0.5
Using cells-rails 0.0.6
Using slim 3.0.7
SyntaxError: (__TEMPLATE__):1: syntax error, unexpected ';'
_erbout = []; _temple_html_pretty1 = /<code|<pre|<textarea/; --;^
(__TEMPLATE__):3: syntax error, unexpected ';'
; --;^
I got this error message when using slim, what's the problem? Anyone help? Thanks
That looks like you're using ERB? @tarvos21
@apotonick, oh yes, it's in nanoc, a site generator, with slim, but I don't know what's the problem here.
I have the same problem. I found workaround, which works for me. I used inline block and raw method to render fields.
= raw(f.fields_for(:files) { |files_f| files_f.file_field :file })
In my case fields_for
didn't work but this did:
== f.simple_fields_for(:children) { |form| cell(AnotherCell, form.object, f: form).to_s.html_safe }.to_s
Thanks opted that too, though I didn't need to to_s
:
== f.simple_form_for(@model) {|form| cell(FormContents, form).() }