dry-view 0.6.0 → 0.7.0

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: 4d0cd65b1329feef3497caadc8f41521850546d9c60aa673d035215bcaaee922
4
- data.tar.gz: 46e2e12a0d192dd2e7443c334bc62fdd86ff76f1aa308c1b1ac14a921e67565b
3
+ metadata.gz: 5484205327cc47a66db6ae6df71a2e6647a690b8709aaf8ccbe3be80f7416a99
4
+ data.tar.gz: 10cb4443866ab17bcd16d90de09e733f3569d3b95ebf84bcffaaebaab068f964
5
5
  SHA512:
6
- metadata.gz: f235921f2631c60446690342c388cc624665f21a9a1e40e979efa285bfa8fd73c3a0f4bb453931e1fc25cdc5a6201d58f42a7a4a6275a96c2f5d641f0ec23961
7
- data.tar.gz: 2cc2906563bcd30b21c1034d0ffb97c395e77898b8ab7d117cdf11aa52462c7a874e05ddb66a59c600c29a31c65f7e3808fae4f447df817cdedbc255e7d0c179
6
+ metadata.gz: 9bd666e31aa5078cd99ed81c3934ba32969c709657ff53efc2e24e8902c9758fb3824c8e665184a24c14d45e182a4af950007764029e9c7715994563749f9222
7
+ data.tar.gz: 9ce17b5ef3be59a4de48acc9c084c1803387000f2c18339b1b39b93aaa3412ce013755e03435dca6525b72be6f919f29580b98f87dac0f7d2754208cd8476adf
@@ -13,11 +13,11 @@ before_script:
13
13
  after_script:
14
14
  - "[ -d coverage ] && ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT"
15
15
  rvm:
16
- - 2.6.0
16
+ - 2.6.1
17
17
  - 2.5.3
18
18
  - 2.4.5
19
19
  - 2.3.8
20
- - jruby-9.2.5.0
20
+ - jruby-9.2.6.0
21
21
  notifications:
22
22
  email: false
23
23
  webhooks:
@@ -1,3 +1,27 @@
1
+ # 0.7.0 / 2019-03-06
2
+
3
+ ### Added
4
+
5
+ - Raise a `Dry::View::UndefinedConfigError` when a view is called but no paths have been configured (timriley in [#130][pr130])
6
+
7
+ ### Changed
8
+
9
+ - [BREAKING] Move `Dry::View::Renderer::TemplateNotFoundError` to `Dry::View::TemplateNotFoundError` (timriley in [#130][pr130])
10
+ - [BREAKING] `Dry::View::UndefinedConfigError` is raised instead of `Dry::View::UndefinedTemplateError` when a view is called but no template has been configured (timriley in [#130][pr130])
11
+ - Stop searching upwards through parent directories when rendering a view's template (as opposed to partials) (timriley in [#130][pr130])
12
+ - Stop searching in `shared/` subdirectories when rendering a view's template (as opposed to partials) (timriley in [#130][pr130])
13
+ - Adjust template lookup cache keys to ensure no false hits (timriley in [#130][pr130])
14
+
15
+ ### Fixed
16
+
17
+ - Avoid a `SystemStackError` when a view is configured with a template that cannot be found on the filesystem (timriley in [#129][pr129])
18
+
19
+ [Compare v0.6.0...v0.7.0](https://github.com/dry-rb/dry-view/compare/v0.6.0...v0.7.0)
20
+
21
+
22
+ [pr129]: https://github.com/dry-rb/dry-view/pull/129
23
+ [pr130]: https://github.com/dry-rb/dry-view/pull/130
24
+
1
25
  # 0.6.0 / 2019-01-30
2
26
 
3
27
  ### Added
@@ -7,6 +7,7 @@ require "dry/inflector"
7
7
 
8
8
  require_relative "view/context"
9
9
  require_relative "view/exposures"
10
+ require_relative "view/errors"
10
11
  require_relative "view/part_builder"
11
12
  require_relative "view/path"
12
13
  require_relative "view/render_environment"
@@ -33,9 +34,6 @@ module Dry
33
34
  #
34
35
  # @api public
35
36
  class View
36
- # @api private
37
- UndefinedTemplateError = Class.new(StandardError)
38
-
39
37
  # @api private
40
38
  DEFAULT_RENDERER_OPTIONS = {default_encoding: "utf-8"}.freeze
41
39
 
@@ -459,7 +457,7 @@ module Dry
459
457
  # @return [Rendered] rendered view object
460
458
  # @api public
461
459
  def call(format: config.default_format, context: config.default_context, **input)
462
- raise UndefinedTemplateError, "no +template+ configured" unless config.template
460
+ ensure_config
463
461
 
464
462
  env = self.class.render_env(format: format, context: context)
465
463
  template_env = self.class.template_env(format: format, context: context)
@@ -469,7 +467,7 @@ module Dry
469
467
 
470
468
  if layout?
471
469
  layout_env = self.class.layout_env(format: format, context: context)
472
- output = layout_env.template(self.class.layout_path, layout_env.scope(config.scope, layout_locals(locals))) { output }
470
+ output = env.template(self.class.layout_path, layout_env.scope(config.scope, layout_locals(locals))) { output }
473
471
  end
474
472
 
475
473
  Rendered.new(output: output, locals: locals)
@@ -477,6 +475,12 @@ module Dry
477
475
 
478
476
  private
479
477
 
478
+ # @api private
479
+ def ensure_config
480
+ raise UndefinedConfigError.new(:paths) unless Array(config.paths).any?
481
+ raise UndefinedConfigError.new(:template) unless config.template
482
+ end
483
+
480
484
  # @api private
481
485
  def locals(render_env, input)
482
486
  exposures.(context: render_env.context, **input) do |value, exposure|
@@ -0,0 +1,27 @@
1
+ module Dry
2
+ class View
3
+ # Error raised when critical settings are not configured
4
+ #
5
+ # @api private
6
+ class UndefinedConfigError < StandardError
7
+ def initialize(key)
8
+ super("no +#{key}+ configured")
9
+ end
10
+ end
11
+
12
+ # Error raised when template could not be found within a view's configured
13
+ # paths
14
+ #
15
+ # @api private
16
+ class TemplateNotFoundError < StandardError
17
+ def initialize(template_name, lookup_paths)
18
+ msg = [
19
+ "Template +#{template_name}+ could not be found in paths:",
20
+ lookup_paths.map { |path| " - #{path}"}
21
+ ].join("\n\n")
22
+
23
+ super(msg)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -22,14 +22,14 @@ module Dry
22
22
 
23
23
  def initialize(dir, root: dir)
24
24
  @dir = Pathname(dir)
25
- @root = root
25
+ @root = Pathname(root)
26
26
  end
27
27
 
28
- def lookup(name, format, include_shared: true)
29
- fetch_or_store(dir, root, name, format) do
30
- template?(name, format) ||
31
- (include_shared && template?("shared/#{name}", format)) ||
32
- !root? && chdir("..").lookup(name, format)
28
+ def lookup(name, format, child_dirs: [], parent_dir: false)
29
+ fetch_or_store(dir, root, name, format, child_dirs, parent_dir) do
30
+ lookup_template(name, format) ||
31
+ lookup_in_child_dirs(name, format, child_dirs: child_dirs) ||
32
+ parent_dir && lookup_in_parent_dir(name, format, child_dirs: child_dirs)
33
33
  end
34
34
  end
35
35
 
@@ -48,10 +48,21 @@ module Dry
48
48
  end
49
49
 
50
50
  # Search for a template using a wildcard for the engine extension
51
- def template?(name, format)
51
+ def lookup_template(name, format)
52
52
  glob = dir.join("#{name}.#{format}.*")
53
53
  Dir[glob].first
54
54
  end
55
+
56
+ def lookup_in_child_dirs(name, format, child_dirs:)
57
+ child_dirs.reduce(nil) { |_, dir|
58
+ template = chdir(dir).lookup(name, format)
59
+ break template if template
60
+ }
61
+ end
62
+
63
+ def lookup_in_parent_dir(name, format, child_dirs:)
64
+ !root? && chdir("..").lookup(name, format, child_dirs: child_dirs, parent_dir: true)
65
+ end
55
66
  end
56
67
  end
57
68
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "dry/core/cache"
4
4
  require "dry/equalizer"
5
+ require_relative "errors"
5
6
  require_relative "tilt"
6
7
 
7
8
  module Dry
@@ -15,8 +16,6 @@ module Dry
15
16
 
16
17
  include Dry::Equalizer(:paths, :format, :engine_mapping, :options)
17
18
 
18
- TemplateNotFoundError = Class.new(StandardError)
19
-
20
19
  attr_reader :paths, :format, :engine_mapping, :options
21
20
 
22
21
  def initialize(paths, format:, engine_mapping: nil, **options)
@@ -26,19 +25,24 @@ module Dry
26
25
  @options = options
27
26
  end
28
27
 
29
- def template(name, scope, &block)
30
- path = lookup(name)
28
+ def template(name, scope, **lookup_options, &block)
29
+ path = lookup(name, **lookup_options)
31
30
 
32
31
  if path
33
32
  render(path, scope, &block)
34
33
  else
35
- msg = "Template #{name.inspect} could not be found in paths:\n#{paths.map { |pa| "- #{pa.to_s}" }.join("\n")}"
36
- raise TemplateNotFoundError, msg
34
+ raise TemplateNotFoundError.new(name, paths)
37
35
  end
38
36
  end
39
37
 
40
38
  def partial(name, scope, &block)
41
- template(name_for_partial(name), scope, &block)
39
+ template(
40
+ name_for_partial(name),
41
+ scope,
42
+ child_dirs: %w[shared],
43
+ parent_dir: true,
44
+ &block
45
+ )
42
46
  end
43
47
 
44
48
  def render(path, scope, &block)
@@ -51,15 +55,15 @@ module Dry
51
55
  self.class.new(new_paths, format: format, **options)
52
56
  end
53
57
 
54
- def lookup(name)
55
- paths.inject(false) { |_, path|
56
- result = path.lookup(name, format, include_shared: false)
58
+ private
59
+
60
+ def lookup(name, **options)
61
+ paths.inject(nil) { |_, path|
62
+ result = path.lookup(name, format, **options)
57
63
  break result if result
58
64
  }
59
65
  end
60
66
 
61
- private
62
-
63
67
  def name_for_partial(name)
64
68
  name_segments = name.to_s.split(PATH_DELIMITER)
65
69
  name_segments[0..-2].push("#{PARTIAL_PREFIX}#{name_segments[-1]}").join(PATH_DELIMITER)
@@ -3,6 +3,6 @@
3
3
  module Dry
4
4
  class View
5
5
  # @api private
6
- VERSION = "0.6.0"
6
+ VERSION = "0.7.0"
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-view
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Riley
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2019-01-29 00:00:00.000000000 Z
12
+ date: 2019-03-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: tilt
@@ -157,6 +157,7 @@ files:
157
157
  - lib/dry/view.rb
158
158
  - lib/dry/view/context.rb
159
159
  - lib/dry/view/decorated_attributes.rb
160
+ - lib/dry/view/errors.rb
160
161
  - lib/dry/view/exposure.rb
161
162
  - lib/dry/view/exposures.rb
162
163
  - lib/dry/view/part.rb
@@ -192,8 +193,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
192
193
  - !ruby/object:Gem::Version
193
194
  version: '0'
194
195
  requirements: []
195
- rubyforge_project:
196
- rubygems_version: 2.7.3
196
+ rubygems_version: 3.0.2
197
197
  signing_key:
198
198
  specification_version: 4
199
199
  summary: A complete, standalone view rendering system that gives you everything you