middleman-data_source 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f007a9a894f8c5fc6d56b47a8e238939b96fbf12
4
- data.tar.gz: 03abe96ea5700bb92236b4f00fc0681b279d33f9
3
+ metadata.gz: 8149a40f5de297992c3027d32d35a35592781065
4
+ data.tar.gz: 14b91bba9a92160b4c2d696df4698eefc48266ec
5
5
  SHA512:
6
- metadata.gz: 0f38a7aade0e3d9f051c37fe2095aacf13a8bc070d66072e9ed95051b09087ff01a1900052baf8aa9aefcc47f201fd93441bcd8477c71e924c145c539a6958b5
7
- data.tar.gz: a01f2c2bc6beacfb1a8e606241ff3a2fb5a4b66c159706f32145be7e57d820fe6f707ed584bea12c1449d3d14b91e1ae84c7dd52deb7f7635fb23f78c697c586
6
+ metadata.gz: 218bd22fd6a2875f9015641d9f87ccaaa865a24e4022304a1ed2a89b0094276e3197b0bf651b4a1cfff6300d097918e726e764087671dc1149ee7ee230ea52ea
7
+ data.tar.gz: 6589a1e6dd03534bf4121ff797058f91776ca6b90ce34b141b1bdb3171c4203a3e51b144a5184b75147b66f133f3e68d77f7b9f9563b475719bd5832b4bd54ce
data/changelog.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 0.6.0
2
+ - add definable decoders & allow override of default json & yaml decoders
3
+ - allow for defining sources with arbitrary data types
4
+
1
5
  # 0.5.0
2
6
  - include support for resources that include query params after their file extension [@jordanandree]
3
7
 
@@ -7,6 +7,10 @@ module Middleman
7
7
  option :rack_app, nil, 'rack app to use'
8
8
  option :root, nil, 'http(s) host to use'
9
9
  option :files, [], 'routes to mount as remote data files'
10
+ option :sources, [], 'array of sources to mount as data'
11
+ option :decoders, {}, 'callable functions to decode data sources'
12
+
13
+ attr_reader :decoders, :sources
10
14
 
11
15
  def rack_app
12
16
  @_rack_app ||= ::Rack::Test::Session.new( ::Rack::MockSession.new( options.rack_app ) )
@@ -15,30 +19,32 @@ module Middleman
15
19
  def initialize app, options_hash={}, &block
16
20
  super app, options_hash, &block
17
21
 
18
- app_inst = app.respond_to?(:inst) ? app.inst : app
19
- remote_datas = if options.files.respond_to? :keys
20
- options.files
21
- else
22
- Hash[options.files.map do |remote_file|
23
- [remote_file, remote_file]
24
- end]
22
+ app_inst = app.respond_to?(:inst) ? app.inst : app
23
+ @sources = options.sources.dup
24
+ @decoders = default_decoders.merge(options.decoders)
25
+
26
+ options.files.flat_map do |remote_path, local|
27
+ @sources.push({
28
+ :alias => (local || remote_path),
29
+ :path => remote_path
30
+ })
25
31
  end
26
32
 
27
- remote_datas.each do |remote_file, local_representation|
28
- raw_extension = File.extname(remote_file)
33
+ @sources.each do |source|
34
+ raw_extension = File.extname(source[:path])
29
35
  extension = raw_extension.split('?').first
30
- parts = local_representation.split(File::SEPARATOR)
36
+ parts = source[:alias].split(File::SEPARATOR)
31
37
  basename = File.basename(parts.pop, raw_extension)
32
38
 
33
39
  if parts.empty?
34
40
  original_callback = app_inst.data.callbacks[basename]
35
41
  app_inst.data.callbacks[basename] = Proc.new do
36
- attempt_merge_then_enhance decode_data(remote_file, extension), original_callback
42
+ attempt_merge_then_enhance decode_data(source, extension), original_callback
37
43
  end
38
44
  else
39
45
  original_callback = app_inst.data.callbacks[parts.first]
40
46
  app_inst.data.callbacks[parts.first] = Proc.new do
41
- built_data = { basename => decode_data(remote_file, extension) }
47
+ built_data = { basename => decode_data(source, extension) }
42
48
  parts[1..-1].reverse.each do |part|
43
49
  built_data = { part => built_data }
44
50
  end
@@ -51,6 +57,19 @@ module Middleman
51
57
 
52
58
  private
53
59
 
60
+ def default_decoders
61
+ {
62
+ json: {
63
+ extensions: ['.json'],
64
+ decoder: ->(source) { ActiveSupport::JSON.decode(source) },
65
+ },
66
+ yaml: {
67
+ extensions: ['.yaml', '.yml'],
68
+ decoder: ->(source) { YAML.load(source) }
69
+ }
70
+ }
71
+ end
72
+
54
73
  def attempt_merge_then_enhance new_data, original_callback
55
74
  if original_callback
56
75
  original_data = original_callback.call
@@ -62,21 +81,27 @@ module Middleman
62
81
  return ::Middleman::Util.recursively_enhance new_data
63
82
  end
64
83
 
65
- def decode_data file_path, extension
66
- if ['.yaml', '.yml'].include? extension
67
- YAML.load get_file_contents file_path
68
- elsif extension == '.json'
69
- ActiveSupport::JSON.decode get_file_contents file_path
84
+ def decode_data source, extension
85
+ if source.has_key? :type
86
+ decoder = decoders[source[:type]]
70
87
  else
71
- raise UnsupportedDataExtension
88
+ decoder = decoders.find do |candidate|
89
+ candidate[1][:extensions].include? extension
90
+ end
91
+ decoder = decoder.last if decoder
72
92
  end
93
+
94
+ raise UnsupportedDataExtension unless decoder
95
+
96
+ decoder[:decoder].call get_file_contents source[:path]
73
97
  end
74
98
 
75
99
  def get_file_contents file_path
76
100
  if options.rack_app
77
101
  rack_app.get( URI.escape(file_path) ).body
78
102
  else
79
- Borrower::Content.get File.join( options.root, file_path )
103
+ file_path = File.join( options.root, file_path ) if options.root
104
+ Borrower::Content.get file_path
80
105
  end
81
106
  end
82
107
 
@@ -1,7 +1,7 @@
1
1
  module Middleman
2
2
  module DataSource
3
3
 
4
- VERSION = "0.5.0"
4
+ VERSION = "0.6.0"
5
5
 
6
6
  end
7
7
  end
data/readme.md CHANGED
@@ -98,6 +98,35 @@ activate :data_source do |c|
98
98
  end
99
99
  ```
100
100
 
101
+ ### Custom data types
102
+
103
+ By default we just look at the extension of a file to determine which decoder to use. By setting a source directly you can give it any data type you need. Each source is a hash with an `alias`, `path`, and `type` key. The `alias` and `path` would be the same as if you defined the source using files as `{ path => alias }`, while type corresponds to the decoder you'd like to use.
104
+
105
+ There are default decoders for `:yaml` and `:json`, however you are free to override them or create your own types.
106
+
107
+ ```ruby
108
+ # config.rb
109
+ activate :data_source do |c|
110
+
111
+ c.files = ['by_extension.ctype']
112
+
113
+ c.sources = [
114
+ {
115
+ alias: "foo_bar",
116
+ path: "/foo/bar.ctype",
117
+ type: :my_type
118
+ }
119
+ ]
120
+
121
+ c.decoders = {
122
+ my_type: {
123
+ extensions: ['.ctype'],
124
+ decoder: ->(src) { CustomType.parse(src) }
125
+ }
126
+ }
127
+ ```
128
+
129
+ In the above example, I can access `app.data.by_extension` w/ the file contents decoded by `CustomType`, because it's extension `.ctype` matches the one defined by the `:my_type` decoder. Similarly, `app.data.foo_bar` is also run through `CustomType` because it's `:type` attribute is set to `:my_type`.
101
130
 
102
131
  # Testing
103
132
 
@@ -9,13 +9,34 @@ activate :data_source do |c|
9
9
  run lambda {|env| [404, {'Content-type' => 'text/plain'}, ['Not found']] }
10
10
  end
11
11
 
12
+ c.sources = [
13
+ {
14
+ alias: "foo",
15
+ path: "foo.bar",
16
+ type: :yaml
17
+ },
18
+ {
19
+ alias: "my_decoder",
20
+ path: "w/e",
21
+ type: :my_decoder
22
+ }
23
+ ]
24
+
25
+ c.decoders = {
26
+ my_decoder: {
27
+ extensions: ['.ctype'],
28
+ decoder: ->(data) { ["grass","is","greener"] }
29
+ }
30
+ }
31
+
12
32
  c.files = [
13
33
  'remote.json',
14
34
  'deeply/nested.json',
15
35
  'deeply/nested/routes.json',
16
36
  'in_yaml.yml',
17
37
  'in_json.json',
18
- 'query_param.json?token=foo'
38
+ 'query_param.json?token=foo',
39
+ 'run_through_my_decoder.ctype'
19
40
  ]
20
41
 
21
42
  end
@@ -42,6 +42,18 @@ describe Middleman::DataSource::Extension do
42
42
  end
43
43
 
44
44
  it_behaves_like "data import"
45
+
46
+ it "allows assignment of sources w/ given type" do
47
+ expect( @mm.data.foo ).to eq ["one","two","three"]
48
+ end
49
+
50
+ it "allows assignment of custom data decoders" do
51
+ expect( @mm.data.my_decoder ).to eq ["grass","is","greener"]
52
+ end
53
+
54
+ it "sets custom decoders based on file extensions" do
55
+ expect( @mm.data.run_through_my_decoder ).to eq ["grass","is","greener"]
56
+ end
45
57
  end
46
58
 
47
59
  context "with unsupported_extension" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: middleman-data_source
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Sloan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-29 00:00:00.000000000 Z
11
+ date: 2015-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: middleman