8000 Sinatra helpers in Erector template · Issue #63 · erector/erector · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Sinatra helpers in Erector template #63

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
tummychow opened this issue Jun 7, 2014 · 1 comment
Open

Sinatra helpers in Erector template #63

tummychow opened this issue Jun 7, 2014 · 1 comment

Comments

@tummychow
Copy link

Background: Sinatra 1.4.5, Erector 0.10.0, Ruby 2.1.2

I'm using Erector in a Sinatra app. Rather than creating a Tilt registration for Erector, I decided to just declare some Widgets in other ruby files:

require 'rubygems'
require 'erector'

module MySinatraApp
  class FooWidget < Erector::Widget
    def content
      # bla bla
    end
  end
end

Then I require the widget in my main sinatra application, and when I want to render a FooWidget, I make an instance of it and to_html it:

require 'rubygems'
require 'sinatra'
require_relative 'views/foo_widget.rb'

module MySinatraApp
  class App < Sinatra::Base
    get '/' do
      FooWidget.new.to_html
    end
  end
end

Now what I want to do is invoke Sinatra helpers in the body of the FooWidget. For example, I might have some CSS file in my FooWidget, being linked to via some path /css/app.css. But this might fail if my app was actually hosted at example.com/myapp. I want to use the to helper instead. So somehow, I need to get the to helper into the widget.

The heart of the problem (at least it looks that way to me) is that the to helper has to be evaluated in the context of the sinatra app instance, so my current solution is to wrap the helper in a Proc and pass it to the widget like this:

# in the Sinatra app
get '/' do
  FooWidget.new(:to => Proc.new { |url| to url }).to_html
end

# in FooWidget
def content
  link :rel => stylesheet, :href => @to.call('/css/app.css')
end

This seems to work. I'd definitely call it an ugly hack though. Is there a better or clever-er way? I'm willing to restructure the widget and where it fits into my application, if that enables a better solution.

@tummychow
Copy link
Author

Update: I've found a slightly more elegant way around this problem by passing the Sinatra application instance as context to the view:

# in Sinatra app
get '/' do
  FooWidget.new(:ctx => self).to_html
end

# in widget
def content
  link :rel => 'stylesheet', :href => @ctx.to('/css/app.css')
end

Would be better if I could just inject the entire calling context into the view, but I doubt that's feasible since an Erector view is a class itself and has its own context. Other suggestions appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant
0