middleman-dato 0.0.1.rc12 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +7 -0
- data/.rspec +2 -0
- data/.rubocop.yml +9 -1070
- data/Gemfile +8 -8
- data/Rakefile +14 -5
- data/foo.rb +12 -0
- data/lib/dato/client.rb +14 -9
- data/lib/dato/entities_repo.rb +43 -0
- data/lib/dato/field_type/boolean.rb +9 -0
- data/lib/dato/field_type/date.rb +9 -0
- data/lib/dato/field_type/date_time.rb +9 -0
- data/lib/dato/field_type/file.rb +30 -0
- data/lib/dato/field_type/float.rb +9 -0
- data/lib/dato/field_type/image.rb +23 -0
- data/lib/dato/field_type/integer.rb +9 -0
- data/lib/dato/field_type/lat_lon.rb +16 -0
- data/lib/dato/field_type/link.rb +9 -0
- data/lib/dato/field_type/links.rb +9 -0
- data/lib/dato/field_type/seo.rb +21 -0
- data/lib/dato/field_type/string.rb +9 -0
- data/lib/dato/field_type/text.rb +9 -0
- data/lib/dato/field_type/video.rb +48 -0
- data/lib/dato/json_api_entity.rb +75 -0
- data/lib/dato/meta_tags/article_modified_time.rb +3 -3
- data/lib/dato/meta_tags/article_publisher.rb +3 -3
- data/lib/dato/meta_tags/base.rb +12 -19
- data/lib/dato/meta_tags/description.rb +4 -4
- data/lib/dato/meta_tags/image.rb +5 -8
- data/lib/dato/meta_tags/og_locale.rb +2 -2
- data/lib/dato/meta_tags/og_meta_tag.rb +2 -4
- data/lib/dato/meta_tags/og_site_name.rb +2 -2
- data/lib/dato/meta_tags/og_type.rb +5 -5
- data/lib/dato/meta_tags/robots.rb +2 -4
- data/lib/dato/meta_tags/title.rb +5 -4
- data/lib/dato/meta_tags/twitter_card.rb +3 -3
- data/lib/dato/meta_tags/twitter_meta_tag.rb +2 -4
- data/lib/dato/meta_tags/twitter_site.rb +2 -2
- data/lib/dato/meta_tags/url.rb +4 -4
- data/lib/dato/meta_tags_builder.rb +13 -13
- data/lib/dato/middleman_extension.rb +15 -23
- data/lib/dato/record.rb +77 -46
- data/lib/dato/records_repo.rb +106 -0
- data/lib/dato/space.rb +36 -0
- data/lib/middleman-dato.rb +5 -2
- data/middleman-dato.gemspec +14 -13
- data/spec/dato/entities_repo_spec.rb +41 -0
- data/spec/dato/field_type/file_spec.rb +20 -0
- data/spec/dato/field_type/image_spec.rb +24 -0
- data/spec/dato/field_type/lat_lon_spec.rb +18 -0
- data/spec/dato/field_type/seo_spec.rb +31 -0
- data/spec/dato/field_type/video_spec.rb +32 -0
- data/spec/dato/json_api_entity_spec.rb +123 -0
- data/spec/dato/meta_tags/article_modified_time_spec.rb +16 -14
- data/spec/dato/meta_tags/image_spec.rb +39 -0
- data/spec/dato/meta_tags/og_locale_spec.rb +14 -12
- data/spec/dato/record_spec.rb +137 -78
- data/spec/dato/records_repo_spec.rb +125 -0
- data/spec/spec_helper.rb +14 -12
- metadata +58 -13
- data/lib/dato/field.rb +0 -43
- data/lib/dato/fields/belongs_to.rb +0 -21
- data/lib/dato/fields/file.rb +0 -22
- data/lib/dato/fields/seo.rb +0 -37
- data/lib/dato/repo.rb +0 -111
- data/lib/middleman_extension.rb +0 -1
- data/spec/dato/field_spec.rb +0 -110
data/lib/dato/record.rb
CHANGED
@@ -1,77 +1,108 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'forwardable'
|
2
|
+
require 'active_support/inflector/transliterate'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
def to_slug
|
7
|
-
downcase.strip.gsub(" ", "-").gsub(/[^\w-]/, "")
|
8
|
-
end
|
9
|
-
end
|
4
|
+
Dir[File.dirname(__FILE__) + '/field_type/*.rb'].each do |file|
|
5
|
+
require file
|
10
6
|
end
|
11
7
|
|
12
8
|
module Dato
|
13
9
|
class Record
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
@
|
21
|
-
@
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
attr_reader :entity
|
13
|
+
def_delegators :entity, :id, :type
|
14
|
+
|
15
|
+
def initialize(entity, records_repo)
|
16
|
+
@entity = entity
|
17
|
+
@records_repo = records_repo
|
18
|
+
end
|
19
|
+
|
20
|
+
def slug
|
21
|
+
if singleton?
|
22
|
+
content_type.api_key.humanize.parameterize
|
23
|
+
elsif title_attribute
|
24
|
+
"#{id}-#{send(title_attribute).parameterize}"
|
25
|
+
else
|
26
|
+
id.to_s
|
27
|
+
end
|
22
28
|
end
|
23
29
|
|
24
30
|
def singleton?
|
25
|
-
|
31
|
+
content_type.singleton
|
26
32
|
end
|
27
33
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
34
|
+
def content_type
|
35
|
+
entity.content_type
|
36
|
+
end
|
37
|
+
|
38
|
+
def fields
|
39
|
+
content_type.fields.sort_by(&:position)
|
40
|
+
end
|
41
|
+
|
42
|
+
def attributes
|
43
|
+
fields.each_with_object({}) do |field, acc|
|
44
|
+
acc[field.api_key.to_sym] = send(field.api_key)
|
33
45
|
end
|
34
46
|
end
|
35
47
|
|
36
|
-
def
|
37
|
-
|
48
|
+
def position
|
49
|
+
entity.position
|
38
50
|
end
|
39
51
|
|
40
52
|
def updated_at
|
41
|
-
Time.parse(
|
53
|
+
Time.parse(entity.updated_at)
|
42
54
|
end
|
43
55
|
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
else
|
48
|
-
super
|
49
|
-
end
|
56
|
+
def to_s
|
57
|
+
api_key = content_type.api_key
|
58
|
+
"#<Record id=#{id} content_type=#{api_key} attributes=#{attributes}>"
|
50
59
|
end
|
60
|
+
alias inspect to_s
|
51
61
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
rescue NoMethodError
|
59
|
-
# there is no title
|
60
|
-
return nil
|
62
|
+
def title_attribute
|
63
|
+
title_field = fields.find do |field|
|
64
|
+
field.field_type == 'string' &&
|
65
|
+
field.appeareance[:type] == 'title'
|
66
|
+
end
|
67
|
+
title_field && title_field.api_key
|
61
68
|
end
|
62
69
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
70
|
+
def respond_to?(method, include_private = false)
|
71
|
+
field = fields.find { |f| f.api_key.to_sym == method }
|
72
|
+
if field
|
73
|
+
true
|
66
74
|
else
|
67
|
-
|
75
|
+
super
|
68
76
|
end
|
69
77
|
end
|
70
78
|
|
71
79
|
private
|
72
80
|
|
73
|
-
def read_attribute(
|
74
|
-
|
81
|
+
def read_attribute(method, field)
|
82
|
+
field_type = field.field_type
|
83
|
+
type_klass_name = "::Dato::FieldType::#{field_type.camelize}"
|
84
|
+
type_klass = type_klass_name.safe_constantize
|
85
|
+
|
86
|
+
if type_klass
|
87
|
+
value = if field.localized
|
88
|
+
(entity.send(method) || {})[I18n.locale]
|
89
|
+
else
|
90
|
+
entity.send(method)
|
91
|
+
end
|
92
|
+
|
93
|
+
value && type_klass.parse(value, @records_repo)
|
94
|
+
else
|
95
|
+
raise "Cannot convert field `#{method}` of type `#{field_type}`"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def method_missing(method, *arguments, &block)
|
100
|
+
field = fields.find { |f| f.api_key.to_sym == method }
|
101
|
+
if field && arguments.empty?
|
102
|
+
read_attribute(method, field)
|
103
|
+
else
|
104
|
+
super
|
105
|
+
end
|
75
106
|
end
|
76
107
|
end
|
77
108
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'active_support/core_ext/string'
|
2
|
+
require 'dato/record'
|
3
|
+
|
4
|
+
module Dato
|
5
|
+
class RecordsRepo
|
6
|
+
attr_reader :entities_repo, :collections_by_type
|
7
|
+
|
8
|
+
def initialize(entities_repo)
|
9
|
+
@entities_repo = entities_repo
|
10
|
+
@collections_by_type = {}
|
11
|
+
|
12
|
+
build_collections_by_type!
|
13
|
+
end
|
14
|
+
|
15
|
+
def find(id)
|
16
|
+
collections_by_type.values.flatten.find do |record|
|
17
|
+
record && record.id == id
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def respond_to?(method, include_private = false)
|
22
|
+
if collections_by_type.key?(method)
|
23
|
+
true
|
24
|
+
else
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def content_type_key(content_type)
|
32
|
+
api_key = content_type.api_key
|
33
|
+
if content_type.singleton
|
34
|
+
[api_key.to_sym, true]
|
35
|
+
else
|
36
|
+
[api_key.pluralize.to_sym, false]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def build_collections_by_type!
|
41
|
+
content_type_entities.each do |content_type|
|
42
|
+
key, singleton = content_type_key(content_type)
|
43
|
+
@collections_by_type[key] = if singleton
|
44
|
+
nil
|
45
|
+
else
|
46
|
+
RecordCollection.new
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
record_entities.each do |record_entity|
|
51
|
+
record = Record.new(record_entity, self)
|
52
|
+
|
53
|
+
key, singleton = content_type_key(record_entity.content_type)
|
54
|
+
if singleton
|
55
|
+
@collections_by_type[key] = record
|
56
|
+
else
|
57
|
+
@collections_by_type[key].push record
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def content_type_entities
|
63
|
+
entities_repo.find_entities_of_type('content_type')
|
64
|
+
end
|
65
|
+
|
66
|
+
def record_entities
|
67
|
+
entities_repo.find_entities_of_type('record')
|
68
|
+
end
|
69
|
+
|
70
|
+
def method_missing(method, *arguments, &block)
|
71
|
+
if collections_by_type.key?(method) && arguments.empty?
|
72
|
+
collections_by_type[method]
|
73
|
+
else
|
74
|
+
super
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
class RecordCollection < Array
|
79
|
+
def each(&block)
|
80
|
+
if block && block.arity == 2
|
81
|
+
each_with_object({}) do |record, acc|
|
82
|
+
acc[record.id] = record
|
83
|
+
end.each(&block)
|
84
|
+
else
|
85
|
+
super(&block)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def [](id)
|
90
|
+
if id.is_a? String
|
91
|
+
find { |record| record.id == id }
|
92
|
+
else
|
93
|
+
super(id)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def keys
|
98
|
+
map(&:id)
|
99
|
+
end
|
100
|
+
|
101
|
+
def values
|
102
|
+
to_a
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/lib/dato/space.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'dato/client'
|
2
|
+
require 'dato/entities_repo'
|
3
|
+
require 'dato/records_repo'
|
4
|
+
|
5
|
+
module Dato
|
6
|
+
class Space
|
7
|
+
attr_reader :options
|
8
|
+
attr_reader :entities_repo
|
9
|
+
attr_reader :records_repo
|
10
|
+
|
11
|
+
def initialize(options)
|
12
|
+
@options = options
|
13
|
+
@entities_repo = EntitiesRepo.new
|
14
|
+
@records_repo = RecordsRepo.new(@entities_repo)
|
15
|
+
end
|
16
|
+
|
17
|
+
def refresh!
|
18
|
+
@entities_repo = EntitiesRepo.new(client.space, client.records)
|
19
|
+
@records_repo = RecordsRepo.new(@entities_repo)
|
20
|
+
end
|
21
|
+
|
22
|
+
def entity
|
23
|
+
@entities_repo.find_entities_of_type('space').first
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def client
|
29
|
+
@client ||= Client.new(
|
30
|
+
options[:api_host],
|
31
|
+
options[:domain],
|
32
|
+
options[:token]
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/middleman-dato.rb
CHANGED
data/middleman-dato.gemspec
CHANGED
@@ -1,25 +1,26 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
2
|
+
$LOAD_PATH.push File.expand_path('../lib', __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
|
-
s.name =
|
6
|
-
s.version =
|
5
|
+
s.name = 'middleman-dato'
|
6
|
+
s.version = '0.5.0'
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
|
-
s.authors = [
|
9
|
-
s.email = [
|
10
|
-
s.homepage =
|
11
|
-
s.summary =
|
12
|
-
s.description =
|
8
|
+
s.authors = ['Stefano Verna']
|
9
|
+
s.email = ['s.verna@cantierecreativo.net']
|
10
|
+
s.homepage = 'http://cantierecreativo.net'
|
11
|
+
s.summary = 'Fetches data from a Dato space'
|
12
|
+
s.description = 'Fetches data from a Dato space'
|
13
13
|
|
14
14
|
s.files = `git ls-files`.split("\n")
|
15
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
16
|
s.executables = `git ls-files -- bin/*`.split("\n").map do |f|
|
17
17
|
File.basename(f)
|
18
18
|
end
|
19
|
-
s.require_paths = [
|
19
|
+
s.require_paths = ['lib']
|
20
20
|
|
21
|
-
s.add_runtime_dependency(
|
22
|
-
s.add_runtime_dependency(
|
23
|
-
s.add_runtime_dependency(
|
24
|
-
s.add_runtime_dependency(
|
21
|
+
s.add_runtime_dependency('middleman-core', ['>= 3.3.12'])
|
22
|
+
s.add_runtime_dependency('faraday', ['>= 0.9.0'])
|
23
|
+
s.add_runtime_dependency('faraday_middleware', ['>= 0.9.0'])
|
24
|
+
s.add_runtime_dependency('imgix', ['>= 0.3.1'])
|
25
|
+
s.add_runtime_dependency('video_embed')
|
25
26
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'dato/json_api_entity'
|
2
|
+
|
3
|
+
module Dato
|
4
|
+
RSpec.describe EntitiesRepo do
|
5
|
+
subject(:source) { described_class.new(payload) }
|
6
|
+
|
7
|
+
describe '#entities' do
|
8
|
+
context 'a payload with a data key' do
|
9
|
+
context 'object' do
|
10
|
+
let(:payload) do
|
11
|
+
{ data: { id: 'bar', type: 'record' } }
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'inserts the object into entities' do
|
15
|
+
expect(source.entities['record']['bar']).to be_a JsonApiEntity
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'array' do
|
20
|
+
let(:payload) do
|
21
|
+
{ data: [{ id: 'bar', type: 'record' }] }
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'inserts the objects into entities' do
|
25
|
+
expect(source.entities['record']['bar']).to be_a JsonApiEntity
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'a payload with an included key' do
|
31
|
+
let(:payload) do
|
32
|
+
{ included: [{ id: 'bar', type: 'record' }] }
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'inserts the objects into entities' do
|
36
|
+
expect(source.entities['record']['bar']).to be_a JsonApiEntity
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Dato
|
2
|
+
module FieldType
|
3
|
+
RSpec.describe Dato::FieldType::File do
|
4
|
+
subject(:file) { described_class.parse(attributes, nil) }
|
5
|
+
let(:attributes) do
|
6
|
+
{
|
7
|
+
path: '/foo.png',
|
8
|
+
format: 'jpg',
|
9
|
+
size: 4000
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'responds to path, format and size methods' do
|
14
|
+
expect(file.path).to eq '/foo.png'
|
15
|
+
expect(file.format).to eq 'jpg'
|
16
|
+
expect(file.size).to eq 4000
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Dato
|
2
|
+
module FieldType
|
3
|
+
RSpec.describe Image do
|
4
|
+
subject(:image) { described_class.parse(attributes, nil) }
|
5
|
+
let(:attributes) do
|
6
|
+
{
|
7
|
+
path: '/foo.png',
|
8
|
+
format: 'jpg',
|
9
|
+
size: 4000,
|
10
|
+
width: 20,
|
11
|
+
height: 20
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'responds to path, format, size, width and height' do
|
16
|
+
expect(image.path).to eq '/foo.png'
|
17
|
+
expect(image.format).to eq 'jpg'
|
18
|
+
expect(image.size).to eq 4000
|
19
|
+
expect(image.width).to eq 20
|
20
|
+
expect(image.height).to eq 20
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Dato
|
2
|
+
module FieldType
|
3
|
+
RSpec.describe LatLon do
|
4
|
+
subject(:latlon) { described_class.parse(attributes, nil) }
|
5
|
+
let(:attributes) do
|
6
|
+
{
|
7
|
+
latitude: 12,
|
8
|
+
longitude: 10
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'responds to latitude and longitude methods' do
|
13
|
+
expect(latlon.latitude).to eq 12
|
14
|
+
expect(latlon.longitude).to eq 10
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|