jekyll-contentful-data-import 0.1.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 +7 -0
- data/.gitignore +14 -0
- data/.travis.yml +18 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +11 -0
- data/CONTRIBUTING.md +43 -0
- data/Gemfile +6 -0
- data/Guardfile +5 -0
- data/LICENSE.md +20 -0
- data/README.md +94 -0
- data/Rakefile +16 -0
- data/jekyll-contentful.gemspec +36 -0
- data/lib/jekyll-contentful-data-import.rb +5 -0
- data/lib/jekyll-contentful-data-import/data_exporter.rb +47 -0
- data/lib/jekyll-contentful-data-import/importer.rb +45 -0
- data/lib/jekyll-contentful-data-import/mappers.rb +1 -0
- data/lib/jekyll-contentful-data-import/mappers/base.rb +87 -0
- data/lib/jekyll-contentful-data-import/serializer.rb +25 -0
- data/lib/jekyll-contentful-data-import/version.rb +5 -0
- data/lib/jekyll/commands/contentful.rb +42 -0
- data/spec/fixtures/vcr_fixtures/entries.yml +914 -0
- data/spec/jekyll-contentful/data_exporter_spec.rb +44 -0
- data/spec/jekyll-contentful/importer_spec.rb +66 -0
- data/spec/jekyll-contentful/mappers/base_spec.rb +109 -0
- data/spec/jekyll-contentful/serializer_spec.rb +58 -0
- data/spec/jekyll/commands/contentful_spec.rb +26 -0
- data/spec/spec_helper.rb +48 -0
- metadata +238 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c3583ff47a05314cd2914810223cad4e0ab01894
|
4
|
+
data.tar.gz: 21cfbb2ed72ad174e5d4613ea1aa3b101ba8ed5b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5ce05d4e5b0a10b60b4dd35ee9ecbc6d35f9fd9546cb1eaf0800659c6ae7dba3db265433ac74d3823b8107b12d4d4a8839664bbe43565b86e0f2d6a0570b491e
|
7
|
+
data.tar.gz: 37c934537a139a0ffa9d19a6011044aa6af48cb66c7f474647fba0bbc632a477b40045a2c6386880cc2ed4eb02509f1c9dc91c4275b609ad15658dc9ffce65e5
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
rvm:
|
2
|
+
- 2.0.0
|
3
|
+
- 2.1.2
|
4
|
+
- 2.2.3
|
5
|
+
- jruby
|
6
|
+
|
7
|
+
script: "bundle exec rake test"
|
8
|
+
|
9
|
+
before_install: gem install bundler -v 1.10.6
|
10
|
+
|
11
|
+
env: TEST=true JRUBY_OPTS='--2.0'
|
12
|
+
notifications:
|
13
|
+
slack:
|
14
|
+
secure: MMWxqKMT4m2UhZ+Ix4wgCs1nLvu9hUFCbyV/qJWmIFif7V4GUKXi6h9krMqGqBAd3YV3pP/InPlw3QoKBUGIAIr5GzDpSnU5ACv7E61v548qViEvPBqsfhRHha2M164rUHn32tpejJnIizVUyND/hIzNviIrab+G8uOaZXUtB5I=
|
15
|
+
|
16
|
+
matrix:
|
17
|
+
allow_failures:
|
18
|
+
- rvm: jruby
|
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# Contributing
|
2
|
+
In the spirit of [free software][free-sw], **everyone** is encouraged to help
|
3
|
+
improve this project.
|
4
|
+
|
5
|
+
[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html
|
6
|
+
|
7
|
+
Here are some ways *you* can contribute:
|
8
|
+
|
9
|
+
* by using alpha, beta, and prerelease versions
|
10
|
+
* by reporting bugs
|
11
|
+
* by suggesting new features
|
12
|
+
* by writing or editing documentation
|
13
|
+
* by writing specifications
|
14
|
+
* by writing code ( **no patch is too small** : fix typos, add comments, clean up inconsistent whitespace )
|
15
|
+
* by refactoring code
|
16
|
+
* by closing [issues][]
|
17
|
+
* by reviewing patches
|
18
|
+
|
19
|
+
[issues]: https://github.com/contentful/jekyll-contentful-data-import/issues
|
20
|
+
|
21
|
+
## Submitting an Issue
|
22
|
+
We use the [GitHub issue tracker][issues] to track bugs and features. Before
|
23
|
+
submitting a bug report or feature request, check to make sure it hasn't
|
24
|
+
already been submitted. When submitting a bug report, please include a [Gist][]
|
25
|
+
that includes a stack trace and any details that may be necessary to reproduce
|
26
|
+
the bug, including your gem version, Ruby version, and operating system.
|
27
|
+
Ideally, a bug report should include a pull request with failing specs.
|
28
|
+
|
29
|
+
[gist]: https://gist.github.com/
|
30
|
+
|
31
|
+
## Submitting a Pull Request
|
32
|
+
1. [Fork the repository.][fork]
|
33
|
+
2. [Create a topic branch.][branch]
|
34
|
+
3. Add specs for your unimplemented feature or bug fix.
|
35
|
+
4. Run `bundle exec rake test`. If your specs pass, return to step 3.
|
36
|
+
5. Implement your feature or bug fix.
|
37
|
+
6. Run `bundle exec rake test`. If your specs fail, return to step 5.
|
38
|
+
7. Add, commit, and push your changes.
|
39
|
+
8. [Submit a pull request.][pr]
|
40
|
+
|
41
|
+
[fork]: http://help.github.com/fork-a-repo/
|
42
|
+
[branch]: http://learn.github.com/p/branching.html
|
43
|
+
[pr]: http://help.github.com/send-pull-requests/
|
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2015 Contentful GmbH
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# Jekyll-Contentful-Data-Import
|
2
|
+
|
3
|
+
[](https://travis-ci.org/contentful/jekyll-contentful)
|
4
|
+
|
5
|
+
Jekyll-Contentful-Data-Import is a [Jekyll](http://jekyllrb.com/) extension to use the Jekyll static site generator together with the API-driven [Contentful CMS](https://www.contentful.com). It is powered by the [Contentful Ruby Gem](https://github.com/contentful/contentful.rb).
|
6
|
+
|
7
|
+
Experience the power of Jekyll while staying sane as a developer by letting end-users edit content in a web-based interface.
|
8
|
+
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
Add the following line to the Gemfile of your Jekyll project:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
group :jekyll_plugins do
|
15
|
+
gem "jekyll-contentful-data-import"
|
16
|
+
end
|
17
|
+
```
|
18
|
+
|
19
|
+
Then as usual, run:
|
20
|
+
|
21
|
+
```bash
|
22
|
+
bundle install
|
23
|
+
```
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
Run `jekyll contentful` in your terminal. This will fetch entries for the configured
|
28
|
+
spaces and content types and put the resulting data in the
|
29
|
+
[local data folder](http://jekyllrb.com/docs/datafiles/) as yaml files.
|
30
|
+
|
31
|
+
### --rebuild option
|
32
|
+
|
33
|
+
The `contentful` command has a `--rebuild` option which will trigger a rebuild of your site
|
34
|
+
|
35
|
+
## Configuration
|
36
|
+
|
37
|
+
To configure the extension, add the following configuration block to Jekyll's `_config.yml`:
|
38
|
+
|
39
|
+
```yaml
|
40
|
+
contentful:
|
41
|
+
spaces:
|
42
|
+
- example: # Jekyll _data folder identifier - Required
|
43
|
+
space: cfexampleapi # Required
|
44
|
+
access_token: b4c0n73n7fu1 # Required
|
45
|
+
cda_query: # Optional
|
46
|
+
include: 2
|
47
|
+
limit: 100
|
48
|
+
content_types: # Optional
|
49
|
+
cat: MyCoolMapper
|
50
|
+
client_options: # Optional
|
51
|
+
:preview: false
|
52
|
+
:raise_errors: true
|
53
|
+
:dynamic_entries: :auto
|
54
|
+
```
|
55
|
+
|
56
|
+
Parameter | Description
|
57
|
+
---------- | ------------
|
58
|
+
space | Contentful Space ID
|
59
|
+
access_token | Contentful Delivery API access token
|
60
|
+
cda_query | Hash describing query configuration. See [contentful.rb](https://github.com/contentful/contentful.rb) for more info (look for filter options there). Note that by default only 100 entries will be fetched, this can be configured to up to 1000 entries using the `limit` option.
|
61
|
+
content_types | Hash describing the mapping applied to entries of the imported content types
|
62
|
+
client_options | Hash describing Contentful::Client configuration. See [contentful.rb](https://github.com/contentful/contentful.rb) for more info.
|
63
|
+
|
64
|
+
You can add multiple spaces to your configuration
|
65
|
+
|
66
|
+
## Entry mapping
|
67
|
+
|
68
|
+
The extension will transform every fetched entry before storing it as a yaml file in the local
|
69
|
+
data folder. If a custom mapper is not specified a default one will be used.
|
70
|
+
|
71
|
+
The default mapper will map fields, assets and linked entries.
|
72
|
+
|
73
|
+
### Custom mappers
|
74
|
+
|
75
|
+
You can create your own mappers if you need so. The only requirement for a class to behave as a
|
76
|
+
mapper is to have a `map` instance method.
|
77
|
+
|
78
|
+
Following is an example of such custom mapper that adds all `sys` properties to the entry:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
class MySysMapper < ::Jekyll::Contentful::Mappers::Base
|
82
|
+
def map
|
83
|
+
result = super
|
84
|
+
|
85
|
+
entry.sys.each do |k, v|
|
86
|
+
name, value = map_field k, v
|
87
|
+
result['sys'][name] = value
|
88
|
+
end
|
89
|
+
|
90
|
+
result
|
91
|
+
end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
|
3
|
+
desc "Run tests, both RSpec and Cucumber"
|
4
|
+
task :test => [:spec]
|
5
|
+
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
desc "Run RSpec"
|
8
|
+
RSpec::Core::RakeTask.new do |spec|
|
9
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
10
|
+
spec.rspec_opts = ['--color']
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'rake'
|
14
|
+
|
15
|
+
require 'rubygems/tasks'
|
16
|
+
Gem::Tasks.new
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require File.expand_path('../lib/jekyll-contentful-data-import/version.rb', __FILE__)
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "jekyll-contentful-data-import"
|
7
|
+
s.version = Jekyll::Contentful::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ['Contentful GmbH']
|
10
|
+
s.email = ["david.litvak@contentful.com"]
|
11
|
+
s.homepage = "https://www.contentful.com"
|
12
|
+
s.summary = %q{Include mangablable content from the Contentful CMS and API into your Jekyll projects}
|
13
|
+
s.description = %q{Load blog posts and other managed content into Jekyll}
|
14
|
+
s.license = "MIT"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# The version of middleman-core your extension depends on
|
22
|
+
s.add_dependency("jekyll", ">= 2.5.0", "< 4")
|
23
|
+
|
24
|
+
# Additional dependencies
|
25
|
+
s.add_dependency("contentful", '~> 0.8')
|
26
|
+
|
27
|
+
s.add_development_dependency 'rubygems-tasks', '~> 0.2'
|
28
|
+
s.add_development_dependency "guard"
|
29
|
+
s.add_development_dependency "guard-rspec"
|
30
|
+
s.add_development_dependency "bundler", "~> 1.6"
|
31
|
+
s.add_development_dependency "rake"
|
32
|
+
s.add_development_dependency "rspec", "~> 3.0"
|
33
|
+
s.add_development_dependency "vcr"
|
34
|
+
s.add_development_dependency "webmock"
|
35
|
+
s.add_development_dependency "pry"
|
36
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'jekyll-contentful-data-import/serializer'
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module Contentful
|
5
|
+
class DataExporter
|
6
|
+
DATA_FOLDER = '_data'
|
7
|
+
CONTENTFUL_FOLDER = 'contentful'
|
8
|
+
SPACES_FOLDER = 'spaces'
|
9
|
+
|
10
|
+
attr_reader :name, :entries, :config
|
11
|
+
|
12
|
+
def initialize(name, entries, config = {})
|
13
|
+
@name = name
|
14
|
+
@entries = entries
|
15
|
+
@config = config
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
setup_directory
|
20
|
+
|
21
|
+
File.open(destination_file, 'w') do |file|
|
22
|
+
file.write(::Jekyll::Contentful::Serializer.new(entries, config).to_yaml)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def destination_directory
|
27
|
+
base_directory = File.expand_path(Dir.pwd)
|
28
|
+
File.join(base_directory, DATA_FOLDER, CONTENTFUL_FOLDER, SPACES_FOLDER)
|
29
|
+
end
|
30
|
+
|
31
|
+
def destination_file
|
32
|
+
File.join(destination_directory, "#{name}.yaml")
|
33
|
+
end
|
34
|
+
|
35
|
+
def setup_directory
|
36
|
+
data_folder = File.join(Dir.pwd, DATA_FOLDER)
|
37
|
+
Dir.mkdir(data_folder) unless Dir.exist?(data_folder)
|
38
|
+
|
39
|
+
contentful_folder = File.join(data_folder, CONTENTFUL_FOLDER)
|
40
|
+
Dir.mkdir(contentful_folder) unless Dir.exist?(contentful_folder)
|
41
|
+
|
42
|
+
spaces_folder = File.join(contentful_folder, SPACES_FOLDER)
|
43
|
+
Dir.mkdir(spaces_folder) unless Dir.exist?(spaces_folder)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'contentful'
|
2
|
+
require 'jekyll-contentful-data-import/data_exporter'
|
3
|
+
|
4
|
+
module Jekyll
|
5
|
+
module Contentful
|
6
|
+
class Importer
|
7
|
+
attr_reader :config
|
8
|
+
|
9
|
+
def initialize(config)
|
10
|
+
@config = config
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
spaces.each do |name, options|
|
15
|
+
space_client = client(
|
16
|
+
options['space'],
|
17
|
+
options['access_token'],
|
18
|
+
options.fetch('client_options', {})
|
19
|
+
)
|
20
|
+
|
21
|
+
Jekyll::Contentful::DataExporter.new(
|
22
|
+
name,
|
23
|
+
space_client.entries(options.fetch('cda_query', {})),
|
24
|
+
options
|
25
|
+
).run
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def spaces
|
30
|
+
config['spaces'].map { |space_data| space_data.first }
|
31
|
+
end
|
32
|
+
|
33
|
+
def client(space, access_token, options = {})
|
34
|
+
options = {
|
35
|
+
space: space,
|
36
|
+
access_token: access_token,
|
37
|
+
dynamic_entries: :auto,
|
38
|
+
raise_errors: true
|
39
|
+
}.merge(options)
|
40
|
+
|
41
|
+
::Contentful::Client.new(options)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'jekyll-contentful-data-import/mappers/base'
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'contentful'
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module Contentful
|
5
|
+
module Mappers
|
6
|
+
class Base
|
7
|
+
def self.mapper_for(entry, config)
|
8
|
+
ct = entry.content_type
|
9
|
+
|
10
|
+
mapper_name = config.fetch(
|
11
|
+
'content_types', {}
|
12
|
+
).fetch(
|
13
|
+
ct.id, ::Jekyll::Contentful::Mappers::Base.to_s
|
14
|
+
)
|
15
|
+
|
16
|
+
Module.const_get(mapper_name).new(entry, config)
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :entry, :config
|
20
|
+
|
21
|
+
def initialize(entry, config)
|
22
|
+
@entry = entry
|
23
|
+
@config = config
|
24
|
+
end
|
25
|
+
|
26
|
+
def map
|
27
|
+
result = {'sys' => {'id' => entry.id}}
|
28
|
+
|
29
|
+
fields = has_multiple_locales? ? entry.fields_with_locales : entry.fields
|
30
|
+
|
31
|
+
fields.each do |k, v|
|
32
|
+
name, value = map_field k, v
|
33
|
+
result[name] = value
|
34
|
+
end
|
35
|
+
|
36
|
+
result
|
37
|
+
end
|
38
|
+
|
39
|
+
def has_multiple_locales?
|
40
|
+
config.fetch('cda_query', {}).fetch(:locale, nil) == '*'
|
41
|
+
end
|
42
|
+
|
43
|
+
def map_field(field_name, field_value)
|
44
|
+
value_mapping = map_value(field_value)
|
45
|
+
return field_name.to_s, value_mapping
|
46
|
+
end
|
47
|
+
|
48
|
+
def map_value(value)
|
49
|
+
case value
|
50
|
+
when ::Contentful::Asset
|
51
|
+
map_asset(value)
|
52
|
+
when ::Contentful::Location
|
53
|
+
map_location(value)
|
54
|
+
when ::Contentful::Link
|
55
|
+
map_link(value)
|
56
|
+
when ::Contentful::DynamicEntry
|
57
|
+
map_entry(value)
|
58
|
+
when ::Array
|
59
|
+
map_array(value)
|
60
|
+
else
|
61
|
+
value
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def map_asset(asset)
|
66
|
+
{'title' => asset.title, 'url' => asset.file.url}
|
67
|
+
end
|
68
|
+
|
69
|
+
def map_entry(child)
|
70
|
+
{'sys' => {'id' => child.id}}
|
71
|
+
end
|
72
|
+
|
73
|
+
def map_location(location)
|
74
|
+
location.properties
|
75
|
+
end
|
76
|
+
|
77
|
+
def map_link(link)
|
78
|
+
{'sys' => {'id' => link.id}}
|
79
|
+
end
|
80
|
+
|
81
|
+
def map_array(array)
|
82
|
+
array.map {|element| map_value(element)}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|