Recognize Path-like objects in Templates#compile_template #529

wants to merge 1 commit into from

2 participants


The following commit aims at allowing the following behavior

get '/:some/:parameters' do

  # Find an existing file that correspond to the request. Make some checks.
  # Returns a Pathname or a Path instance, responding to #path
  filepath = ...

  # Render found file, reusing sinatra template cache, options, etc.
  erb filepath, ...


The pull request allows this provided that the located file is inside the views folder. This is to match the current behavior that does not allow rendering files outside it (without extending find_template).

I'm not sure this pull request makes sense. However, I'm not really confortable with the following workarounds:

# assuming a relative_from method that returns another Path(name)
erb filepath.relative_from(settings.views).to_s.to_sym

# manually use Tilt, no cache support ...

# explicit use of the template cache
template_cache.fetch(filepath){ ... }.render ...

What do you think?


This pull request fails (merged 985f11b into 8752085).


Further thoughts about this. An additional problem I encounter is that, currently, in Sinatra knowing the name or file of a view is not sufficient for rendering it. You also need to know which engine has to be used:

def render(engine, data, options={}, locals={}, &block)
def compile_template(engine, data, options, views)
def find_template(views, name, engine)

All those methods require knowing the engine a priori. That seems more restrictive than Tilt itself, which returns a template if you provide a file... However, using Tilt directly or indirectly through the template cache seems difficult since the engine is used as a cache key:

template_cache.fetch engine, data, options

Now, it is true that having only the name of a view might be ambiguous if multiple files have the same name but different extensions. Still, such ambiguity already hurts sinatra internals somewhat, in find_template...

By the way, Tilt's support for smart bind between extensions and engines is difficult to use in Sinatra for the same reasons.


Ok, I've got a full example of what I would like to achieve:

The current implementation works, but needs serious workarounds that use private APIs:

Let me know what you think!


Forget about this one, too specific. I'll make another proposal for better integration with Tilt.

@blambeau blambeau closed this Jun 14, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment