I have a Ruby on Rails app, using Backbone. In the coffee, I have:
class App.Views.TableElement extends Backbone.View
events:
"change input[name='past_results']": "togglePastResults",
"change .cohort_toggle select": "selectCohort"
initialize: (options) ->
@listenTo(@model, "change", @render)
render: =>
console.log @model.toJSON()
@$el.empty().append(HandlebarsTemplates['shared/table_element'](@model.toJSON(), data: { tableClass: @tableClass() }))
@$el.find('.cohort_toggle select').val(@model.get("selectedCohortLabel"))
@$el
I think that that's the relevant bit.
I'm not going to present the entire model.toJSON output, but it's got headers and rows, like a table should. One of the elements in one of the rows is supposed to be a link. Eventually I think it's going to be a link to javascript I think, but for now, I just want a link to google for testing... So I'm hardcoding the element as '<a href="https://google.com">Visit google</a>'
However, that's getting interpreted with <
and stuff, so the HTML is what actually appears in the table.
The questions are: Who's escaping my HTML, and how do I make it stop?
The model (parts of it):
class App.Table extends Backbone.Model
defaults: {
showPastResults: true
}
initialize: ->
@set("selectedCohortLabel", @get("cohortLabels")[0])
columns: =>
columns = []
Array::push.apply columns, [@get('categories')]
Array::push.apply columns, @get('currentData')
Array::push.apply columns, [['<a href="https://google.com">Visit google</a>', 5, 5]] if @get('haveDataBytes')
columns
template. All of it because I'm not sure what any of it does... and so it's got columns that the model excerpt doesn't:
<table class="table {{@tableClass}}">
<thead>
<tr>
{{#each headers}}
<th class="{{this.class}}">
{{#if this.data }}
{{ this.data }}
{{ else }}
{{ this }}
{{/if}}
</th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each rows}}
<tr>
{{#each this}}
<td>{{this}}</td>
{{/each}}
</tr>
{{/each}}
</tbody>
</table>
From the fine manual:
HTML Escaping
Handlebars HTML-escapes values returned by a{{expression}}
. If you don't want Handlebars to escape a value, use the "triple-stash",{{{
.
Presumably your columns
data gets into the model's toJSON
return value somewhere. Your template will need some way of knowing when it is dealing with a link so that it can say {{{link}}}
instead of {{link}}
to keep {{...}}
from escaping the HTML.
Also, you could write your columns
method like this:
columns: ->
columns = [ @get('categories'), @get('currentData')... ]
if @get('haveDataBytes')
columns.push ['<a href="https://google.com">Visit google</a>', 5, 5]
columns
to avoid the strange and non-idiomatic use of Array
's prototype.