Skip to content

Commit 506caa4

Browse files
committed
Specify fixed locals for rendered templates by default, disable with use_template_fixed_locals? false
This is designed to work with the fixed locals support added to Roda, in applications that specify default fixed locals for templates using the :template_opts option to Roda's render plugin. A recommended practice for Roda going forward is to specify that templates do not accept local variables by default, and force templates that accept local variables to specify which local variables are accepted: plugin :render, template_opts: { default_fixed_locals: '()', extract_fixed_locals: true } This change allows Rodauth to work with such a recommendation, by specifying that Rodauth templates take the rodauth local variable (and the button template takes the value and opts local variables). In cases where the user is passing additional local variables via the :locals option, the assumption is they are using their own templates, in which case Rodauth shouldn't specify the fixed locals, so Rodauth doesn't set fixed locals in that case. There may be other cases where Rodauth shouldn't set fixed locals, and for those cases, the use_template_fixed_locals? false configuration method can be used. If the Roda and Tilt versions support fixed locals, this run the tests with fixed locals on by default.
1 parent 14a5e38 commit 506caa4

File tree

5 files changed

+55
-2
lines changed

5 files changed

+55
-2
lines changed

CHANGELOG

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
=== master
22

3+
* Specify fixed locals for rendered templates by default, disable with use_template_fixed_locals? false (jeremyevans)
4+
35
* Make rodauth.has_password? method public (enescakir) (#461)
46

57
* Use JWT.gem_version to check jwt gem version, for compatibility with jwt 2.10.0 (janko) (#462)

doc/base.rdoc

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ unopen_account_error_status :: The response status to use when trying to login t
8282
use_database_authentication_functions? :: Whether to use functions to do authentication. True by default on PostgreSQL, MySQL, and Microsoft SQL Server, false otherwise.
8383
use_date_arithmetic? :: Whether the date_arithmetic extension should be loaded into the database. Defaults to whether deadline values should be set.
8484
use_request_specific_csrf_tokens? :: Whether to use request-specific CSRF tokens. True if the default CSRF setting are used.
85+
use_template_fixed_locals? :: Whether to specify fixed locals for rodauth templates. True by default, should only be set to false if overriding the templates and having them accept different local variables.
8586

8687
== Auth Methods
8788

lib/rodauth/features/base.rb

+11
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ module Rodauth
6767
auth_value_method :unopen_account_error_status, 403
6868
translatable_method :unverified_account_message, "unverified account, please verify account before logging in"
6969
auth_value_method :default_field_attributes, ''
70+
auth_value_method :use_template_fixed_locals?, true
7071

7172
redirect(:require_login){"#{prefix}/login"}
7273

@@ -409,6 +410,7 @@ def csrf_tag(path=request.path)
409410

410411
def button_opts(value, opts)
411412
opts = Hash[template_opts].merge!(opts)
413+
_merge_fixed_locals_opts(opts, '(value:, opts:)')
412414
opts[:locals] = {:value=>value, :opts=>opts}
413415
opts[:cache] = cache_templates
414416
opts[:cache_key] = :rodauth_button
@@ -912,13 +914,22 @@ def update_account(values, ds=account_ds)
912914

913915
def _view_opts(page)
914916
opts = template_opts.dup
917+
_merge_fixed_locals_opts(opts, '(rodauth: self.rodauth)')
915918
opts[:locals] = opts[:locals] ? opts[:locals].dup : {}
916919
opts[:locals][:rodauth] = self
917920
opts[:cache] = cache_templates
918921
opts[:cache_key] = :"rodauth_#{page}"
919922
_template_opts(opts, page)
920923
end
921924

925+
def _merge_fixed_locals_opts(opts, fixed_locals)
926+
if use_template_fixed_locals? && !opts[:locals]
927+
fixed_locals_opts = {default_fixed_locals: fixed_locals}
928+
fixed_locals_opts.merge!(opts[:template_opts]) if opts[:template_opts]
929+
opts[:template_opts] = fixed_locals_opts
930+
end
931+
end
932+
922933
# Set the template path only if there isn't an overridden template in the application.
923934
# Result should replace existing template opts.
924935
def _template_opts(opts, page)

spec/rodauth_spec.rb

+35-1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,40 @@
7474
page.title.must_equal 'Foo Login'
7575
end
7676

77+
it "should disabled setting default_fixed_locals if use_template_fixed_locals? false" do
78+
rodauth do
79+
enable :login
80+
use_template_fixed_locals? false
81+
end
82+
roda do |r|
83+
r.rodauth
84+
end
85+
86+
if app.render_opts[:template_opts][:default_fixed_locals]
87+
proc{visit '/login'}.must_raise ArgumentError
88+
else
89+
visit '/login'
90+
page.title.must_equal 'Login'
91+
end
92+
end
93+
94+
it "should allow overriding fixed_locals via template_opts" do
95+
rodauth do
96+
enable :login
97+
template_opts(template_opts: {fixed_locals: "()"})
98+
end
99+
roda do |r|
100+
r.rodauth
101+
end
102+
103+
if app.render_opts[:template_opts][:default_fixed_locals]
104+
proc{visit '/login'}.must_raise ArgumentError
105+
else
106+
visit '/login'
107+
page.title.must_equal 'Login'
108+
end
109+
end
110+
77111
it "should support flash_error_key and flash_notice_key" do
78112
rodauth do
79113
enable :login
@@ -910,7 +944,7 @@ def foo
910944
auth = nil
911945
rodauth do
912946
enable :login
913-
template_opts(:locals=>{a: 1})
947+
template_opts(:locals=>{a: 1}, :template_opts=>{:fixed_locals=>false})
914948
end
915949
roda(:no_csrf) do |r|
916950
r.rodauth

spec/spec_helper.rb

+6-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,12 @@ def roda(type=nil, &block)
217217
app.opts[:verbatim_string_matcher] = true
218218
rodauth_block = @rodauth_block
219219
opts = rodauth_opts(type)
220-
app.plugin :render, :template_opts=>{:freeze => true} if ENV['RODAUTH_TEMPLATE_FREEZE']
220+
template_opts = {}
221+
template_opts[:freeze] = true if ENV['RODAUTH_TEMPLATE_FREEZE']
222+
if Tilt::Template.method_defined?(:fixed_locals?) && defined?(Roda::RodaPlugins::Render::FIXED_LOCALS_COMPILED_METHOD_SUPPORT)
223+
template_opts[:default_fixed_locals] = '()'
224+
end
225+
app.plugin :render, :template_opts=>template_opts
221226

222227
if json || jwt
223228
opts[:json] = jwt_only ? :only : true

0 commit comments

Comments
 (0)