middleman-data_source 0.6.1 → 0.7.1

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: 8644a9a460f377c8c69f395ad49f85e08c600fcc
4
- data.tar.gz: 2dc0d7139e818f655f7ad6a3bbd7eb8612d38693
3
+ metadata.gz: c171a11ee4a3c842ff19e9da42ef88fa4db97efe
4
+ data.tar.gz: c68e86e0c5b7bd274cd4fb1bf94bd6dd7668b88b
5
5
  SHA512:
6
- metadata.gz: 031b02e3c88069f6232345bf159f007b9d0b14fa22e87e74c461beaf5abef13d47e7a85bff1d4cf210247ed695c1b37fba8128964c7e286d78af391d748fda0e
7
- data.tar.gz: 1699caaa0cdfad8f4ba4cf5d311ca0ff0fe44ea101cfe2bd0d2f7a9e68027763a9e5e0b647e8480dd655126e08ec217afa61f68d4ca16ea5ef38aaa9775a7edf
6
+ metadata.gz: f781063b434454cbe0051dc59e60a49ba52f4e6cabc77dcced2c06c6dde231e9652f0b539fd5e648052880391c483c1d6b657cb5fcdeca5567b81ca1424f17c8
7
+ data.tar.gz: 4067143433e37ed48fefeb716b44ace151b7ba8efbfb7b82dbde3c605c41421aa15b735db6ecf185398289784a75a69fc523bdc4564432deaec6519f7bb7dfc4
data/changelog.md CHANGED
@@ -1,3 +1,11 @@
1
+ # 0.7.1
2
+ - allow passing data type to collection
3
+ - fix access to data object in middleman 3.x code branches
4
+
5
+ # 0.7.0 [YANKED]
6
+ - feat(collection): create a collection type that can generate a collection of resources based off of an index endpoint. [more info](readme.md#creating-a-collection)
7
+ - stop using `ActiveSupport::JSON` to parse json, this causes dates to no longer be decoded. To restore the original behavior, add a custom decoder for json.
8
+
1
9
  # 0.6.1
2
10
  - fixes for newer versions of middleman 4 compatability
3
11
 
@@ -5,12 +5,14 @@ module Middleman
5
5
  self.supports_multiple_instances = true
6
6
 
7
7
  option :rack_app, nil, 'rack app to use'
8
- option :root, nil, 'http(s) host to use'
8
+ option :root, nil, 'http(s) host or file path to use'
9
9
  option :files, [], 'routes to mount as remote data files'
10
10
  option :sources, [], 'array of sources to mount as data'
11
11
  option :decoders, {}, 'callable functions to decode data sources'
12
+ option :collection, {}, 'group of recursive resources'
12
13
 
13
- attr_reader :decoders, :sources
14
+ attr_reader :decoders, :sources, :collection,
15
+ :app_inst
14
16
 
15
17
  def rack_app
16
18
  @_rack_app ||= ::Rack::Test::Session.new( ::Rack::MockSession.new( options.rack_app ) )
@@ -18,19 +20,35 @@ module Middleman
18
20
 
19
21
  def initialize app, options_hash={}, &block
20
22
  super app, options_hash, &block
23
+ @app_inst = app.respond_to?(:inst) ? app.inst : app
21
24
 
22
- app_inst = app.respond_to?(:inst) ? app.inst : app
23
- @sources = options.sources.dup
24
- @decoders = default_decoders.merge(options.decoders)
25
+ @sources = options.sources.dup + convert_files_to_sources(options.files)
26
+ @decoders = default_decoders.merge(options.decoders)
25
27
 
26
- options.files.flat_map do |remote_path, local|
27
- @sources.push({
28
- :alias => (local || remote_path),
29
- :path => remote_path
30
- })
28
+ if options.collection.empty?
29
+ @collection = false
30
+ else
31
+ @collection = options.collection
32
+ sources.push options.collection.merge alias: File.join( options.collection[:alias], 'all' )
31
33
  end
32
34
 
33
- @sources.each do |source|
35
+ sources.each do |source|
36
+ add_data_callback_for_source(source)
37
+ end
38
+
39
+ if collection
40
+ collection[:items].call( app_inst.data[collection[:alias]]['all'] ).map do |source|
41
+ source[:alias] = File.join(collection[:alias], source[:alias])
42
+ source
43
+ end.each do |source|
44
+ add_data_callback_for_source(source)
45
+ end
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def add_data_callback_for_source source
34
52
  raw_extension = File.extname(source[:path])
35
53
  extension = raw_extension.split('?').first
36
54
  parts = source[:alias].split(File::SEPARATOR)
@@ -44,24 +62,34 @@ module Middleman
44
62
  else
45
63
  original_callback = app_inst.data.callbacks[parts.first]
46
64
  app_inst.data.callbacks[parts.first] = Proc.new do
47
- built_data = { basename => decode_data(source, extension) }
48
- parts[1..-1].reverse.each do |part|
49
- built_data = { part => built_data }
65
+ begin
66
+ built_data = { basename => decode_data(source, extension) }
67
+ parts[1..-1].reverse.each do |part|
68
+ built_data = { part => built_data }
69
+ end
70
+
71
+ attempt_merge_then_enhance built_data, original_callback
72
+ rescue => e
73
+ binding.pry
50
74
  end
51
-
52
- attempt_merge_then_enhance built_data, original_callback
53
75
  end
54
76
  end
55
77
  end
56
- end
57
78
 
58
- private
79
+ def convert_files_to_sources files={}
80
+ files.flat_map do |remote_path, local|
81
+ {
82
+ alias: (local || remote_path),
83
+ path: remote_path
84
+ }
85
+ end
86
+ end
59
87
 
60
88
  def default_decoders
61
89
  {
62
90
  json: {
63
91
  extensions: ['.json'],
64
- decoder: ->(source) { ActiveSupport::JSON.decode(source) },
92
+ decoder: ->(source) { JSON.parse(source) },
65
93
  },
66
94
  yaml: {
67
95
  extensions: ['.yaml', '.yml'],
@@ -1,7 +1,7 @@
1
1
  module Middleman
2
2
  module DataSource
3
3
 
4
- VERSION = "0.6.1"
4
+ VERSION = "0.7.1"
5
5
 
6
6
  end
7
7
  end
data/readme.md CHANGED
@@ -128,6 +128,64 @@ activate :data_source do |c|
128
128
 
129
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`.
130
130
 
131
+
132
+ ### Creating a collection
133
+
134
+ Collections allow you to collection sources that have belong together in an array and have distinct urls. This would loosely follow the Rails index/show convension. For example, lets say we have an endpoint that tells us about some Game of Thrones characters, and then includes a single endpoint for each with expanded information:
135
+
136
+ ```json
137
+ # /got/index.json
138
+ [
139
+ { "name": "Eddard Stark", "url": "/got/eddard-stark.json" },
140
+ { "name": "Hodor", "url": "/got/hodor.json" }
141
+ ]
142
+ ```
143
+
144
+ ```json
145
+ # /got/eddard-stark.json
146
+ {
147
+ "name": "Eddard Stark",
148
+ "quote": "Winter is coming"
149
+ }
150
+
151
+ #/got/hodor.json
152
+ {
153
+ "name": "Hodor",
154
+ "quote": "Hodor!"
155
+ }
156
+ ```
157
+
158
+ Then set up a collection to access them through Middleman. A collection requires 3 keys, an `alias`, `path`, and `items`. The alias & path act just like a source, except that data will be available at `#{all}.all`. Items should be an object that responds to `#call` and returns an array of sources when given the data from the collection index. A collection for our example API:
159
+
160
+ ```ruby
161
+ activate :data_source do |c|
162
+ c.root = 'http://winteriscoming.com'
163
+ c.collection = {
164
+ alias: 'got_chars',
165
+ path: '/got/index.json',
166
+ items: Proc.new { |data|
167
+ data.map do |char|
168
+ {
169
+ alias: char['name'].to_slug,
170
+ path: char['url']
171
+ }
172
+ end
173
+ }
174
+ }
175
+ end
176
+ ```
177
+
178
+ You'll see I've used a proc to map our index into sources. The information is then accessible via the data object:
179
+
180
+ ```ruby
181
+ data.got_chars.all.map(&:name)
182
+ # => ['Eddard Stark', 'Hodor']
183
+
184
+ data.got_chars['eddard-stark'].quote
185
+ # => Winter is coming
186
+ ```
187
+
188
+
131
189
  # Testing
132
190
 
133
191
  ```bash
@@ -135,6 +193,7 @@ $ rspec
135
193
  ```
136
194
 
137
195
 
196
+
138
197
  # Contributing
139
198
 
140
199
  If there is any thing you'd like to contribute or fix, please:
@@ -0,0 +1,37 @@
1
+ set :environment, :test
2
+ set :show_exceptions, false
3
+
4
+
5
+ activate :data_source do |c|
6
+
7
+ c.root = File.join( Dir.pwd, 'remote_data' )
8
+
9
+ c.collection = {
10
+ alias: 'root',
11
+ path: 'root.json',
12
+ items: Proc.new { |data|
13
+ data.map do |d|
14
+ {
15
+ alias: d['slug'],
16
+ path: File.join('root', "#{d['slug']}.json")
17
+ }
18
+ end
19
+ }
20
+ }
21
+
22
+ end
23
+
24
+
25
+ activate :data_source do |c|
26
+
27
+ c.root = File.join( Dir.pwd, 'remote_data' )
28
+
29
+ c.collection = {
30
+ alias: 'extensionless',
31
+ path: 'extensionless/foo',
32
+ type: :json,
33
+ items: Proc.new { |d| [] }
34
+ }
35
+
36
+ end
37
+
@@ -0,0 +1,19 @@
1
+ set :environment, :test
2
+ set :show_exceptions, false
3
+
4
+ activate :data_source do |c|
5
+
6
+ c.root = File.join( Dir.pwd, 'remote_data' )
7
+
8
+ c.files = {
9
+ 'nested.json' => 'mounted/remote'
10
+ }
11
+
12
+ c.sources = [
13
+ {
14
+ alias: 'mounted',
15
+ path: 'nested.json'
16
+ }
17
+ ]
18
+
19
+ end
@@ -1,4 +1,2 @@
1
- require 'spec_helper'
2
-
3
- describe Middleman::DataSource do
1
+ RSpec.describe Middleman::DataSource do
4
2
  end
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Middleman::DataSource::Extension do
1
+ RSpec.describe Middleman::DataSource::Extension do
4
2
 
5
3
  it "is registered as an extension" do
6
4
  expect( Middleman::Extensions.registered[:data_source] ).to eq Middleman::DataSource::Extension
@@ -130,4 +128,52 @@ describe Middleman::DataSource::Extension do
130
128
  expect( remote_data ).to match_array [{"item"=>"one"},{"item"=>"two"}]
131
129
  end
132
130
 
131
+ context "with nested alias locations" do
132
+ before :each do
133
+ Given.fixture 'nested_alias'
134
+ @mm = Middleman::Fixture.app
135
+ end
136
+
137
+ after :each do
138
+ Given.cleanup!
139
+ end
140
+
141
+ it "puts data into the nested data location as though alias was a path" do
142
+ expect( @mm.data.mounted.remote.data ).to eq 'remote'
143
+ end
144
+
145
+ it "allows for overlapping paths" do
146
+ expect( @mm.data.mounted.data ).to eq 'remote'
147
+ end
148
+
149
+ end
150
+
151
+
152
+ context "with collection app" do
153
+ before :each do
154
+ Given.fixture 'collection'
155
+ @mm = Middleman::Fixture.app
156
+ end
157
+
158
+ after :each do
159
+ Given.cleanup!
160
+ end
161
+
162
+ it "makes collection items available at aliases" do
163
+ expect( @mm.data.root.john.title ).to eq "John"
164
+ expect( @mm.data.root.hodor.title ).to eq "Hodor"
165
+ end
166
+
167
+ it "makes collection index available at #all" do
168
+ expect( @mm.data.root.all.map(&:to_h) ).to match_array [{ "extra" => "info",
169
+ "slug" => "hodor" },
170
+ { "extra" => "info",
171
+ "slug" => "john" }]
172
+ end
173
+
174
+ it "allows passing an extension type" do
175
+ expect( @mm.data.extensionless.all.foo ).to eq "bar"
176
+ end
177
+ end
178
+
133
179
  end
@@ -1,6 +1,4 @@
1
- require 'spec_helper'
2
-
3
- describe Middleman::DataSource::VERSION do
1
+ RSpec.describe Middleman::DataSource::VERSION do
4
2
  it "has a version" do
5
3
  expect( Middleman::DataSource::VERSION >= '0.0.0' ).to eq true
6
4
  end
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.6.1
4
+ version: 0.7.1
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-07-15 00:00:00.000000000 Z
11
+ date: 2016-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: middleman
@@ -67,9 +67,11 @@ files:
67
67
  - readme.md
68
68
  - spec/fixtures/base/config.rb
69
69
  - spec/fixtures/borrower/config.rb
70
+ - spec/fixtures/collection/config.rb
70
71
  - spec/fixtures/files_as_hash/config.rb
71
72
  - spec/fixtures/imediate_use/config.rb
72
73
  - spec/fixtures/multiple_instances/config.rb
74
+ - spec/fixtures/nested_alias/config.rb
73
75
  - spec/fixtures/unsupported_extension/config.rb
74
76
  - spec/lib/middleman-data_source_spec.rb
75
77
  - spec/lib/middleman/data_source/extension_spec.rb
@@ -98,16 +100,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
100
  version: '0'
99
101
  requirements: []
100
102
  rubyforge_project:
101
- rubygems_version: 2.4.6
103
+ rubygems_version: 2.4.8
102
104
  signing_key:
103
105
  specification_version: 4
104
106
  summary: Allow for loading data in middleman from remote sources
105
107
  test_files:
106
108
  - spec/fixtures/base/config.rb
107
109
  - spec/fixtures/borrower/config.rb
110
+ - spec/fixtures/collection/config.rb
108
111
  - spec/fixtures/files_as_hash/config.rb
109
112
  - spec/fixtures/imediate_use/config.rb
110
113
  - spec/fixtures/multiple_instances/config.rb
114
+ - spec/fixtures/nested_alias/config.rb
111
115
  - spec/fixtures/unsupported_extension/config.rb
112
116
  - spec/lib/middleman/data_source/extension_spec.rb
113
117
  - spec/lib/middleman/data_source/version_spec.rb