jekyll-contentful-data-import 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.com/contentful/jekyll-contentful.svg?token=Nx7fXKYs7PbM7CcY2dS1)](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
|