hanami-view 2.0.0.alpha8 → 2.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/README.md +15 -3
  4. data/hanami-view.gemspec +5 -3
  5. data/lib/hanami/view/cache.rb +16 -0
  6. data/lib/hanami/view/context.rb +15 -55
  7. data/lib/hanami/view/context_helpers/content_helpers.rb +5 -5
  8. data/lib/hanami/view/decorated_attributes.rb +2 -2
  9. data/lib/hanami/view/erb/engine.rb +27 -0
  10. data/lib/hanami/view/erb/filters/block.rb +44 -0
  11. data/lib/hanami/view/erb/filters/trimming.rb +42 -0
  12. data/lib/hanami/view/erb/parser.rb +161 -0
  13. data/lib/hanami/view/erb/template.rb +30 -0
  14. data/lib/hanami/view/errors.rb +8 -2
  15. data/lib/hanami/view/exposure.rb +23 -17
  16. data/lib/hanami/view/exposures.rb +22 -13
  17. data/lib/hanami/view/helpers/escape_helper.rb +221 -0
  18. data/lib/hanami/view/helpers/number_formatting_helper.rb +182 -0
  19. data/lib/hanami/view/helpers/tag_helper/tag_builder.rb +230 -0
  20. data/lib/hanami/view/helpers/tag_helper.rb +210 -0
  21. data/lib/hanami/view/html.rb +104 -0
  22. data/lib/hanami/view/html_safe_string_buffer.rb +46 -0
  23. data/lib/hanami/view/part.rb +13 -15
  24. data/lib/hanami/view/part_builder.rb +68 -108
  25. data/lib/hanami/view/path.rb +4 -31
  26. data/lib/hanami/view/renderer.rb +36 -44
  27. data/lib/hanami/view/rendering.rb +42 -0
  28. data/lib/hanami/view/{render_environment_missing.rb → rendering_missing.rb} +8 -13
  29. data/lib/hanami/view/scope.rb +14 -15
  30. data/lib/hanami/view/scope_builder.rb +42 -78
  31. data/lib/hanami/view/tilt/haml_adapter.rb +40 -0
  32. data/lib/hanami/view/tilt/slim_adapter.rb +40 -0
  33. data/lib/hanami/view/tilt.rb +22 -46
  34. data/lib/hanami/view/version.rb +1 -1
  35. data/lib/hanami/view.rb +53 -91
  36. metadata +64 -26
  37. data/LICENSE +0 -20
  38. data/lib/hanami/view/render_environment.rb +0 -62
  39. data/lib/hanami/view/tilt/erb.rb +0 -26
  40. data/lib/hanami/view/tilt/erbse.rb +0 -21
  41. data/lib/hanami/view/tilt/haml.rb +0 -26
@@ -1,69 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "dry/core/cache"
4
3
  require "tilt"
5
4
 
6
5
  module Hanami
7
6
  class View
8
7
  # @api private
9
8
  module Tilt
10
- extend Dry::Core::Cache
9
+ Mapping = ::Tilt.default_mapping.dup.tap { |mapping|
10
+ # If "slim" has been required before "hanami/view", unregister Slim's non-lazy registered
11
+ # template, so our own template adapter (using register_lazy below) can take precedence.
12
+ mapping.unregister "slim"
13
+
14
+ # Register our own ERB template.
15
+ mapping.register_lazy "Hanami::View::ERB::Template", "hanami/view/erb/template", "erb", "rhtml"
16
+
17
+ # Register ERB templates for Haml and Slim that set the `use_html_safe: true` option.
18
+ #
19
+ # Our template namespaces below have the "Adapter" suffix to work around a bug in Tilt's
20
+ # `Mapping#const_defined?`, which (if slim was already required) would receive
21
+ # "Hanami::View::Slim::Template" and return `Slim::Template`, which is the opposite of what
22
+ # we want.
23
+ mapping.register_lazy "Hanami::View::Tilt::HamlAdapter::Template", "hanami/view/tilt/haml_adapter", "haml"
24
+ mapping.register_lazy "Hanami::View::Tilt::SlimAdapter::Template", "hanami/view/tilt/slim_adapter", "slim"
25
+ }
11
26
 
12
27
  class << self
13
- def [](path, mapping, **options)
14
- ext = File.extname(path).sub(/^./, "").to_sym
15
- activate_adapter ext
16
-
17
- with_mapping(mapping).new(path, **options)
18
- end
19
-
20
- def default_mapping
21
- ::Tilt.default_mapping
22
- end
23
-
24
- def register_adapter(ext, adapter)
25
- adapters[ext] = adapter
26
- end
27
-
28
- def deregister_adapter(ext)
29
- adapters.delete(ext)
28
+ def [](path, mapping, options)
29
+ with_mapping(mapping).new(path, options)
30
30
  end
31
31
 
32
32
  private
33
33
 
34
- def adapters
35
- @adapters ||= {}
36
- end
37
-
38
- def activate_adapter(ext)
39
- fetch_or_store(:adapter, ext) {
40
- adapter = adapters[ext]
41
- return unless adapter
42
-
43
- *requires, error_message = adapter.requirements
44
-
45
- begin
46
- requires.each(&method(:require))
47
- rescue LoadError => e
48
- raise e, "#{e.message}\n\n#{error_message}"
49
- end
50
-
51
- adapter.activate
52
- }
53
- end
54
-
55
34
  def with_mapping(mapping)
56
- fetch_or_store(:mapping, mapping) {
35
+ View.cache.fetch_or_store(:tilt_mapping, mapping) {
57
36
  if mapping.any?
58
37
  build_mapping(mapping)
59
38
  else
60
- default_mapping
39
+ Mapping
61
40
  end
62
41
  }
63
42
  end
64
43
 
65
44
  def build_mapping(mapping)
66
- default_mapping.dup.tap do |new_mapping|
45
+ Mapping.dup.tap do |new_mapping|
67
46
  mapping.each do |extension, template_class|
68
47
  new_mapping.register template_class, extension
69
48
  end
@@ -73,6 +52,3 @@ module Hanami
73
52
  end
74
53
  end
75
54
  end
76
-
77
- require_relative "tilt/erb"
78
- require_relative "tilt/haml"
@@ -3,6 +3,6 @@
3
3
  module Hanami
4
4
  class View
5
5
  # @api private
6
- VERSION = "2.0.0.alpha8"
6
+ VERSION = "2.1.0.beta1"
7
7
  end
8
8
  end
data/lib/hanami/view.rb CHANGED
@@ -1,20 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "dry/configurable"
4
- require "dry/core/cache"
5
4
  require "dry/core/equalizer"
6
5
  require "dry/inflector"
6
+ require "zeitwerk"
7
7
 
8
- require_relative "view/application_view"
9
- require_relative "view/context"
10
- require_relative "view/exposures"
11
8
  require_relative "view/errors"
12
- require_relative "view/part_builder"
13
- require_relative "view/path"
14
- require_relative "view/render_environment"
15
- require_relative "view/rendered"
16
- require_relative "view/renderer"
17
- require_relative "view/scope_builder"
9
+ require_relative "view/html"
18
10
 
19
11
  module Hanami
20
12
  # A standalone, template-based view rendering system that offers everything
@@ -31,13 +23,34 @@ module Hanami
31
23
  #
32
24
  # @api public
33
25
  class View
26
+ # @since 2.1.0
27
+ # @api private
28
+ def self.gem_loader
29
+ @gem_loader ||= Zeitwerk::Loader.new.tap do |loader|
30
+ root = File.expand_path("..", __dir__)
31
+ loader.tag = "hanami-view"
32
+ loader.push_dir(root)
33
+ loader.ignore(
34
+ "#{root}/hanami-view.rb",
35
+ "#{root}/hanami/view/version.rb",
36
+ "#{root}/hanami/view/errors.rb",
37
+ )
38
+ loader.inflector = Zeitwerk::GemInflector.new("#{root}/hanami-view.rb")
39
+ loader.inflector.inflect(
40
+ "erb" => "ERB",
41
+ "html" => "HTML",
42
+ "html_safe_string_buffer" => "HTMLSafeStringBuffer",
43
+ )
44
+ end
45
+ end
46
+
47
+ gem_loader.setup
48
+
34
49
  # @api private
35
50
  DEFAULT_RENDERER_OPTIONS = {default_encoding: "utf-8"}.freeze
36
51
 
37
52
  include Dry::Equalizer(:config, :exposures)
38
53
 
39
- extend Dry::Core::Cache
40
-
41
54
  extend Dry::Configurable
42
55
 
43
56
  # @!group Configuration
@@ -142,6 +155,8 @@ module Hanami
142
155
  # @!scope class
143
156
  setting :default_format, default: :html
144
157
 
158
+ setting :part_class, default: Part
159
+
145
160
  # @overload config.scope_namespace=(namespace)
146
161
  # Set a namespace that will be searched when building scope classes.
147
162
  #
@@ -163,6 +178,8 @@ module Hanami
163
178
  # @!scope class
164
179
  setting :part_builder, default: PartBuilder
165
180
 
181
+ setting :scope_class, default: Scope
182
+
166
183
  # @overload config.scope_namespace=(namespace)
167
184
  # Set a namespace that will be searched when building scope classes.
168
185
  #
@@ -225,7 +242,7 @@ module Hanami
225
242
  # @param mapping [Hash<Symbol, Class>] engine mapping
226
243
  # @api public
227
244
  # @!scope class
228
- setting :renderer_engine_mapping
245
+ setting :renderer_engine_mapping, default: {}
229
246
 
230
247
  # @!endgroup
231
248
 
@@ -451,77 +468,23 @@ module Hanami
451
468
  # # <%= copyright(Time.now.utc) %>
452
469
  #
453
470
  # MyView.new.(message: "Hello") # => "HELLO!"
454
- def self.scope(base: config.scope || Hanami::View::Scope, &block)
455
- config.scope = Class.new(base, &block)
456
- end
471
+ def self.scope(scope_class = nil, &block)
472
+ scope_class ||= config.scope || config.scope_class
457
473
 
458
- # @!endgroup
459
-
460
- # @!group Render environment
461
-
462
- # Returns a render environment for the view and the given options. This
463
- # environment isn't chdir'ed into any particular directory.
464
- #
465
- # @param format [Symbol] template format to use (defaults to the `default_format` setting)
466
- # @param context [Context] context object to use (defaults to the `default_context` setting)
467
- #
468
- # @see View.template_env render environment for the view's template
469
- # @see View.layout_env render environment for the view's layout
470
- #
471
- # @return [RenderEnvironment]
472
- # @api public
473
- def self.render_env(format: config.default_format, context: config.default_context)
474
- RenderEnvironment.prepare(renderer(format), config, context)
475
- end
476
-
477
- # @overload template_env(format: config.default_format, context: config.default_context)
478
- # Returns a render environment for the view and the given options,
479
- # chdir'ed into the view's template directory. This is the environment
480
- # used when rendering the template, and is useful to to fetch
481
- # independently when unit testing Parts and Scopes.
482
- #
483
- # @param format [Symbol] template format to use (defaults to the `default_format` setting)
484
- # @param context [Context] context object to use (defaults to the `default_context` setting)
485
- #
486
- # @return [RenderEnvironment]
487
- # @api public
488
- def self.template_env(**args)
489
- render_env(**args).chdir(config.template)
474
+ config.scope = Class.new(scope_class, &block)
490
475
  end
491
476
 
492
- # @overload layout_env(format: config.default_format, context: config.default_context)
493
- # Returns a render environment for the view and the given options,
494
- # chdir'ed into the view's layout directory. This is the environment used
495
- # when rendering the view's layout.
496
- #
497
- # @param format [Symbol] template format to use (defaults to the `default_format` setting)
498
- # @param context [Context] context object to use (defaults to the `default_context` setting)
499
- #
500
- # @return [RenderEnvironment] @api public
501
- def self.layout_env(**args)
502
- render_env(**args).chdir(layout_path)
503
- end
504
-
505
- # Returns renderer for the view and provided format
506
- #
507
- # @api private
508
- def self.renderer(format)
509
- fetch_or_store(:renderer, config, format) {
510
- Renderer.new(
511
- config.paths,
512
- format: format,
513
- engine_mapping: config.renderer_engine_mapping,
514
- **config.renderer_options
515
- )
516
- }
517
- end
477
+ # @!endgroup
518
478
 
519
479
  # @api private
520
480
  def self.layout_path
521
481
  File.join(*[config.layouts_dir, config.layout].compact)
522
482
  end
523
483
 
524
- # @!endgroup
484
+ # @api private
485
+ def self.cache
486
+ Cache
487
+ end
525
488
 
526
489
  # Returns an instance of the view. This binds the defined exposures to the
527
490
  # view instance.
@@ -532,6 +495,9 @@ module Hanami
532
495
  #
533
496
  # @api public
534
497
  def initialize
498
+ self.class.config.finalize!
499
+ ensure_config
500
+
535
501
  @exposures = self.class.exposures.bind(self)
536
502
  end
537
503
 
@@ -559,20 +525,16 @@ module Hanami
559
525
  # @return [Rendered] rendered view object
560
526
  # @api public
561
527
  def call(format: config.default_format, context: config.default_context, **input)
562
- ensure_config
563
-
564
- env = self.class.render_env(format: format, context: context)
565
- template_env = self.class.template_env(format: format, context: context)
528
+ rendering = self.rendering(format: format, context: context)
566
529
 
567
- locals = locals(template_env, input)
568
- output = env.template(config.template, template_env.scope(config.scope, locals))
530
+ locals = locals(rendering, input)
531
+ output = rendering.template(config.template, rendering.scope(config.scope, locals))
569
532
 
570
533
  if layout?
571
- layout_env = self.class.layout_env(format: format, context: context)
572
534
  begin
573
- output = env.template(
535
+ output = rendering.template(
574
536
  self.class.layout_path,
575
- layout_env.scope(config.scope, layout_locals(locals))
537
+ rendering.scope(config.scope, layout_locals(locals))
576
538
  ) { output }
577
539
  rescue TemplateNotFoundError
578
540
  raise LayoutNotFoundError.new(config.layout, config.paths)
@@ -582,33 +544,33 @@ module Hanami
582
544
  Rendered.new(output: output, locals: locals)
583
545
  end
584
546
 
547
+ def rendering(format: config.default_format, context: config.default_context)
548
+ Rendering.new(config: config, format: format, context: context)
549
+ end
550
+
585
551
  private
586
552
 
587
- # @api private
588
553
  def ensure_config
589
554
  raise UndefinedConfigError, :paths unless Array(config.paths).any?
590
555
  raise UndefinedConfigError, :template unless config.template
591
556
  end
592
557
 
593
- # @api private
594
- def locals(render_env, input)
595
- exposures.(context: render_env.context, **input) do |value, exposure|
558
+ def locals(rendering, input)
559
+ exposures.(context: rendering.context, **input) do |value, exposure|
596
560
  if exposure.decorate? && value
597
- render_env.part(exposure.name, value, **exposure.options)
561
+ rendering.part(exposure.name, value, as: exposure.options[:as])
598
562
  else
599
563
  value
600
564
  end
601
565
  end
602
566
  end
603
567
 
604
- # @api private
605
568
  def layout_locals(locals)
606
569
  locals.each_with_object({}) do |(key, value), layout_locals|
607
570
  layout_locals[key] = value if exposures[key].for_layout?
608
571
  end
609
572
  end
610
573
 
611
- # @api private
612
574
  def layout?
613
575
  !!config.layout # rubocop:disable Style/DoubleNegation
614
576
  end
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: 2.0.0.alpha8
4
+ version: 2.1.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Riley
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-05-19 00:00:00.000000000 Z
12
+ date: 2023-06-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: concurrent-ruby
@@ -31,54 +31,68 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: '0.13'
35
- - - ">="
36
- - !ruby/object:Gem::Version
37
- version: 0.13.0
34
+ version: '1.0'
38
35
  type: :runtime
39
36
  prerelease: false
40
37
  version_requirements: !ruby/object:Gem::Requirement
41
38
  requirements:
42
39
  - - "~>"
43
40
  - !ruby/object:Gem::Version
44
- version: '0.13'
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: 0.13.0
41
+ version: '1.0'
48
42
  - !ruby/object:Gem::Dependency
49
43
  name: dry-core
50
44
  requirement: !ruby/object:Gem::Requirement
51
45
  requirements:
52
46
  - - "~>"
53
47
  - !ruby/object:Gem::Version
54
- version: '0.5'
55
- - - ">="
48
+ version: '1.0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: dry-inflector
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
56
61
  - !ruby/object:Gem::Version
57
- version: '0.5'
62
+ version: '1.0'
63
+ - - "<"
64
+ - !ruby/object:Gem::Version
65
+ version: '2'
58
66
  type: :runtime
59
67
  prerelease: false
60
68
  version_requirements: !ruby/object:Gem::Requirement
61
69
  requirements:
62
70
  - - "~>"
63
71
  - !ruby/object:Gem::Version
64
- version: '0.5'
65
- - - ">="
72
+ version: '1.0'
73
+ - - "<"
66
74
  - !ruby/object:Gem::Version
67
- version: '0.5'
75
+ version: '2'
68
76
  - !ruby/object:Gem::Dependency
69
- name: dry-inflector
77
+ name: temple
70
78
  requirement: !ruby/object:Gem::Requirement
71
79
  requirements:
72
80
  - - "~>"
73
81
  - !ruby/object:Gem::Version
74
- version: '0.1'
82
+ version: 0.10.0
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: 0.10.2
75
86
  type: :runtime
76
87
  prerelease: false
77
88
  version_requirements: !ruby/object:Gem::Requirement
78
89
  requirements:
79
90
  - - "~>"
80
91
  - !ruby/object:Gem::Version
81
- version: '0.1'
92
+ version: 0.10.0
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: 0.10.2
82
96
  - !ruby/object:Gem::Dependency
83
97
  name: tilt
84
98
  requirement: !ruby/object:Gem::Requirement
@@ -99,6 +113,20 @@ dependencies:
99
113
  - - ">="
100
114
  - !ruby/object:Gem::Version
101
115
  version: 2.0.6
116
+ - !ruby/object:Gem::Dependency
117
+ name: zeitwerk
118
+ requirement: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - "~>"
121
+ - !ruby/object:Gem::Version
122
+ version: '2.6'
123
+ type: :runtime
124
+ prerelease: false
125
+ version_requirements: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '2.6'
102
130
  - !ruby/object:Gem::Dependency
103
131
  name: bundler
104
132
  requirement: !ruby/object:Gem::Requirement
@@ -151,31 +179,41 @@ extensions: []
151
179
  extra_rdoc_files: []
152
180
  files:
153
181
  - CHANGELOG.md
154
- - LICENSE
155
182
  - README.md
156
183
  - hanami-view.gemspec
157
184
  - lib/hanami-view.rb
158
185
  - lib/hanami/view.rb
159
186
  - lib/hanami/view/application_view.rb
187
+ - lib/hanami/view/cache.rb
160
188
  - lib/hanami/view/context.rb
161
189
  - lib/hanami/view/context_helpers/content_helpers.rb
162
190
  - lib/hanami/view/decorated_attributes.rb
191
+ - lib/hanami/view/erb/engine.rb
192
+ - lib/hanami/view/erb/filters/block.rb
193
+ - lib/hanami/view/erb/filters/trimming.rb
194
+ - lib/hanami/view/erb/parser.rb
195
+ - lib/hanami/view/erb/template.rb
163
196
  - lib/hanami/view/errors.rb
164
197
  - lib/hanami/view/exposure.rb
165
198
  - lib/hanami/view/exposures.rb
199
+ - lib/hanami/view/helpers/escape_helper.rb
200
+ - lib/hanami/view/helpers/number_formatting_helper.rb
201
+ - lib/hanami/view/helpers/tag_helper.rb
202
+ - lib/hanami/view/helpers/tag_helper/tag_builder.rb
203
+ - lib/hanami/view/html.rb
204
+ - lib/hanami/view/html_safe_string_buffer.rb
166
205
  - lib/hanami/view/part.rb
167
206
  - lib/hanami/view/part_builder.rb
168
207
  - lib/hanami/view/path.rb
169
- - lib/hanami/view/render_environment.rb
170
- - lib/hanami/view/render_environment_missing.rb
171
208
  - lib/hanami/view/rendered.rb
172
209
  - lib/hanami/view/renderer.rb
210
+ - lib/hanami/view/rendering.rb
211
+ - lib/hanami/view/rendering_missing.rb
173
212
  - lib/hanami/view/scope.rb
174
213
  - lib/hanami/view/scope_builder.rb
175
214
  - lib/hanami/view/tilt.rb
176
- - lib/hanami/view/tilt/erb.rb
177
- - lib/hanami/view/tilt/erbse.rb
178
- - lib/hanami/view/tilt/haml.rb
215
+ - lib/hanami/view/tilt/haml_adapter.rb
216
+ - lib/hanami/view/tilt/slim_adapter.rb
179
217
  - lib/hanami/view/version.rb
180
218
  homepage: https://dry-rb.org/gems/hanami-view
181
219
  licenses:
@@ -201,7 +239,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
201
239
  - !ruby/object:Gem::Version
202
240
  version: 1.3.1
203
241
  requirements: []
204
- rubygems_version: 3.3.7
242
+ rubygems_version: 3.4.13
205
243
  signing_key:
206
244
  specification_version: 4
207
245
  summary: A complete, standalone view rendering system that gives you everything you
data/LICENSE DELETED
@@ -1,20 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2015-2020 dry-rb team
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy of
6
- this software and associated documentation files (the "Software"), to deal in
7
- the Software without restriction, including without limitation the rights to
8
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
- the Software, and to permit persons to whom the Software is furnished to do so,
10
- subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "dry/core/equalizer"
4
-
5
- module Hanami
6
- class View
7
- # @api private
8
- class RenderEnvironment
9
- def self.prepare(renderer, config, context)
10
- new(
11
- renderer: renderer,
12
- inflector: config.inflector,
13
- context: context,
14
- scope_builder: config.scope_builder.new(namespace: config.scope_namespace),
15
- part_builder: config.part_builder.new(namespace: config.part_namespace)
16
- )
17
- end
18
-
19
- include Dry::Equalizer(:renderer, :inflector, :context, :scope_builder, :part_builder)
20
-
21
- attr_reader :renderer, :inflector, :context, :scope_builder, :part_builder
22
-
23
- def initialize(renderer:, inflector:, context:, scope_builder:, part_builder:)
24
- @renderer = renderer
25
- @inflector = inflector
26
- @context = context.for_render_env(self)
27
- @scope_builder = scope_builder.for_render_env(self)
28
- @part_builder = part_builder.for_render_env(self)
29
- end
30
-
31
- def format
32
- renderer.format
33
- end
34
-
35
- def part(name, value, **options)
36
- part_builder.(name, value, **options)
37
- end
38
-
39
- def scope(name = nil, locals) # rubocop:disable Style/OptionalArguments
40
- scope_builder.(name, locals)
41
- end
42
-
43
- def template(name, scope, &block)
44
- renderer.template(name, scope, &block)
45
- end
46
-
47
- def partial(name, scope, &block)
48
- renderer.partial(name, scope, &block)
49
- end
50
-
51
- def chdir(dirname)
52
- self.class.new(
53
- renderer: renderer.chdir(dirname),
54
- inflector: inflector,
55
- context: context,
56
- scope_builder: scope_builder,
57
- part_builder: part_builder
58
- )
59
- end
60
- end
61
- end
62
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Hanami
4
- class View
5
- module Tilt
6
- module ERB
7
- def self.requirements
8
- ["hanami/view/tilt/erbse", <<~ERROR]
9
- hanami-view requires erbse for full compatibility when rendering .erb templates (e.g. implicitly capturing block content when yielding)
10
-
11
- To ignore this and use another engine for .erb templates, deregister this adapter before calling your views:
12
-
13
- Hanami::View::Tilt.deregister_adapter(:erb)
14
- ERROR
15
- end
16
-
17
- def self.activate
18
- Tilt.default_mapping.register ErbseTemplate, "erb"
19
- self
20
- end
21
- end
22
-
23
- register_adapter :erb, ERB
24
- end
25
- end
26
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "tilt/template"
4
- require "erbse"
5
-
6
- module Hanami
7
- class View
8
- module Tilt
9
- # Tilt template class copied from cells-erb gem
10
- class ErbseTemplate < ::Tilt::Template
11
- def prepare
12
- @template = ::Erbse::Engine.new
13
- end
14
-
15
- def precompiled_template(_locals)
16
- @template.call(data)
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Hanami
4
- class View
5
- module Tilt
6
- module Haml
7
- def self.requirements
8
- ["hamlit/block", <<~ERROR]
9
- hanami-view requires hamlit-block for full compatibility when rendering .haml templates (e.g. implicitly capturing block content when yielding)
10
-
11
- To ignore this and use another engine for .haml templates, dereigster this adapter before calling your views:
12
-
13
- Hanami::View::Tilt.deregister_adatper(:haml)
14
- ERROR
15
- end
16
-
17
- def self.activate
18
- # Requiring hamlit/block will register the engine with Tilt
19
- self
20
- end
21
- end
22
-
23
- register_adapter :haml, Haml
24
- end
25
- end
26
- end