hanami-view 3.0.0.rc1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ab1223361a1dd1e27cda821d93b04857383189680e9eb2936011ae18119a3b98
4
- data.tar.gz: 10d4f6e9057266613cdd392a0daa16d4aa130cffdafda095e393fa1260a28e3e
3
+ metadata.gz: cfd4f5b396df91cbef8969c45d2619115365a83856411998e92f9bf9ba35d027
4
+ data.tar.gz: fd73d60f403a32f11a4261caf786dc33ba7f53c891edbf50dfcfe44f2445fb5c
5
5
  SHA512:
6
- metadata.gz: 2bb9ee14ae0cb4c446c80e24ee36a6f73a21baf95bc41face07aeb694014f74bed5e8ef1dfa8ec827de1f2a74acf3248cfdfd4c99ece34bcbb014c3a2f4bfddd
7
- data.tar.gz: 33310b9d1de7704edcf2db34c401e310b18649a4d41f6bf8d5320c73842a46d545c9be9e43b9347634d2c9e635fc7d752f55b4630bd262091da43c1afffb4c29
6
+ metadata.gz: c7958b7d98292e6595c0abde96ce7ba136d2ac75d2036d415668ded39a6a44435349b5fa6ea0bf87486e3a7c55ff54bce5be971a62bc7b70e5d2cad18dad4ff9
7
+ data.tar.gz: 4baa7d74944594e1af1357ed042b1cae7cc1577200e026f9da575142ac199824dece54a67158bf1a3e1f1a698ac72774e01433d20052d306fa8d3a0a670d08e4
data/CHANGELOG.md CHANGED
@@ -19,7 +19,45 @@ and this project adheres to [Break Versioning](https://www.taoensso.com/break-ve
19
19
 
20
20
  ### Security
21
21
 
22
- [Unreleased]: https://github.com/hanami/view/compare/v3.0.0.rc1...HEAD
22
+ [Unreleased]: https://github.com/hanami/view/compare/v3.0.1...HEAD
23
+
24
+ ## [3.0.1] - 2026-08-14
25
+
26
+ ### Fixed
27
+
28
+ - Report the calling template as the current template name inside blocks passed to `render`, instead of the partial the block is yielded into. (@timriley in #281)
29
+ - Look up bare-named partials in the directory containing the template that renders them, instead of a same-named directory at the root. (@timriley in #282)
30
+
31
+ Previously, a partial rendered via a relative path (e.g. `render("shared/fields")` from `posts/show`) would look for its own bare-named partials under `shared/` at the root, rather than `posts/shared/`.
32
+
33
+ [3.0.1]: https://github.com/hanami/view/compare/v3.0.0...v3.0.1
34
+
35
+ ## [3.0.0] - 2026-06-30
36
+
37
+ ### Added
38
+
39
+ - Track the currently-rendering template name. (@timriley in #277)
40
+
41
+ Expose this as `Hanami::View::Scope#_template_name` (with `template_name` as a convenience alias) and `Hanami::View::Context#current_template_name`.
42
+
43
+ The name is resolved path of the file actually being rendered, relative to its configured `paths` directory, with format/engine extensions stripped. For example, `render("form")` from inside `posts/show.html.erb` returns `"posts/_form"`; a layout at `layouts/app.html.erb` returns `"layouts/app"`.
44
+
45
+ The current template name can be used to enable such behaviors as lazy/relative key lookups for i18n view helpers.
46
+
47
+ ### Changed
48
+
49
+ - **BREAKING:** Default to undecorated exposures. (@timriley in #274)
50
+
51
+ Decorate your exposures with the new `.decorate` method, or the `decorate: true` option for `.expose`. Default back to decorated exposures via `config.decorate_exposures = true`.
52
+ - Cache the view's resolved configuration as a frozen `Data` snapshot (via dry-configurable's `#to_data`) at initialization, avoiding repeated config lookups on the rendering hot path for improved memory usage and speed. (@cllns in #276)
53
+ - Require Ruby 3.3 or newer.
54
+
55
+ ### Fixed
56
+
57
+ - Allow the gem to be eager loaded by Zeitwerk when the optional haml and slim gems are not installed. (@timriley in #279)
58
+ - Use our own Haml template engine even when the haml gem is required before hanami-view. (@timriley in #279)
59
+
60
+ [3.0.0]: https://github.com/hanami/view/compare/v2.3.1...v3.0.0
23
61
 
24
62
  ## [3.0.0.rc1] - 2026-06-16
25
63
 
@@ -27,9 +65,11 @@ and this project adheres to [Break Versioning](https://www.taoensso.com/break-ve
27
65
 
28
66
  - Track the currently-rendering template name. (@timriley in #277)
29
67
 
30
- Expose the topmost entry as `Hanami::View::Rendering#current_template_name` and the full stack as `#current_template_names`. Entries are the resolved path of the file actually being rendered, relative to its configured `paths` directory, with format/engine extensions stripped. For example, `render("form")` from inside `posts/show.html.erb` reports `"posts/_form"`; a layout at `layouts/app.html.erb` reports `"layouts/app"`.
68
+ Expose this as `Hanami::View::Scope#_template_name` (with `template_name` as a convenience alias) and `Hanami::View::Context#current_template_name`.
69
+
70
+ The name is resolved path of the file actually being rendered, relative to its configured `paths` directory, with format/engine extensions stripped. For example, `render("form")` from inside `posts/show.html.erb` returns `"posts/_form"`; a layout at `layouts/app.html.erb` returns `"layouts/app"`.
31
71
 
32
- Convenience accessors are available as `Hanami::View::Scope#_template_name` (with `template_name` as a convenience alias) and `Hanami::View::Context#current_template_name`. The current template name can be used to enable such behaviors as lazy/relative key lookups for i18n view helpers.
72
+ The current template name can be used to enable such behaviors as lazy/relative key lookups for i18n view helpers.
33
73
 
34
74
  ### Changed
35
75
 
@@ -47,7 +47,7 @@ module Hanami
47
47
  # @return [String, nil]
48
48
  #
49
49
  # @api public
50
- # @since x.x.x
50
+ # @since 3.0.0
51
51
  def current_template_name
52
52
  _rendering.current_template_name
53
53
  end
@@ -16,7 +16,7 @@ module Hanami
16
16
  # rendered, its parent directory (e.g. `"users"` for `"users/index"`) is pushed onto the stack
17
17
  # so that a partial referenced by its bare name (e.g. `render("form")` from inside
18
18
  # `users/index.html.erb`) can be found alongside the template that renders it. The stack is
19
- # snapshot-and-restored around each render via `ensure`.
19
+ # snapshot-and-restored around each render via `ensure`.
20
20
  #
21
21
  # `#lookup` tries every combination of a path and a prefix, joining each pair with the
22
22
  # requested name to find a matching file. `paths` are checked in configured order; an earlier
@@ -48,20 +48,21 @@ module Hanami
48
48
 
49
49
  def template(name, format, scope, &block)
50
50
  old_prefixes = @prefixes.dup
51
+ old_template_names = @current_template_names
51
52
 
52
53
  result = lookup(name, format)
53
54
  raise TemplateNotFoundError.new(name, format, config_data.paths) unless result
54
55
 
55
56
  template_path, relative_path = result
56
57
 
57
- new_prefix = File.dirname(name)
58
+ new_prefix = File.dirname(relative_path)
58
59
  @prefixes << new_prefix unless @prefixes.include?(new_prefix)
59
- @current_template_names << resolve_template_name(relative_path)
60
+ @current_template_names = old_template_names + [resolve_template_name(relative_path)]
60
61
 
61
- render(template_path, scope, &block)
62
+ render(template_path, scope, &yielded_block(block, old_template_names))
62
63
  ensure
63
64
  @prefixes = old_prefixes
64
- @current_template_names.pop if result
65
+ @current_template_names = old_template_names
65
66
  end
66
67
 
67
68
  def partial(name, format, scope, &block)
@@ -107,6 +108,28 @@ module Hanami
107
108
  }
108
109
  end
109
110
 
111
+ # Wraps a block yielded into a template so that, while it runs, `#current_template_name`
112
+ # reports the template that _wrote_ the block, not the one yielding to it.
113
+ #
114
+ # A block passed to `render` is written inside the calling template, so its contents belong to
115
+ # that template even though they're evaluated during the rendering of another.
116
+ #
117
+ # @return [Proc, nil]
118
+ def yielded_block(block, caller_template_names)
119
+ return nil unless block
120
+
121
+ proc { |*args|
122
+ yielding_template_names = @current_template_names
123
+ @current_template_names = caller_template_names
124
+
125
+ begin
126
+ block.call(*args)
127
+ ensure
128
+ @current_template_names = yielding_template_names
129
+ end
130
+ }
131
+ end
132
+
110
133
  # Derives the rendered template's name from its relative path, suitable for tracking on
111
134
  # `@current_template_names` and surfacing via `#current_template_name`.
112
135
  #
@@ -37,9 +37,6 @@ module Hanami
37
37
  # no render is in progress.
38
38
  #
39
39
  # @return [String, nil]
40
- #
41
- # @api public
42
- # @since x.x.x
43
40
  def current_template_name
44
41
  renderer.current_template_name
45
42
  end
@@ -48,9 +45,6 @@ module Hanami
48
45
  # rendered.
49
46
  #
50
47
  # @return [Array<String>]
51
- #
52
- # @api private
53
- # @since x.x.x
54
48
  def current_template_names
55
49
  renderer.current_template_names
56
50
  end
@@ -157,7 +157,7 @@ module Hanami
157
157
  # @return [String, nil]
158
158
  #
159
159
  # @api public
160
- # @since x.x.x
160
+ # @since 3.0.0
161
161
  def _template_name
162
162
  _rendering.current_template_name
163
163
  end
@@ -10,14 +10,24 @@ module Hanami
10
10
  # @api private
11
11
  # @since 2.1.0
12
12
  Mapping = ::Tilt.default_mapping.dup.tap { |mapping|
13
- # If "slim" has been required before "hanami/view", unregister Slim's non-lazy registered
14
- # template, so our own template adapter (using register_lazy below) can take precedence.
15
- mapping.unregister "slim"
13
+ # Unregister any existing mappings for the extensions we provide our own engines for.
14
+ #
15
+ # Tilt preferences non-lazy registrations over lazy ones (see `Tilt::Mapping#lookup`). So if
16
+ # "haml" or "slim" has been required before this mapping is built (each of which registers
17
+ # its own non-lazy mapping with Tilt), our own lazy-registered adapters below would be
18
+ # shadowed and never picked up, and templates would render without our specific required
19
+ # behavior.
20
+ #
21
+ # Unregistering first ensures our engines are always used, regardless of load order.
22
+ mapping.unregister "erb", "rhtml", "haml", "slim"
16
23
 
17
24
  # Register our own ERB template.
18
25
  mapping.register_lazy "Hanami::View::ERB::Template", "hanami/view/erb/template", "erb", "rhtml"
19
26
 
20
- # Register ERB templates for Haml and Slim that set the `use_html_safe: true` option.
27
+ # Register templates for Haml and Slim that set the `use_html_safe: true` option.
28
+ #
29
+ # We register these lazily so that the optional "haml" and "slim" gems only need to be
30
+ # installed when their templates are actually used.
21
31
  #
22
32
  # Our template namespaces below have the "Adapter" suffix to work around a bug in Tilt's
23
33
  # `Mapping#const_defined?`, which (if slim was already required) would receive
@@ -3,6 +3,6 @@
3
3
  module Hanami
4
4
  class View
5
5
  # @api public
6
- VERSION = "3.0.0.rc1"
6
+ VERSION = "3.0.1"
7
7
  end
8
8
  end
data/lib/hanami/view.rb CHANGED
@@ -30,7 +30,12 @@ module Hanami
30
30
  loader.ignore(
31
31
  "#{root}/hanami-view.rb",
32
32
  "#{root}/hanami/view/version.rb",
33
- "#{root}/hanami/view/errors.rb"
33
+ "#{root}/hanami/view/errors.rb",
34
+ # These adapters require the optional "haml" and "slim" gems. They are loaded lazily by
35
+ # Tilt (see Hanami::View::Tilt) only when their respective template engines are used;
36
+ # ignore them here to allow eager loading without those gems installed.
37
+ "#{root}/hanami/view/tilt/haml_adapter.rb",
38
+ "#{root}/hanami/view/tilt/slim_adapter.rb"
34
39
  )
35
40
  loader.inflector = Zeitwerk::GemInflector.new("#{root}/hanami-view.rb")
36
41
  loader.inflector.inflect(
@@ -246,7 +251,7 @@ module Hanami
246
251
  #
247
252
  # @param value [Boolean] whether to decorate exposures by default
248
253
  # @api public
249
- # @since x.x.x
254
+ # @since 3.0.0
250
255
  # @!scope class
251
256
  setting :decorate_exposures, default: false
252
257
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-view
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.rc1
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hanakai team