middleman-data_source 0.6.1 → 0.7.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
  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