jeremyevans/roda

Sending tilt's .rcsv from roda with escape => true

njh opened this issue · 2 comments

njh commented

Hi,

I have been looking at using tilt's CSV engine output with roda, along with erubi for HTML pages.

I have been using plugin :render, :escape => true in order to ensure that HTML is escaped by default, but the CSV engine, doesn't seem to like being past the argument :escape => true.

The error message I get is:

ArgumentError at /sheet
Unknown options: escape.

Things I have considered:

  • Pass :escape => true every time I call render() or view() with erubi, instead of it being default
  • Find a way to remove the default :escape argument just when using CSV
  • That there is a bug somewhere but I am not sure if it is roda / tilt or csv that is the problem

config.ru

require 'roda'
require 'erubi'

class App < Roda
  plugin :render, :escape => true

  route do |r|

    r.root do
      r.redirect '/page'
    end
    
    r.get 'page' do
      render('page')
    end

    r.get 'sheet' do
      response['Content-Type'] = 'text/csv'
      render('sheet', :engine => 'rcsv')
    end
  end

end

run App

views/page.erb

<h1>Hello World</h1>

<p><%= 'Escape this &amp; this' %></p>

views/sheet.rcsv

csv << ["Row 1 Col 1", "Row 1 Col 2"]
csv << ["Row 2 Col 1", "Row 2 Col 2"]

Gem versions

  • erubi (1.7.1)
  • rack (2.0.6)
  • roda (3.14.1)
  • tilt (2.0.9)

Thanks for the report. I haven't used the rcsv format before, so I wasn't aware of this problem.

What the :escape render plugin option does is require tilt/erubi and set the :escape template option. However, the Tilt rcsv format does not support the :escape option, hence the error.

To work around this problem, require 'tilt/erubi' manually, and use :engine_opts=>{'erb'=>{:escape=>true}}.

One issue with changing the render plugin from :template_opts to :engine_opts is that users could be using custom engine strings (e.g. :engine=>'html.erb'), and that would break if :engine_opts is used. However, it may be worth adding another option to the render plugin to specify which engines to escape. Maybe :escape_engines=>'erb' and then it will not modify :template_opts but only add the :escape option to the related entries in :engine_opts. Do you think that makes sense?

njh commented

Thanks for your speedy work on this Jeremy.

I am using the version of the gem from git master:

gem 'roda', :github => 'jeremyevans/roda'

And now only enabling escaping for the erb/erubi engine:

  plugin :render, :escape => %w|erb erubi|

And it is working well!