jekyll-airtable 0.3.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -3
- data/README.md +26 -9
- data/jekyll-airtable.gemspec +2 -1
- data/lib/jekyll-airtable/version.rb +1 -1
- data/lib/jekyll/airtable_fetcher.rb +98 -23
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8823b75bac320ee91a3c9e2047d939f454dbe5ee
|
4
|
+
data.tar.gz: d05f45a5710a493dca9bafcfe944a29ca5065ad8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de5626a0609472cf9214c3fd87050eed7af1dae916ae7a3f0265911e6cba54763c2d0ed5009aeadf41e85fe593b3f1a609eaea1d1fe06b75f389760567cfb914
|
7
|
+
data.tar.gz: '09e5a93c147c5bb9aa19fd92f77896206dbcaeaede8563b1cde77796c844958b9e0cc98467e5a32cf4a67d482f921deac7c76157597f47b0974e577b611fb04d'
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
jekyll-airtable (0.
|
4
|
+
jekyll-airtable (0.4.1)
|
5
5
|
faraday (~> 0.11.0)
|
6
6
|
faraday_middleware (~> 0.10.1)
|
7
|
+
hashie
|
7
8
|
jekyll (~> 3.3)
|
8
9
|
|
9
10
|
GEM
|
@@ -26,10 +27,11 @@ GEM
|
|
26
27
|
faraday (>= 0.7.4, < 1.0)
|
27
28
|
ffi (1.9.25)
|
28
29
|
forwardable-extended (2.6.0)
|
30
|
+
hashie (3.6.0)
|
29
31
|
http_parser.rb (0.6.0)
|
30
32
|
i18n (0.9.5)
|
31
33
|
concurrent-ruby (~> 1.0)
|
32
|
-
jekyll (3.8.
|
34
|
+
jekyll (3.8.4)
|
33
35
|
addressable (~> 2.4)
|
34
36
|
colorator (~> 1.0)
|
35
37
|
em-websocket (~> 0.5)
|
@@ -77,7 +79,7 @@ GEM
|
|
77
79
|
rspec-support (3.8.0)
|
78
80
|
ruby_dep (1.5.0)
|
79
81
|
safe_yaml (1.0.4)
|
80
|
-
sass (3.
|
82
|
+
sass (3.6.0)
|
81
83
|
sass-listen (~> 4.0.0)
|
82
84
|
sass-listen (4.0.0)
|
83
85
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
data/README.md
CHANGED
@@ -27,11 +27,11 @@ run bundle install again
|
|
27
27
|
.env
|
28
28
|
```
|
29
29
|
|
30
|
-
3. Copy the .env.example in this repo to the root of your project, rename it to .env
|
31
|
-
4. Set
|
30
|
+
3. Copy the .env.example in this repo to the root of your project, rename it to .env.
|
31
|
+
4. Set your Airtable API Key in the .env
|
32
32
|
|
33
33
|
```
|
34
|
-
|
34
|
+
AIRTABLE_API_KEY='your_airtable_api_key'
|
35
35
|
```
|
36
36
|
|
37
37
|
5. You need to add a custom plugin to get the dotenv to work, you do this by creating a folder ```_plugins``` (if does not exist already) inside your Jekyll repo
|
@@ -49,10 +49,7 @@ module Jekyll
|
|
49
49
|
Dotenv.overload
|
50
50
|
site.config['env'] = Dotenv.overload
|
51
51
|
|
52
|
-
site.config['SYNC_WITH_AIRTABLE'] = ENV['SYNC_WITH_AIRTABLE']
|
53
52
|
site.config['AIRTABLE_API_KEY'] = ENV['AIRTABLE_API_KEY']
|
54
|
-
site.config['AIRTABLE_BASE_UID'] = ENV['AIRTABLE_BASE_UID']
|
55
|
-
site.config['AIRTABLE_TABLE_NAMES'] = ENV['AIRTABLE_TABLE_NAMES'].split(',').map(&:strip)
|
56
53
|
end
|
57
54
|
end
|
58
55
|
end
|
@@ -60,11 +57,21 @@ end
|
|
60
57
|
|
61
58
|
Now the secret keys can be accessed by Jekyll without being visible to the public.
|
62
59
|
|
63
|
-
7. Now, you need to declare the plugins in the config.yml
|
60
|
+
7. Now, you need to declare and hook the plugins in the config.yml
|
64
61
|
```yml
|
65
62
|
plugins:
|
66
63
|
- jekyll-airtable
|
67
64
|
- environment_variables_generator
|
65
|
+
|
66
|
+
airtable:
|
67
|
+
enable_sync: true
|
68
|
+
base_uid: 'appp7C1MblPCnMePn'
|
69
|
+
tables:
|
70
|
+
- name: 'Use Cases'
|
71
|
+
- name: 'Whitepapers'
|
72
|
+
- name: 'Quotes'
|
73
|
+
long_text_columns:
|
74
|
+
- 'column name'
|
68
75
|
```
|
69
76
|
|
70
77
|
8. Finally, you can execute the plugin using ```sh bundle exec jekyll serve ``` or ```sh bundle exec jekyll build ```
|
@@ -80,8 +87,6 @@ collections:
|
|
80
87
|
output: true
|
81
88
|
whitepapers:
|
82
89
|
output: true
|
83
|
-
tutorials:
|
84
|
-
output: true
|
85
90
|
|
86
91
|
defaults:
|
87
92
|
- scope:
|
@@ -90,6 +95,18 @@ defaults:
|
|
90
95
|
layout: "page" # any jekyll layout file you already have in the _layouts that you want to use for this collection type.
|
91
96
|
```
|
92
97
|
|
98
|
+
|
99
|
+
## Conventions
|
100
|
+
|
101
|
+
There are a number of "enforced" conventions you have to know and can take advantage of.
|
102
|
+
|
103
|
+
1. By default, the slug of the record (which is the file name) come from this sources, in order of priority: 1) The column labelled 'Slug' / 'slug' in your Airtable table, 2) The primary key of each row (the first column on each table), 3) or the Airtable UID of the record. So if you want to set each record's slug manually, you can do so by creating slug column in your Airtable table.**GOTCHA:** Should slugs that are derived from priority 1 and 2 are both longer than 100 char, then it will automatically use the Airtable UID.
|
104
|
+
|
105
|
+
2. Attachments are not copied into your Jekyll repo but their informations, such as url and so on, will be stored in "_data/airtable/attachments.yml_" folder, if none exist before, this plugin will automatically create it for you.
|
106
|
+
|
107
|
+
|
108
|
+
3. Long text with paragraphs are now supported.
|
109
|
+
|
93
110
|
## Development
|
94
111
|
|
95
112
|
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/jekyll-airtable.gemspec
CHANGED
@@ -30,5 +30,6 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_development_dependency "dotenv"
|
31
31
|
spec.add_dependency 'faraday', '~> 0.11.0'
|
32
32
|
spec.add_dependency 'faraday_middleware', '~> 0.10.1'
|
33
|
-
spec.add_dependency "jekyll", "~> 3.3"
|
33
|
+
spec.add_dependency "jekyll", "~> 3.3"
|
34
|
+
spec.add_dependency "hashie"
|
34
35
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require "json"
|
2
2
|
require 'fileutils'
|
3
3
|
require 'yaml'
|
4
|
+
require 'hashie'
|
5
|
+
require 'uri'
|
4
6
|
|
5
7
|
module Jekyll
|
6
8
|
class AirtableFetcher < Jekyll::Generator
|
@@ -8,44 +10,42 @@ module Jekyll
|
|
8
10
|
priority :lowest
|
9
11
|
|
10
12
|
def generate(site)
|
11
|
-
|
12
|
-
return false if
|
13
|
-
|
14
|
-
setup_directories
|
13
|
+
jekyll_config = Hashie::Mash.new(site.config)
|
14
|
+
return false if should_generate_be_prevented?(jekyll_config)
|
15
15
|
# For storing hashes of attachments that will be saved to the data file
|
16
16
|
@attachments_hash = {}
|
17
|
+
setup_directories
|
17
18
|
|
18
|
-
|
19
|
-
config.api_key = site.config['AIRTABLE_API_KEY']
|
20
|
-
end
|
21
|
-
|
22
|
-
client = Airtable.client(base_uid: site.config['AIRTABLE_BASE_UID'])
|
19
|
+
client = setting_up_airtable_client
|
23
20
|
|
24
|
-
|
21
|
+
@table_names.each do |table_name|
|
25
22
|
records = client.list_records(table_name: table_name)
|
26
23
|
next if records.size == 0
|
24
|
+
|
25
|
+
if records.class.name == 'Hash'
|
26
|
+
error = records["error"]
|
27
|
+
if error.present?
|
28
|
+
puts error['message']
|
29
|
+
next
|
30
|
+
end
|
31
|
+
end
|
27
32
|
|
28
33
|
directory_name = "collections/_" + to_snake(table_name)
|
29
34
|
Dir.mkdir(directory_name) unless File.exists?(directory_name)
|
30
35
|
|
31
36
|
records.each do |record|
|
32
37
|
fields = record['fields']
|
33
|
-
# We use the first field as the primary key
|
34
|
-
# Then find the value of the primary key to be stored as the slug, which
|
35
|
-
# will be used as file name and the path to the record in the url.
|
36
|
-
# However, if the record has field called 'slug', it will be used instead
|
37
|
-
pkey = fields.keys.first
|
38
|
-
slug = fields['slug'].nil? ? fields[pkey] : fields['slug']
|
39
|
-
filename = to_snake(slug) + '.md'
|
40
38
|
uid = record['id']
|
41
|
-
|
42
|
-
out_file = File.new("#{directory_name}/#{filename}", "w")
|
43
|
-
out_file.puts(front_matter_mark)
|
44
|
-
out_file.puts("uid: #{uid}")
|
39
|
+
out_file = create_page_for_the_record(directory_name, uid, fields)
|
45
40
|
|
46
41
|
fields.each do |key, value|
|
47
42
|
snake_key = to_snake(key)
|
48
43
|
|
44
|
+
if is_a_long_text?(jekyll_config, table_name, key)
|
45
|
+
write_long_text_to_file(snake_key, value, out_file)
|
46
|
+
next
|
47
|
+
end
|
48
|
+
|
49
49
|
if value.class.name == 'Array'
|
50
50
|
out_file.puts("#{snake_key}:")
|
51
51
|
write_array_values(out_file, value)
|
@@ -62,11 +62,29 @@ module Jekyll
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
write_attachments_data_file
|
65
|
+
write_attachments_data_file if @attachments_hash.keys.size > 0
|
66
66
|
end
|
67
67
|
|
68
68
|
private
|
69
69
|
|
70
|
+
def should_generate_be_prevented?(config)
|
71
|
+
is_enabled = config.airtable.enable_sync
|
72
|
+
return true if !is_enabled
|
73
|
+
|
74
|
+
@api_key = config.to_hash['AIRTABLE_API_KEY']
|
75
|
+
@base_uid = config.airtable.base_uid
|
76
|
+
@table_names = config.airtable.tables.map{ |t| t.name }
|
77
|
+
|
78
|
+
return true if @api_key.nil? || @api_key == '' || @base_uid.nil? || @base_uid == ''
|
79
|
+
false
|
80
|
+
end
|
81
|
+
|
82
|
+
def setting_up_airtable_client
|
83
|
+
Airtable.configure { |config| config.api_key = @api_key }
|
84
|
+
|
85
|
+
Airtable.client(base_uid: @base_uid)
|
86
|
+
end
|
87
|
+
|
70
88
|
def front_matter_mark
|
71
89
|
'---'
|
72
90
|
end
|
@@ -75,6 +93,10 @@ module Jekyll
|
|
75
93
|
string.split(' ').map(&:downcase).join('_')
|
76
94
|
end
|
77
95
|
|
96
|
+
def to_dash(string)
|
97
|
+
string.split(' ').map(&:downcase).join('-')
|
98
|
+
end
|
99
|
+
|
78
100
|
def write_array_values(file, array)
|
79
101
|
array.each do |element|
|
80
102
|
if is_this_is_an_attachment?(element)
|
@@ -113,7 +135,7 @@ module Jekyll
|
|
113
135
|
Dir.mkdir('_data') unless File.exists?('_data')
|
114
136
|
Dir.mkdir('_data/airtable') unless File.exists?('_data/airtable')
|
115
137
|
|
116
|
-
Dir.mkdir('collections') unless File.exists?('collections')
|
138
|
+
Dir.mkdir('collections') unless File.exists?('collections')
|
117
139
|
end
|
118
140
|
|
119
141
|
def write_attachments_data_file
|
@@ -121,5 +143,58 @@ module Jekyll
|
|
121
143
|
f.write(@attachments_hash.to_yaml)
|
122
144
|
end
|
123
145
|
end
|
146
|
+
|
147
|
+
def create_page_for_the_record(directory_name, uid, fields)
|
148
|
+
# We use the first field as the primary key
|
149
|
+
# Then find the value of the primary key to be stored as the slug, which
|
150
|
+
# will be used as file name and the path to the record in the url.
|
151
|
+
# However, if the record has field called 'slug', it will be used instead
|
152
|
+
pkey = fields.keys.first
|
153
|
+
slug = fields['slug'].nil? ? fields[pkey] : fields['slug']
|
154
|
+
slug = slug.length > 100 ? uid : slug
|
155
|
+
|
156
|
+
if is_an_uri?(slug)
|
157
|
+
filename = to_dash(slug) + '.md'
|
158
|
+
else
|
159
|
+
filename = to_dash(uid) + '.md'
|
160
|
+
end
|
161
|
+
|
162
|
+
out_file = File.new("#{directory_name}/#{filename}", "w")
|
163
|
+
out_file.puts(front_matter_mark)
|
164
|
+
out_file.puts("uid: #{uid}")
|
165
|
+
|
166
|
+
out_file
|
167
|
+
end
|
168
|
+
|
169
|
+
def is_a_long_text?(config, table_name, key)
|
170
|
+
table = config.airtable.tables.select{ |a| a.name == table_name }.first
|
171
|
+
return false if table.nil?
|
172
|
+
|
173
|
+
list = table.long_text_columns || []
|
174
|
+
list.include?(key)
|
175
|
+
end
|
176
|
+
|
177
|
+
def write_long_text_to_file(snake_key, text, out_file)
|
178
|
+
out_file.puts("#{snake_key}: |")
|
179
|
+
|
180
|
+
lines = text.split("\n")
|
181
|
+
|
182
|
+
lines.each do |line|
|
183
|
+
out_file.puts(" " + line)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def is_an_uri?(string)
|
188
|
+
return true if string.include?('http') ||
|
189
|
+
string.include?('://') ||
|
190
|
+
string.include?('www.')
|
191
|
+
|
192
|
+
uri = URI.parse(string)
|
193
|
+
%w( http https ).include?(uri.scheme)
|
194
|
+
rescue URI::BadURIError
|
195
|
+
false
|
196
|
+
rescue URI::InvalidURIError
|
197
|
+
false
|
198
|
+
end
|
124
199
|
end
|
125
200
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-airtable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Galih Muhammad
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '3.3'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: hashie
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
description: Airtable support in Jekyll site to easily fetch and store data
|
126
140
|
email:
|
127
141
|
- galih0muhammad@gmail.com
|