roda 2.28.0 → 2.29.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +46 -0
  3. data/README.rdoc +25 -7
  4. data/doc/release_notes/2.29.0.txt +156 -0
  5. data/lib/roda.rb +25 -3
  6. data/lib/roda/plugins/_erubis_escaping.rb +2 -0
  7. data/lib/roda/plugins/_symbol_regexp_matchers.rb +22 -0
  8. data/lib/roda/plugins/assets.rb +3 -2
  9. data/lib/roda/plugins/branch_locals.rb +74 -0
  10. data/lib/roda/plugins/caching.rb +15 -7
  11. data/lib/roda/plugins/chunked.rb +10 -7
  12. data/lib/roda/plugins/content_for.rb +4 -1
  13. data/lib/roda/plugins/drop_body.rb +3 -2
  14. data/lib/roda/plugins/error_email.rb +3 -2
  15. data/lib/roda/plugins/error_mail.rb +3 -2
  16. data/lib/roda/plugins/head.rb +2 -1
  17. data/lib/roda/plugins/header_matchers.rb +3 -0
  18. data/lib/roda/plugins/heartbeat.rb +3 -2
  19. data/lib/roda/plugins/json.rb +5 -3
  20. data/lib/roda/plugins/json_parser.rb +3 -2
  21. data/lib/roda/plugins/mailer.rb +3 -3
  22. data/lib/roda/plugins/match_affix.rb +6 -0
  23. data/lib/roda/plugins/multi_route.rb +3 -1
  24. data/lib/roda/plugins/padrino_render.rb +3 -2
  25. data/lib/roda/plugins/params_capturing.rb +3 -3
  26. data/lib/roda/plugins/partials.rb +3 -3
  27. data/lib/roda/plugins/path.rb +4 -2
  28. data/lib/roda/plugins/path_rewriter.rb +2 -2
  29. data/lib/roda/plugins/per_thread_caching.rb +2 -0
  30. data/lib/roda/plugins/placeholder_string_matchers.rb +42 -0
  31. data/lib/roda/plugins/precompile_templates.rb +3 -2
  32. data/lib/roda/plugins/render.rb +86 -37
  33. data/lib/roda/plugins/render_each.rb +2 -1
  34. data/lib/roda/plugins/render_locals.rb +102 -0
  35. data/lib/roda/plugins/run_append_slash.rb +2 -1
  36. data/lib/roda/plugins/run_handler.rb +2 -1
  37. data/lib/roda/plugins/sinatra_helpers.rb +4 -4
  38. data/lib/roda/plugins/static_path_info.rb +2 -0
  39. data/lib/roda/plugins/static_routing.rb +1 -1
  40. data/lib/roda/plugins/streaming.rb +9 -4
  41. data/lib/roda/plugins/symbol_matchers.rb +23 -20
  42. data/lib/roda/plugins/view_options.rb +63 -28
  43. data/lib/roda/plugins/view_subdirs.rb +1 -0
  44. data/lib/roda/plugins/websockets.rb +2 -0
  45. data/lib/roda/version.rb +1 -1
  46. data/spec/composition_spec.rb +2 -2
  47. data/spec/matchers_spec.rb +6 -5
  48. data/spec/plugin/_erubis_escaping_spec.rb +5 -5
  49. data/spec/plugin/backtracking_array_spec.rb +0 -2
  50. data/spec/plugin/branch_locals_spec.rb +88 -0
  51. data/spec/plugin/content_for_spec.rb +8 -2
  52. data/spec/plugin/halt_spec.rb +8 -0
  53. data/spec/plugin/header_matchers_spec.rb +20 -5
  54. data/spec/plugin/multi_route_spec.rb +1 -1
  55. data/spec/plugin/named_templates_spec.rb +2 -2
  56. data/spec/plugin/params_capturing_spec.rb +1 -1
  57. data/spec/plugin/per_thread_caching_spec.rb +1 -1
  58. data/spec/plugin/placeholder_string_matchers_spec.rb +159 -0
  59. data/spec/plugin/render_locals_spec.rb +114 -0
  60. data/spec/plugin/render_spec.rb +83 -8
  61. data/spec/plugin/streaming_spec.rb +104 -4
  62. data/spec/plugin/symbol_matchers_spec.rb +1 -1
  63. data/spec/plugin/view_options_spec.rb +83 -7
  64. data/spec/plugin/websockets_spec.rb +7 -8
  65. data/spec/spec_helper.rb +22 -2
  66. metadata +11 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ca75e717d558d6b3c163517c6e8e3678a33b68e0
4
- data.tar.gz: a08ab3922fc609e9413f6151444bc9a92186777e
3
+ metadata.gz: e11c20c0c5dfda417dafc01b68c10915e59abf04
4
+ data.tar.gz: edd6bd09207b2f8e15f78b9c9ada35285003ff0d
5
5
  SHA512:
6
- metadata.gz: 29684100b4d5dd39d11e034a9158442b9e7379c11fe8c0169033fab127394855e79016aa0101f7abdb79cc544dbfcedc98c0fa3fd6fad7559678ab43f69b9dbe
7
- data.tar.gz: 77d6d7bb57535d375a46103b4ba5f803231172ecf6b98cdc3ebba85600be1e02dfe06dc907758ffbdbe6123911f436e15fbf87fe3c2a4f2d4a0742a36af94471
6
+ metadata.gz: a82a396922fc18b9d69551ff405cade3d51e09d5eb518c70bc3166b4214d70692412f91e59c4e31a9fec84e948c93bec3a1a7a066584bd1c5585b39fc57b2c15
7
+ data.tar.gz: 4690e25684a1264e29c3c60426263a5631716080de3e699785e193bd96868a9c4788b8aa17ca97fbecacf1db96a39146bb33bc0db23e1398c8d79c2ab3ab34da
data/CHANGELOG CHANGED
@@ -1,3 +1,49 @@
1
+ = 2.29.0 (2017-08-16)
2
+
3
+ * Deprecate accessing multi_route namespace when there are no routes (jeremyevans)
4
+
5
+ * Deprecate additional internal constants (jeremyevans)
6
+
7
+ * Respect :root app option when using :layout_opts=>:views render plugin option (jeremyevans)
8
+
9
+ * Deprecate rendering templates outside of render plugin :allowed_paths option by default (jeremyevans)
10
+
11
+ * Deprecate :cache=>nil/false render plugin option overriding :cache render/view method option (jeremyevans)
12
+
13
+ * Deprecate using :header matcher in header_matchers plugin without :header_matcher_prefix app option (jeremyevans)
14
+
15
+ * Deprecate using content_for multiple times with the same key in the content_for plugin unless :append plugin option is used (jeremyevans)
16
+
17
+ * Deprecate use of :host matcher with regexp value in header_matchers plugin without :host_matcher_captures app option (jeremyevans)
18
+
19
+ * Deprecate view_options plugin locals handling, move to the new branch_locals plugin (jeremyevans)
20
+
21
+ * Deprecate render plugin locals handling, move to the new render_locals plugin (jeremyevans)
22
+
23
+ * Deprecate the :ext render method and plugin option (jeremyevans)
24
+
25
+ * Deprecate the view_subdirs plugin alias for the view_options plugin (jeremyevans)
26
+
27
+ * Deprecate Stream#callback in the streaming plugin (jeremyevans)
28
+
29
+ * Deprecate the automatic support for EventMachine in the streaming plugin (jeremyevans)
30
+
31
+ * Deprecate static_path_info plugin, which has been a no-op in Roda 2 (jeremyevans)
32
+
33
+ * Deprecate render plugin :escape option loading Erubis escaping support (jeremyevans)
34
+
35
+ * Deprecate the per_thread_caching plugin (jeremyevans)
36
+
37
+ * Deprecate the websockets plugin (jeremyevans)
38
+
39
+ * Deprecate treating unsupported matchers as always matching (jeremyevans)
40
+
41
+ * Deprecate ignoring unsupported match block return values (jeremyevans)
42
+
43
+ * Deprecate the :format, :opt, and :optd default symbol matchers in the symbol_matchers plugin (jeremyevans)
44
+
45
+ * Deprecate use of placeholders in string matchers by default, add placeholder_string_matchers plugin for it (jeremyevans)
46
+
1
47
  = 2.28.0 (2017-07-14)
2
48
 
3
49
  * Deprecate unneeded internal constants (jeremyevans)
data/README.rdoc CHANGED
@@ -285,7 +285,7 @@ If a string contains any slashes, it matches one additional segment for each sla
285
285
  "foo/bar" # matches "/foo/bar"
286
286
  "foo/bar" # does not match "/foo/bard"
287
287
 
288
- For backwards compatibility, if a string contains a colon followed by any
288
+ While deprecated by default, if a string contains a colon followed by any
289
289
  <tt>\\w</tt> characters, the colon and remaining <tt>\\w</tt> characters match any
290
290
  nonempty segment that contains at least one character:
291
291
 
@@ -303,8 +303,9 @@ symbol arguments, as it is faster and simpler:
303
303
  "foo", String # instead of "foo/:id"
304
304
  String, String # instead of ":x/:y"
305
305
 
306
- It is possible in future versions of Roda, colons will not be treated specially
307
- in strings, and will just match a literal colon character.
306
+ You can load the placeholder_string_matchers plugin to allow placeholders in
307
+ strings without a deprecation warning. The deprecated default handling of placeholders
308
+ in strings will be removed in Roda 3.
308
309
 
309
310
  Note that other than colons followed by a <tt>\\w</tt> character, strings do no
310
311
  handle regular expression syntax, they are matched verbatim:
@@ -437,9 +438,8 @@ If +false+ or +nil+ is given directly as a matcher, it doesn't match anything.
437
438
 
438
439
  === Everything else
439
440
 
440
- Everything else matches anything. Note that future versions of Roda will probably
441
- raise exceptions for unsupported matchers, so it is not recommended to rely on this
442
- behavior.
441
+ Everything else matches anything, but such usage is deprecated. In Roda 3, using
442
+ an unsupported matcher will raise an error.
443
443
 
444
444
  == Optional segments
445
445
 
@@ -485,7 +485,25 @@ An alternative way to implement this is via a regexp:
485
485
  r.is "items", /(\d+)(?:\/(\d+))?/ do |item_id, optional_data|
486
486
  end
487
487
 
488
- == Status codes
488
+ == Match/Route Block Return Values
489
+
490
+ If the response body has already been written to by calling +response.write+
491
+ directly, then any return value of a match block or route block is ignored.
492
+
493
+ If the response body has not already been written to, then the match block
494
+ or route block return value is inspected:
495
+
496
+ String :: used as the response body
497
+ nil, false :: ignored
498
+ everything else :: also ignored, but this is deprecated and will raise an
499
+ error starting in Roda 3
500
+
501
+ Plugins can add support for additional match block and route block return
502
+ values. One example of this is the json plugin, which allows returning
503
+ arrays and hashes in match and route blocks and converts those directly
504
+ to JSON and uses the JSON as the response body.
505
+
506
+ == Status Codes
489
507
 
490
508
  When it comes time to finalize a response,
491
509
  if a status code has not been set manually and anything has been written to the response,
@@ -0,0 +1,156 @@
1
+ = Deprecated Features
2
+
3
+ Roda 2.29.0 will be the last minor release of Roda 2. Roda 3.0.0
4
+ will be released next month and will remove support for the following
5
+ deprecated features. All of these features will have deprecation
6
+ warnings if used in Roda 2.29.0.
7
+
8
+ * The use of placeholders in string matchers is now deprecated.
9
+ So code such as:
10
+
11
+ r.get "users/:user_id" do |id|
12
+ end
13
+
14
+ should be switched to using a class matcher such as String or
15
+ Integer:
16
+
17
+ r.get "users", Integer do |id|
18
+ end
19
+
20
+ or a symbol matcher:
21
+
22
+ r.get "users", :user_id do |id|
23
+ end
24
+
25
+ If you really want to keep support for placeholders in string
26
+ matchers, the support is available in the new
27
+ placeholder_string_matchers plugin.
28
+
29
+ * The :format, :opt, and :optd default symbol matchers are now
30
+ deprecated in the symbol_matchers plugin. These matchers
31
+ only made sense when placeholder string matchers are used,
32
+ which will no longer be the default behavior in Roda 3. These
33
+ methods can be defined manually if you are going to use the
34
+ placeholder_string_matchers plugin and still want to use
35
+ these symbol matchers:
36
+
37
+ symbol_matcher(:format, /(?:\.(\w+))?/)
38
+ symbol_matcher(:opt, /(?:\/([^\/]+))?/)
39
+ symbol_matcher(:optd, /(?:\/(\d+))?/)
40
+
41
+ * Ignoring unsupported match block return values is now deprecated.
42
+ Doing so can hide errors and make debugging more difficult. If you
43
+ get a deprecation warning related to this, just make sure the match
44
+ block returns nil or false to specify the match block return value
45
+ should be ignored.
46
+
47
+ * Treating unsupported matchers as always matching is now deprecated.
48
+ Doing so can hide errors and make debugging more difficult. If you
49
+ get a deprecation warning related to this, switch the matcher to
50
+ true instead of an unsupported object.
51
+
52
+ * The render plugin's handling of plugin level locals and merging of
53
+ template and layout locals is now deprecated. Users of these
54
+ features should switch to the new render_locals plugin.
55
+
56
+ * The view_options plugin's handling of per-branch view and layout
57
+ locals is now deprecated. Users of these feature should switch to
58
+ the new branch_locals plugin.
59
+
60
+ * The render plugin's support for Erubis escaping is now deprecated.
61
+ In Roda 3, the render plugin :escape option will use Erubi escaping.
62
+ Switch to using :escape=>:erubi temporarily to avoid the deprecation
63
+ warning.
64
+
65
+ * Using the render plugin to render a template that is outside one of
66
+ the allowed paths is now deprecated unless the :check_paths option
67
+ has been set to false. In Roda 3, the default behavior will change
68
+ to checking that template files are in one of the allowed paths.
69
+
70
+ * The :ext option in the render plugin is now deprecated, users should
71
+ switch to using the :engine option, which has always had priority.
72
+
73
+ * Using the :cache=>true option to the view/render method in the
74
+ render plugin is now deprecated if the :cache=>nil/false option
75
+ was given when loading the plugin. In Roda 3, the default behavior
76
+ will change so that the :cache=>nil/false plugin option still
77
+ allows caching via the :cache=>true method option. Users can use
78
+ the :explicit_cache=>true render plugin option instead of the
79
+ :cache=>nil render plugin option to work around the deprecation
80
+ warning.
81
+
82
+ * Attempting to use multi_route while routing with a namespace that
83
+ hasn't yet been defined is now deprecated. The previous behavior
84
+ was to ignore undefined namespaces, but that is more likely to
85
+ hide an error than be desired behavior. In Roda 3, using an
86
+ undefined namespace will raise an error.
87
+
88
+ * The streaming plugin's support for EventMachine is now deprecated,
89
+ as is related support for Stream#callback. The streaming plugin
90
+ will be much simpler in Roda 3 by dropping this support.
91
+
92
+ * Calling content_for in the content_for plugin multiple times with
93
+ the same argument is now deprecated unless the content_for
94
+ plugin :append option is used to specify behavior. The default
95
+ behavior in Roda 3 will change to appending to the existing
96
+ content instead of overwriting the existing content.
97
+
98
+ * The :host matcher in the header_matchers plugin is now deprecated
99
+ when using a regexp value unless the :host_matcher_captures app
100
+ option is used. In Roda 3, the :host matcher will automatically
101
+ yield any regexp captures to the match block.
102
+
103
+ * The :header matcher in the header_matchers plugin is now deprecated
104
+ unless the :header_matcher_prefix app option is used. In Roda 3,
105
+ the :header matcher will always prefix the argument given with
106
+ HTTP_.
107
+
108
+ * The websockets plugin is now deprecated. It was one of the less
109
+ commonly used plugins, and the tests for it were subject to race
110
+ conditions and failed occassionally, and even when they worked
111
+ they almost doubled the testing time. Anyone wanting to use it
112
+ should consider maintaining it as an external plugin.
113
+
114
+ * The per_thread_caching, static_path_info, and view_subdirs
115
+ plugins are now deprecated. static_path_info has been a no-op since
116
+ Roda 3, view_subdirs is just an alias for view_options, and
117
+ per_thread_caching doesn't change behavior and is unlikely to
118
+ significantly increase performance.
119
+
120
+ * Additional internal constants are now deprecated. Deprecation
121
+ warnings for accessing these constants will only be displayed on
122
+ ruby 2.3+.
123
+
124
+ = Forward Compatibility
125
+
126
+ Roda 3.0.0 will also include some behavior changes which will not
127
+ have deprecation warnings:
128
+
129
+ * Ruby 1.8.7 support will be dropped. Ruby 1.9.2 will be the new
130
+ minimum supported version.
131
+
132
+ * Subclassing a Roda app that uses the render plugin will always
133
+ use a copy of the superclass's template cache.
134
+
135
+ * The assets plugin will default to using subresource integrity
136
+ using SHA256 for compiled assets, and using SHA256 instead of
137
+ SHA1 for compiled asset hashes.
138
+
139
+ * Using an Roda app as middleware will now always use a subclass
140
+ of the app for the middleware.
141
+
142
+ * public_send will be used instead of send internally unless it is
143
+ expected that private methods will be called.
144
+
145
+ * The match methods added by the symbol_matchers and hash_matchers
146
+ plugins will be private instead of public.
147
+
148
+ = New Features
149
+
150
+ * The render plugin now has the :layout_opts=>:views plugin option
151
+ respect the :root app option.
152
+
153
+ * RodaPlugins::OPTS and RodaPlugins::EMPTY_ARRAY have been added.
154
+ These are a frozen empty hash and a frozen empty array, and
155
+ they are designed for use in plugins so that similar objects are
156
+ not needed to be defined separately in each plugin.
data/lib/roda.rb CHANGED
@@ -65,9 +65,19 @@ class Roda
65
65
  # Module in which all Roda plugins should be stored. Also contains logic for
66
66
  # registering and loading plugins.
67
67
  module RodaPlugins
68
+ OPTS = {}.freeze
69
+ EMPTY_ARRAY = [].freeze
70
+
68
71
  # Stores registered plugins
69
72
  @plugins = RodaCache.new
70
73
 
74
+ class << self
75
+ # Make warn a public method, as it is used for deprecation warnings.
76
+ # Roda::RodaPlugins.warn can be overridden for custom handling of
77
+ # deprecation warnings.
78
+ public :warn
79
+ end
80
+
71
81
  # If the registered plugin already exists, use it. Otherwise,
72
82
  # require it and return it. This raises a LoadError if such a
73
83
  # plugin doesn't exist, or a RodaError if it exists but it does
@@ -740,7 +750,16 @@ class Roda
740
750
  # colon tokens for placeholders.
741
751
  def _match_string(str)
742
752
  if str.index(":") && placeholder_string_matcher?
743
- consume(self.class.cached_matcher(str){Regexp.escape(str).gsub(/:(\w+)/){|m| _match_symbol_regexp($1)}})
753
+ # RODA3: Remove
754
+ not_warned = true
755
+ consume(self.class.cached_matcher(str){Regexp.escape(str).gsub(/:(\w+)/) do |m|
756
+ match = $1
757
+ if not_warned
758
+ nor_warned = false
759
+ RodaPlugins.warn("Placeholder symbol matchers are deprecated by default and will be removed in Roda 3 (matcher used: #{str.inspect}). Use the placeholder_symbol_matchers plugin or split the string and use separate symbol matchers or String class matchers for the placeholders")
760
+ end
761
+ _match_symbol_regexp(match)
762
+ end})
744
763
  else
745
764
  rp = @remaining_path
746
765
  if rp.start_with?("/#{str}")
@@ -752,6 +771,7 @@ class Roda
752
771
  @remaining_path = ""
753
772
  when Integer
754
773
  # :nocov:
774
+ # RODA3: Remove
755
775
  # Ruby 1.8 support
756
776
  if rp[last].chr == "/"
757
777
  @remaining_path = rp[last, rp.length]
@@ -781,8 +801,7 @@ class Roda
781
801
  # Match any nonempty segment. This should be called without an argument.
782
802
  alias _match_class_String _match_symbol
783
803
 
784
- # The regular expression to use for matching symbols. By default, any non-empty
785
- # segment matches.
804
+ # RODA3: Remove
786
805
  def _match_symbol_regexp(s)
787
806
  "([^\\/]+)"
788
807
  end
@@ -821,6 +840,8 @@ class Roda
821
840
  else
822
841
  if roda_class.opts[:unsupported_block_result] == :raise
823
842
  raise RodaError, "unsupported block result: #{result.inspect}"
843
+ else
844
+ RodaPlugins.warn("Unsupported match block return result: #{result.inspect}. This is currently ignored, but will raise an error in Roda 3. Have the block return nil or false to ignore the result.")
824
845
  end
825
846
  end
826
847
  end
@@ -933,6 +954,7 @@ class Roda
933
954
  if roda_class.opts[:unsupported_matcher] == :raise
934
955
  raise RodaError, "unsupported matcher: #{matcher.inspect}"
935
956
  end
957
+ RodaPlugins.warn("Unsupported matcher used: #{matcher.inspect}. This currently always matches, but will raise an error in Roda 3. Switch to using true if you want the matcher to always match.")
936
958
  matcher
937
959
  end
938
960
  end
@@ -4,6 +4,8 @@ require 'erubis'
4
4
 
5
5
  class Roda
6
6
  module RodaPlugins
7
+ warn 'Using the render plugin :escape option for Erubis escaping support is deprecated. In Roda 3, the :escape option will use Erubi escaping support. You can turn on the Roda 3 behavior by using :escape=>:erubi.'
8
+
7
9
  # The _erubis_escaping plugin handles escaping of <tt><%= %></tt> inside
8
10
  # ERB templates. It is an internal plugin that should not be loaded
9
11
  # directlyn by user code.
@@ -0,0 +1,22 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The _symbol_regexp_matchers plugin is designed for internal use by other plugins,
7
+ # for the historical behavior of a symbol matching an arbitrary segment by default
8
+ # using a regexp.
9
+ module SymbolRegexpMatchers
10
+ module RequestMethods
11
+ # The regular expression to use for matching symbols. By default, any non-empty
12
+ # segment matches.
13
+ def _match_symbol_regexp(s)
14
+ "([^\\/]+)"
15
+ end
16
+ end
17
+ end
18
+
19
+ register_plugin(:_symbol_regexp_matchers, SymbolRegexpMatchers)
20
+ end
21
+ end
22
+
@@ -306,8 +306,9 @@ class Roda
306
306
  :compiled_css_dir => nil,
307
307
  :compiled_js_dir => nil,
308
308
  }.freeze
309
- EMPTY_ATTRS = {}.freeze
310
309
 
310
+ EMPTY_ATTRS = {}.freeze
311
+ RodaPlugins.deprecate_constant(self, :EMPTY_ATTRS)
311
312
  JS_END = "\"></script>".freeze
312
313
  RodaPlugins.deprecate_constant(self, :JS_END)
313
314
  CSS_END = "\" />".freeze
@@ -656,7 +657,7 @@ class Roda
656
657
  # When the assets are not compiled, this will result in a separate
657
658
  # tag for each asset file. When the assets are compiled, this will
658
659
  # result in a single tag to the compiled asset file.
659
- def assets(type, attrs = EMPTY_ATTRS)
660
+ def assets(type, attrs = OPTS)
660
661
  ltype = type.is_a?(Array) ? type[0] : type
661
662
 
662
663
  o = self.class.assets_opts
@@ -0,0 +1,74 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The branch_locals plugin allows you to override view and layout
7
+ # locals for specific branches and routes.
8
+ #
9
+ # plugin :render
10
+ # plugin :render_locals, :render=>{:footer=>'Default'}, :layout=>{:title=>'Main'}
11
+ # plugin :branch_locals
12
+ #
13
+ # route do |r|
14
+ # r.on "users" do
15
+ # set_layout_locals :title=>'Users'
16
+ # set_view_locals :footer=>'(c) Roda'
17
+ # end
18
+ # end
19
+ #
20
+ # The locals you specify in the set_layout_locals and set_view_locals methods
21
+ # have higher precedence than the render_locals plugin options, but lower precedence
22
+ # than options you directly pass to the view/render methods.
23
+ module BranchLocals
24
+ # Load the render_locals plugin before this plugin, since this plugin
25
+ # works by overriding methods in the render_locals plugin.
26
+ def self.load_dependencies(app)
27
+ app.plugin :render_locals
28
+ end
29
+
30
+ module InstanceMethods
31
+ # Update the default layout locals to use in this branch.
32
+ def set_layout_locals(opts)
33
+ if locals = @_layout_locals
34
+ @_layout_locals = Hash[locals].merge!(opts)
35
+ else
36
+ @_layout_locals = opts
37
+ end
38
+ end
39
+
40
+ # Update the default view locals to use in this branch.
41
+ def set_view_locals(opts)
42
+ if locals = @_view_locals
43
+ @_view_locals = Hash[locals].merge!(opts)
44
+ else
45
+ @_view_locals = opts
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ # Make branch specific view locals override render_locals plugin defaults.
52
+ def render_locals
53
+ locals = super
54
+ if @_view_locals
55
+ locals = Hash[locals].merge!(@_view_locals)
56
+ end
57
+ locals
58
+ end
59
+
60
+ # Make branch specific layout locals override render_locals plugin defaults.
61
+ def layout_locals
62
+ locals = super
63
+ if @_view_locals
64
+ locals = Hash[locals].merge!(@_layout_locals)
65
+ end
66
+ locals
67
+ end
68
+ end
69
+ end
70
+
71
+ register_plugin(:branch_locals, BranchLocals)
72
+ end
73
+ end
74
+