Thanks for raising this, @waiting-for-dev.
To be honest, not including the exposures in the layout’s scope just felt like the right thing to do, and it so happened to align with how we had always used dry-view, that is, to have a view controller superclass where the layout name is configured, inherited by a bunch of subclasses, one for each template. In this arrangement, if you had the layout expecting e.g. a title
, you’d have to ensure every subclass provided its own title exposure, which feels pretty onerous. Also, it never seemed to make sense to me that a single layout file should be rendered with such a varying range of scopes (i.e. all the differing sets exposures for the view controller subclasses).
We of course wanted to do similar things around providing title information up into the layout, and we handled this by using a content_for
-style approach, inspired by Rails’ so-named helper, e.g.
class MyContext
def initialize
@content_for = {}
end
def content_for(key, content = nil)
if content || block_given?
@content_for[key] = block_given? ? yield : content
else
@content_for[key]
end
end
end
This allows us to set the title inside a template:
= content_for :title, "Checkout: Processing payment"
And have it available in the layout:
title
- if content_for(:title)
= "#{content_for(:title)} — "
| My Cool Site
However, now that we support exposures being inherited, I think one could make an argument for including the exposures in the layout’s scope; if the layout was restricted only to work for the common exposures, you could define them as defaults in the superclass and only override them as necessary in the subclasses.
However, there’s part of me that’s still hesitant to provide such wildly varying scopes to a single template. I wonder if there’s another, better way we could handle this?
Either way, I do your use case is something we should make easier: let’s get something done before 1.0. Do you have any other ideas, @waiting-for-dev?