Ensure proper access to full `locals` hash in templates (#208)

This _should_ already have worked, thanks to the `method_missing`-based `#locals` method that we expose in `Hanami::View::Scope`.

However, `locals` in in fact a _local variable_ in the template rendering context, since that's the name of the one and only parameter for the method that Tilt compiles each template into. This means we can't access the `#locals` on our `Scope` instance without explicitly calling `self.locals`.

To fix this, we pass our `scope._locals` additionally into Tilt's `render` method, which will allow bare `locals` references to work inside templates.

Since this behavior evaded detection for so many years, we now have a dedicated test to make sure it remains working like we expect in the future.
This commit is contained in:
Tim Riley 2022-04-22 22:41:14 +10:00 committed by GitHub
parent 198f2daa5c
commit a5bd7d25bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 21 additions and 3 deletions

View File

@ -46,7 +46,7 @@ module Hanami
end
def render(path, scope, &block)
tilt(path).render(scope, &block)
tilt(path).render(scope, {locals: scope._locals}, &block)
end
def chdir(dirname)

View File

@ -35,7 +35,7 @@ module Hanami
# @overload _locals
# Returns the locals
# @overload locals
# A convenience alias for `#_format.` Is available unless there is a
# A convenience alias for `#_locals.` Is available unless there is a
# local named `locals`
#
# @return [Hash[<Symbol, Object>]

View File

@ -0,0 +1 @@
== "Locals: #{locals.inspect}"

View File

@ -0,0 +1,17 @@
RSpec.describe "Tempalte rendering / locals" do
let(:base_view) {
Class.new(Hanami::View) do
config.paths = FIXTURES_PATH.join("integration/template_rendering/locals")
end
}
specify "Accessing all `locals` inside template" do
view = Class.new(base_view) do
config.template = "locals_in_template"
expose :text, decorate: false
end.new
expect(view.(text: "Hello").to_s).to eq %{Locals: {:text=>"Hello"}}
end
end

View File

@ -12,7 +12,7 @@ RSpec.describe Hanami::View::Renderer do
)
end
let(:scope) { double(:scope) }
let(:scope) { double(:scope, _locals: {}) }
describe "#template" do
it "renders template in current directory" do