middleman-dato 0.0.1.rc4 → 0.0.1.rc5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/.rubocop.yml +1077 -0
- data/Gemfile +9 -5
- data/Rakefile +7 -9
- data/lib/dato/client.rb +6 -4
- data/lib/dato/field.rb +43 -0
- data/lib/dato/fields/belongs_to.rb +21 -0
- data/lib/dato/fields/file.rb +22 -0
- data/lib/dato/fields/seo.rb +37 -0
- data/lib/dato/meta_tags/article_modified_time.rb +2 -2
- data/lib/dato/meta_tags/article_publisher.rb +3 -3
- data/lib/dato/meta_tags/base.rb +5 -5
- data/lib/dato/meta_tags/description.rb +16 -7
- data/lib/dato/meta_tags/image.rb +4 -7
- data/lib/dato/meta_tags/og_locale.rb +1 -1
- data/lib/dato/meta_tags/og_meta_tag.rb +1 -1
- data/lib/dato/meta_tags/og_site_name.rb +1 -1
- data/lib/dato/meta_tags/og_type.rb +1 -1
- data/lib/dato/meta_tags/robots.rb +1 -4
- data/lib/dato/meta_tags/title.rb +1 -4
- data/lib/dato/meta_tags/twitter_card.rb +1 -1
- data/lib/dato/meta_tags/twitter_meta_tag.rb +1 -2
- data/lib/dato/meta_tags/twitter_site.rb +1 -1
- data/lib/dato/meta_tags/url.rb +1 -4
- data/lib/dato/meta_tags_builder.rb +12 -12
- data/lib/dato/middleman_extension.rb +19 -21
- data/lib/dato/record.rb +36 -25
- data/lib/dato/repo.rb +45 -43
- data/lib/middleman_extension.rb +1 -1
- data/middleman-dato.gemspec +13 -11
- data/spec/dato/field_spec.rb +110 -0
- data/spec/dato/meta_tags/article_modified_time_spec.rb +6 -6
- data/spec/dato/meta_tags/og_locale_spec.rb +4 -3
- data/spec/dato/record_spec.rb +104 -0
- data/spec/spec_helper.rb +5 -2
- metadata +11 -4
- data/lib/dato/file.rb +0 -16
- data/lib/dato/seo.rb +0 -31
@@ -1,18 +1,18 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "middleman-core"
|
2
|
+
require "dato/repo"
|
3
|
+
require "dato/meta_tags_builder"
|
4
|
+
require "ostruct"
|
5
5
|
|
6
6
|
module Dato
|
7
7
|
class MiddlemanExtension < ::Middleman::Extension
|
8
|
-
option :domain, nil,
|
9
|
-
option :token, nil,
|
10
|
-
option :api_host,
|
11
|
-
option :base_url, nil,
|
8
|
+
option :domain, nil, "Space domain"
|
9
|
+
option :token, nil, "Space API token"
|
10
|
+
option :api_host, "http://dato-api.herokuapp.com", "Space API token"
|
11
|
+
option :base_url, nil, "Website base URL"
|
12
12
|
|
13
13
|
attr_reader :records
|
14
14
|
|
15
|
-
def initialize(app, options_hash={}, &block)
|
15
|
+
def initialize(app, options_hash = {}, &block)
|
16
16
|
super
|
17
17
|
|
18
18
|
Repo.instance.connection_options = options
|
@@ -42,18 +42,16 @@ module Dato
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def dato_meta_tags(record)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
puts e.backtrace.join("\n")
|
56
|
-
end
|
45
|
+
builder = MetaTagsBuilder.new(
|
46
|
+
self,
|
47
|
+
Repo.instance.connection_options[:base_url],
|
48
|
+
Repo.instance.space,
|
49
|
+
record
|
50
|
+
)
|
51
|
+
builder.meta_tags
|
52
|
+
rescue Exception => e
|
53
|
+
puts e.message
|
54
|
+
puts e.backtrace.join("\n")
|
57
55
|
end
|
58
56
|
end
|
59
57
|
end
|
data/lib/dato/record.rb
CHANGED
@@ -1,15 +1,24 @@
|
|
1
|
-
require "
|
2
|
-
require "dato/
|
3
|
-
|
1
|
+
require "active_support/core_ext/hash/indifferent_access"
|
2
|
+
require "dato/field"
|
3
|
+
|
4
|
+
module Slugify
|
5
|
+
refine String do
|
6
|
+
def to_slug
|
7
|
+
downcase.strip.gsub(" ", "-").gsub(/[^\w-]/, "")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
4
11
|
|
5
12
|
module Dato
|
6
13
|
class Record
|
14
|
+
using Slugify
|
7
15
|
attr_reader :attributes, :fields, :content_type
|
8
16
|
|
9
17
|
def initialize(attributes, content_type)
|
10
18
|
@attributes = attributes.with_indifferent_access
|
11
19
|
@content_type = content_type
|
12
20
|
@fields = content_type[:fields].with_indifferent_access
|
21
|
+
@values = {}
|
13
22
|
end
|
14
23
|
|
15
24
|
def singleton?
|
@@ -24,28 +33,6 @@ module Dato
|
|
24
33
|
end
|
25
34
|
end
|
26
35
|
|
27
|
-
def read_attribute(name)
|
28
|
-
attribute = @attributes[name]
|
29
|
-
|
30
|
-
attribute = if fields[name][:localized]
|
31
|
-
attribute[I18n.locale]
|
32
|
-
else
|
33
|
-
attribute
|
34
|
-
end
|
35
|
-
|
36
|
-
return nil if !attribute
|
37
|
-
|
38
|
-
if %w(image file).include? fields[name][:field_type]
|
39
|
-
Dato::File.new(attribute)
|
40
|
-
elsif fields[name][:field_type] == "date"
|
41
|
-
Date.parse(attribute)
|
42
|
-
elsif fields[name][:field_type] == "seo"
|
43
|
-
Dato::Seo.new(attribute)
|
44
|
-
else
|
45
|
-
attribute
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
36
|
def id
|
50
37
|
@attributes[:id]
|
51
38
|
end
|
@@ -61,5 +48,29 @@ module Dato
|
|
61
48
|
super
|
62
49
|
end
|
63
50
|
end
|
51
|
+
|
52
|
+
def slug
|
53
|
+
field_name = content_type[:fields].select do |_name, data|
|
54
|
+
data[:field_type] == "title"
|
55
|
+
end.shift.first
|
56
|
+
|
57
|
+
"#{id}-#{send(field_name).to_slug}"
|
58
|
+
rescue NoMethodError
|
59
|
+
# there is no title
|
60
|
+
return nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def ==(other)
|
64
|
+
id == other.id
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def read_attribute(name)
|
70
|
+
unless @values.has_key?(name)
|
71
|
+
@values[name] = Field.value(attributes[name], fields[name])
|
72
|
+
end
|
73
|
+
@values[name]
|
74
|
+
end
|
64
75
|
end
|
65
76
|
end
|
data/lib/dato/repo.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "singleton"
|
2
|
+
require "active_support/inflector/methods"
|
3
|
+
require "dato/client"
|
4
|
+
require "dato/record"
|
5
5
|
|
6
6
|
module Dato
|
7
7
|
class Repo
|
8
8
|
include Singleton
|
9
9
|
|
10
10
|
attr_reader :client, :space, :content_types, :records_per_content_type,
|
11
|
-
:connection_options
|
11
|
+
:connection_options, :records
|
12
12
|
|
13
13
|
def connection_options=(options)
|
14
14
|
@connection_options = options
|
@@ -23,43 +23,40 @@ module Dato
|
|
23
23
|
space_response = client.space.with_indifferent_access
|
24
24
|
@space = space_response[:data]
|
25
25
|
@content_types = prepare_content_types(space_response)
|
26
|
-
@
|
26
|
+
@records = client.records.with_indifferent_access
|
27
|
+
@records_per_content_type = group_by_content_type(@records)
|
27
28
|
end
|
28
29
|
|
29
30
|
def prepare_content_types(data)
|
30
31
|
data = data.with_indifferent_access
|
31
32
|
|
32
|
-
|
33
|
-
data[:data][:links][:content_types][:linkage]
|
34
|
-
|
35
|
-
[
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
end
|
33
|
+
Hash[
|
34
|
+
data[:data][:links][:content_types][:linkage].map do |content_type|
|
35
|
+
[
|
36
|
+
content_type[:id],
|
37
|
+
content_type_data(content_type[:id], data[:included])
|
38
|
+
]
|
39
|
+
end
|
40
40
|
]
|
41
41
|
end
|
42
42
|
|
43
43
|
def content_type_data(content_type, data)
|
44
|
-
content_type = data
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
content_type = data.
|
45
|
+
detect do |item|
|
46
|
+
item[:type] == "content_type" && item[:id] == content_type
|
47
|
+
end
|
48
48
|
|
49
|
-
field_ids = content_type[:links][:fields][:linkage]
|
50
|
-
|
49
|
+
field_ids = content_type[:links][:fields][:linkage].
|
50
|
+
map { |field| field[:id] }
|
51
51
|
|
52
52
|
fields = Hash[
|
53
|
-
data
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
field[:attributes]
|
61
|
-
]
|
62
|
-
end
|
53
|
+
data.
|
54
|
+
select do |item|
|
55
|
+
item[:type] == "field" && field_ids.include?(item[:id])
|
56
|
+
end.
|
57
|
+
map do |field|
|
58
|
+
[field[:attributes][:api_key], field[:attributes]]
|
59
|
+
end
|
63
60
|
]
|
64
61
|
|
65
62
|
{
|
@@ -68,19 +65,27 @@ module Dato
|
|
68
65
|
}
|
69
66
|
end
|
70
67
|
|
68
|
+
def find(id)
|
69
|
+
record = records[:data].detect { |r| r[:id] == id }
|
70
|
+
normalize_record(record) unless record.nil?
|
71
|
+
end
|
72
|
+
|
73
|
+
def find_all(ids)
|
74
|
+
ids.map { |id| find(id) }
|
75
|
+
end
|
76
|
+
|
71
77
|
def group_by_content_type(data)
|
72
78
|
Hash[
|
73
79
|
content_types.map do |id, content_type|
|
74
|
-
records = data
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
80
|
+
records = data[:data].
|
81
|
+
select do |record|
|
82
|
+
record[:links][:content_type][:linkage][:id] == id
|
83
|
+
end
|
79
84
|
|
80
85
|
if content_type[:singleton]
|
81
|
-
[
|
86
|
+
[id, records.any? ? normalize_record(records.first) : nil]
|
82
87
|
else
|
83
|
-
[
|
88
|
+
[id.pluralize, group_by_id(records)]
|
84
89
|
end
|
85
90
|
end
|
86
91
|
]
|
@@ -88,17 +93,14 @@ module Dato
|
|
88
93
|
|
89
94
|
def group_by_id(records)
|
90
95
|
Hash[
|
91
|
-
records
|
92
|
-
|
93
|
-
|
94
|
-
[ id, normalize_record(records.first) ]
|
95
|
-
end
|
96
|
+
records.
|
97
|
+
group_by { |record| record[:id] }.
|
98
|
+
map { |id, r| [id, normalize_record(r.first)] }
|
96
99
|
]
|
97
100
|
end
|
98
101
|
|
99
102
|
def normalize_record(record)
|
100
103
|
content_type = record[:links][:content_type][:linkage][:id]
|
101
|
-
|
102
104
|
Record.new(
|
103
105
|
record[:attributes].merge(id: record[:id]),
|
104
106
|
content_types[content_type]
|
data/lib/middleman_extension.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require "middleman-dato"
|
data/middleman-dato.gemspec
CHANGED
@@ -2,18 +2,20 @@
|
|
2
2
|
$:.push File.expand_path("../lib", __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
|
-
s.name
|
6
|
-
s.version
|
7
|
-
s.platform
|
8
|
-
s.authors
|
9
|
-
s.email
|
10
|
-
s.homepage
|
11
|
-
s.summary
|
12
|
-
s.description =
|
5
|
+
s.name = "middleman-dato"
|
6
|
+
s.version = "0.0.1.rc5"
|
7
|
+
s.platform = Gem::Platform::RUBY
|
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
|
-
s.files
|
15
|
-
s.test_files
|
16
|
-
s.executables
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map do |f|
|
17
|
+
File.basename(f)
|
18
|
+
end
|
17
19
|
s.require_paths = ["lib"]
|
18
20
|
|
19
21
|
s.add_runtime_dependency("middleman-core", [">= 3.3.12"])
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe Dato::Field do
|
4
|
+
describe ".value" do
|
5
|
+
let(:attribute) { "bar" }
|
6
|
+
let(:field) { { field_type: "text" } }
|
7
|
+
|
8
|
+
it "returns the field value" do
|
9
|
+
expect(described_class.value(attribute, field)).to eq("bar")
|
10
|
+
end
|
11
|
+
|
12
|
+
context "if the field is marked to be localizable" do
|
13
|
+
let(:field) { { field_type: "text", localized: true } }
|
14
|
+
|
15
|
+
before do
|
16
|
+
allow(I18n).to receive(:locale).and_return("en")
|
17
|
+
end
|
18
|
+
|
19
|
+
context "if it has a translation for the current locale" do
|
20
|
+
let(:attribute) { { en: "baz" } }
|
21
|
+
|
22
|
+
it "returns the field value translation" do
|
23
|
+
expect(described_class.value(attribute, field)).to eq("baz")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "else" do
|
28
|
+
let(:attribute) { { fr: "baz" } }
|
29
|
+
|
30
|
+
it "returns nil" do
|
31
|
+
expect(described_class.value(attribute, field)).to be_nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "field types" do
|
37
|
+
let(:client) { double("Client") }
|
38
|
+
|
39
|
+
before do
|
40
|
+
allow(Dato::Client).to receive(:new).and_return(client)
|
41
|
+
allow(client).to receive(:records).and_return(data: [
|
42
|
+
{
|
43
|
+
id: 1,
|
44
|
+
attributes: {},
|
45
|
+
links: {
|
46
|
+
content_type: {
|
47
|
+
linkage: {
|
48
|
+
id: "foo",
|
49
|
+
type: "content_type"
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
])
|
55
|
+
allow(client).to receive(:space).and_return(
|
56
|
+
data: {
|
57
|
+
links: {
|
58
|
+
content_types: {
|
59
|
+
linkage: [
|
60
|
+
{
|
61
|
+
id: "foo",
|
62
|
+
type: "content_type"
|
63
|
+
}
|
64
|
+
]
|
65
|
+
}
|
66
|
+
}
|
67
|
+
},
|
68
|
+
included: [
|
69
|
+
{
|
70
|
+
attributes: {
|
71
|
+
name: "foo",
|
72
|
+
singleton: false
|
73
|
+
},
|
74
|
+
id: "foo",
|
75
|
+
links: {
|
76
|
+
fields: {
|
77
|
+
linkage: []
|
78
|
+
},
|
79
|
+
singleton_record: {
|
80
|
+
linkage: nil
|
81
|
+
}
|
82
|
+
},
|
83
|
+
type: "content_type"
|
84
|
+
}
|
85
|
+
]
|
86
|
+
)
|
87
|
+
|
88
|
+
Dato::Repo.instance.connection_options = {}
|
89
|
+
Dato::Repo.instance.sync!
|
90
|
+
end
|
91
|
+
|
92
|
+
[
|
93
|
+
{ type: "image", value: {}, result: Dato::Fields::File.new({}) },
|
94
|
+
{ type: "file", value: {}, result: Dato::Fields::File.new({}) },
|
95
|
+
{ type: "date", value: "2015-06-09", result: Date.new(2015, 6, 9) },
|
96
|
+
{ type: "seo", value: {}, result: Dato::Fields::Seo.new({}) },
|
97
|
+
{ type: "belongs_to", value: 1, result: Dato::Record.new({ id: 1 }, fields: {}) }
|
98
|
+
].each do |data|
|
99
|
+
context "if the field has '#{data[:type]}' type" do
|
100
|
+
let(:attribute) { data[:value] }
|
101
|
+
let(:field) { { field_type: data[:type] } }
|
102
|
+
|
103
|
+
it "converts the value to the specific type" do
|
104
|
+
expect(described_class.value(attribute, field)).to eq(data[:result])
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -1,21 +1,21 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
module Dato::MetaTags
|
4
4
|
RSpec.describe ArticleModifiedTime do
|
5
|
-
subject(:meta_tag) { described_class.new(builder, space, record) }
|
5
|
+
subject(:meta_tag) { described_class.new(builder, base_url, space, record) }
|
6
6
|
let(:builder) { MockBuilder.new }
|
7
|
+
let(:base_url) { nil }
|
7
8
|
let(:space) { nil }
|
8
9
|
let(:record) do
|
9
10
|
double("Record", updated_at: Time.now, singleton?: false)
|
10
11
|
end
|
11
12
|
|
12
|
-
describe
|
13
|
-
context
|
14
|
-
it
|
13
|
+
describe ".value" do
|
14
|
+
context "if record is not singleton" do
|
15
|
+
it "returns an ISO 8601 time representation" do
|
15
16
|
expect(meta_tag.value).not_to be_nil
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
21
|
-
|