Reputation: 38682
In my application, I let users input annotations, which are potentially unsafe. When I render them in my view, the following shows the annotation nicely:
<%= simple_format h annotation.body %>
It preserves line breaks but also escapes HTML properly. Now, I need to render this body in an overlay, which is created by Javascript. Right now, I fetch my annotations through JSON by calling the following from the controller:
def index
# ...
respond_to do |format|
format.json { render :json => @annotations }
end
end
And create the overlay like this (very simplified example):
$.getJSON(this.annotations_url, function(data) {
$.each(data, function(key, val) {
annotation = val;
this.div_body.html(annotation.body);
// ...
Of course, the resulting HTML will not be escaped properly and the line breaks aren't preserved as well.
Now, I don't feel like using pure Javascript to do the escaping and line break conversion because it feels like I wouldn't be DRYing a lot if I did so. It seems hard to maintain and clutters the whole code.
Can't I somehow send the safe HTML body from the controller through JSON? It looks as if the ERB simple_format
and h
methods are only available in views.
Or should I really do everything in Javascript?
Upvotes: 2
Views: 153
Reputation: 38792
I think you can use the helpers
every where just calling them by their long name:
ActionController::Base.helpers.simple_format str
ERB::Util::html_escape str
Once you have this you can customize your Model.to_json
behavior to include an already parsed version of the Model.body
.
Of course there are two problems with this approach:
But sometimes trying to avoid these issues is bringing more complexity than clarity.
Upvotes: 1
Reputation: 10089
You can return JSON from erb templates just as you would for html. Instead of returning JSON in the controller, let it fall through doing no rendering, just like html responses. Instead of naming the view index.hmtl.erb, name it index.json.erb.
I'm not sure that's the best cleanest way. It is the only way Rails has provided simple_format for responses html or other.
Upvotes: 0