diff --git a/README.md b/README.md
index ce0afa3..43db641 100644
--- a/README.md
+++ b/README.md
@@ -55,19 +55,21 @@ contentful:
api_url: 'preview.contentful.com' # Defaults to 'api.contentful.com' which is Production
base_path: app_path # Optional - Defaults to Current directory
destination: destination_in_data # Optional - Defaults to _data/contentful/spaces
+ individual_entry_files: true # Optional - Defaults to false
```
-Parameter | Description
----------- | ------------
-space | Contentful Space ID
-access_token | Contentful Delivery API access token
-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.
-all_entries | Boolean, if true will run multiple queries to the API until it fetches all entries for the space
-all_entries_page_size | Integer, the amount of maximum entries per CDA Request when fetching :all_entries
-content_types | Hash describing the mapping applied to entries of the imported content types
-client_options | Hash describing Contentful::Client configuration. See [contentful.rb](https://github.com/contentful/contentful.rb) for more info.
-base_path | String with path to your Jekyll Application, defaults to current directory. Path is relative to your current location.
-destination | String with path within `_data` under which to store the output yaml file. Defaults to contentful/spaces
+Parameter | Description
+---------- | ------------
+space | Contentful Space ID
+access_token | Contentful Delivery API access token
+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.
+all_entries | Boolean, if true will run multiple queries to the API until it fetches all entries for the space
+all_entries_page_size | Integer, the amount of maximum entries per CDA Request when fetching :all_entries
+content_types | Hash describing the mapping applied to entries of the imported content types
+client_options | Hash describing Contentful::Client configuration. See [contentful.rb](https://github.com/contentful/contentful.rb) for more info.
+base_path | String with path to your Jekyll Application, defaults to current directory. Path is relative to your current location.
+destination | String with path within `_data` under which to store the output yaml file. Defaults to contentful/spaces
+individual_entry_files | Boolean, if true will create an individual file per entry separated in folders by content type, file path will be `{space_alias}/{content_type_id}/{entry_id}.yaml`. Default behavior is to create a file per space. Usage is affected when this is set to true, please look in the section below.
You can add multiple spaces to your configuration
@@ -157,6 +159,26 @@ therefore you can do the following:
This way, it is safe to share your code without having to worry
about your credentials.
+### Using Multiple Entry Files
+
+When setting the `individual_entry_files` flag to true, the usage pattern changes a little,
+as Jekyll does not allow for variable unpacking when iterating.
+
+A usage example is as follows:
+
+```html
+
+```
+
## Examples
You can find working examples of multiple uses [here](https://github.com/contentful/contentful_jekyll_examples).
diff --git a/lib/jekyll-contentful-data-import/data_exporter.rb b/lib/jekyll-contentful-data-import/base_data_exporter.rb
similarity index 51%
rename from lib/jekyll-contentful-data-import/data_exporter.rb
rename to lib/jekyll-contentful-data-import/base_data_exporter.rb
index a48d239..080f99c 100644
--- a/lib/jekyll-contentful-data-import/data_exporter.rb
+++ b/lib/jekyll-contentful-data-import/base_data_exporter.rb
@@ -2,14 +2,10 @@
module Jekyll
module Contentful
- # Data Exporter Class
+ # Base Data Exporter Class
#
- # Serializes Contentful data into YAML files
- class DataExporter
- DATA_FOLDER = '_data'.freeze
- CONTENTFUL_FOLDER = 'contentful'.freeze
- SPACES_FOLDER = 'spaces'.freeze
-
+ # Generic Data Exporter Implementation
+ class BaseDataExporter
attr_reader :name, :entries, :config
def initialize(name, entries, config = {})
@@ -19,16 +15,7 @@ def initialize(name, entries, config = {})
end
def run
- setup_directory
-
- File.open(destination_file, 'w') do |file|
- file.write(
- ::Jekyll::Contentful::Serializer.new(
- entries,
- config
- ).to_yaml
- )
- end
+ raise 'must implement'
end
def base_directory
@@ -45,24 +32,34 @@ def base_directory
def destination_directory
destination_dir = File.join(
- base_directory, DATA_FOLDER,
- CONTENTFUL_FOLDER, SPACES_FOLDER
+ base_directory, data_folder,
+ contentful_folder, spaces_folder
)
if config.key?('destination')
destination_dir = File.join(
- base_directory, DATA_FOLDER, config['destination']
+ base_directory, data_folder, config['destination']
)
end
destination_dir
end
- def destination_file
- File.join(destination_directory, "#{name}.yaml")
+ def setup_directory(directory)
+ FileUtils.mkdir_p(directory)
+ end
+
+ protected
+
+ def data_folder
+ '_data'
+ end
+
+ def contentful_folder
+ 'contentful'
end
- def setup_directory
- FileUtils.mkdir_p destination_directory
+ def spaces_folder
+ 'spaces'
end
end
end
diff --git a/lib/jekyll-contentful-data-import/importer.rb b/lib/jekyll-contentful-data-import/importer.rb
index df24920..3f66388 100644
--- a/lib/jekyll-contentful-data-import/importer.rb
+++ b/lib/jekyll-contentful-data-import/importer.rb
@@ -1,5 +1,6 @@
require 'contentful'
-require 'jekyll-contentful-data-import/data_exporter'
+require 'jekyll-contentful-data-import/single_file_data_exporter'
+require 'jekyll-contentful-data-import/multi_file_data_exporter'
module Jekyll
module Contentful
@@ -26,9 +27,35 @@ def run
end
def export_data(name, space_client, options)
- Jekyll::Contentful::DataExporter.new(
+ entries = get_entries(space_client, options)
+
+ if options.fetch('individual_entry_files', false)
+ export_data_multiple_files(
+ name,
+ entries,
+ options
+ )
+ else
+ export_data_single_file(
+ name,
+ entries,
+ options
+ )
+ end
+ end
+
+ def export_data_single_file(name, entries, options)
+ Jekyll::Contentful::SingleFileDataExporter.new(
+ name,
+ entries,
+ options
+ ).run
+ end
+
+ def export_data_multiple_files(name, entries, options)
+ Jekyll::Contentful::MultiFileDataExporter.new(
name,
- get_entries(space_client, options),
+ entries,
options
).run
end
diff --git a/lib/jekyll-contentful-data-import/multi_file_data_exporter.rb b/lib/jekyll-contentful-data-import/multi_file_data_exporter.rb
new file mode 100644
index 0000000..1734706
--- /dev/null
+++ b/lib/jekyll-contentful-data-import/multi_file_data_exporter.rb
@@ -0,0 +1,35 @@
+require 'jekyll-contentful-data-import/base_data_exporter'
+require 'yaml'
+
+module Jekyll
+ module Contentful
+ # Single File Data Exporter Class
+ #
+ # Serializes Contentful data into a multiple YAML files
+ class MultiFileDataExporter < BaseDataExporter
+ def run
+ data = ::Jekyll::Contentful::Serializer.new(
+ entries,
+ config
+ ).serialize
+
+ data.each do |content_type, entries|
+ content_type_directory = File.join(destination_directory, name, content_type.to_s)
+ setup_directory(content_type_directory)
+
+ entries.each do |entry|
+ yaml_entry = YAML.dump(entry)
+
+ File.open(destination_file(content_type_directory, entry), 'w') do |file|
+ file.write(yaml_entry)
+ end
+ end
+ end
+ end
+
+ def destination_file(content_type_directory, entry)
+ File.join(content_type_directory, "#{entry['sys']['id']}.yaml")
+ end
+ end
+ end
+end
diff --git a/lib/jekyll-contentful-data-import/single_file_data_exporter.rb b/lib/jekyll-contentful-data-import/single_file_data_exporter.rb
new file mode 100644
index 0000000..78a28b3
--- /dev/null
+++ b/lib/jekyll-contentful-data-import/single_file_data_exporter.rb
@@ -0,0 +1,27 @@
+require 'jekyll-contentful-data-import/base_data_exporter'
+
+module Jekyll
+ module Contentful
+ # Single File Data Exporter Class
+ #
+ # Serializes Contentful data into a single YAML file
+ class SingleFileDataExporter < BaseDataExporter
+ def run
+ setup_directory(destination_directory)
+
+ File.open(destination_file, 'w') do |file|
+ file.write(
+ ::Jekyll::Contentful::Serializer.new(
+ entries,
+ config
+ ).to_yaml
+ )
+ end
+ end
+
+ def destination_file
+ File.join(destination_directory, "#{name}.yaml")
+ end
+ end
+ end
+end
diff --git a/spec/jekyll-contentful/importer_spec.rb b/spec/jekyll-contentful/importer_spec.rb
index 7842041..b0dd61c 100644
--- a/spec/jekyll-contentful/importer_spec.rb
+++ b/spec/jekyll-contentful/importer_spec.rb
@@ -70,7 +70,7 @@ def run; end
allow(subject).to receive(:spaces).and_return([['foo', {'space' => 'foo', 'access_token' => 'bar'}], ['bar', {'space' => 'bar', 'access_token' => 'foo'}]])
allow(subject).to receive(:client).and_return(ClientDouble.new)
- expect(Jekyll::Contentful::DataExporter).to receive(:new).and_return(ExporterDouble.new).twice
+ expect(Jekyll::Contentful::SingleFileDataExporter).to receive(:new).and_return(ExporterDouble.new).twice
subject.run
end
@@ -78,7 +78,27 @@ def run; end
it 'runs exporter with correct arguments' do
allow(subject).to receive(:client).and_return(ClientDouble.new)
- expect(Jekyll::Contentful::DataExporter).to receive(:new).with('example', [], config['spaces'].first['example']).and_return(ExporterDouble.new)
+ expect(Jekyll::Contentful::SingleFileDataExporter).to receive(:new).with('example', [], config['spaces'].first['example']).and_return(ExporterDouble.new)
+
+ subject.run
+ end
+
+ it 'runs multifile exporter when passed :individual_entry_files flag' do
+ config = {
+ 'spaces' => [
+ {
+ 'example' => {
+ 'space' => 'cfexampleapi',
+ 'access_token' => 'b4c0n73n7fu1',
+ 'individual_entry_files' => true
+ }
+ }
+ ]
+ }
+ subject = described_class.new(config)
+ allow(subject).to receive(:client).and_return(ClientDouble.new)
+
+ expect(Jekyll::Contentful::MultiFileDataExporter).to receive(:new).with('example', [], config['spaces'].first['example']).and_return(ExporterDouble.new)
subject.run
end
diff --git a/spec/jekyll-contentful/multi_file_data_exporter_spec.rb b/spec/jekyll-contentful/multi_file_data_exporter_spec.rb
new file mode 100644
index 0000000..e299854
--- /dev/null
+++ b/spec/jekyll-contentful/multi_file_data_exporter_spec.rb
@@ -0,0 +1,85 @@
+require 'spec_helper'
+require 'stringio'
+
+describe Jekyll::Contentful::MultiFileDataExporter do
+ subject { described_class.new('foo', []) }
+
+ describe 'instance methods' do
+ describe '#base_directory' do
+ it 'default directory' do
+ expect(subject.base_directory).to eq(Dir.pwd)
+ end
+
+ it 'overriden directory' do
+ subject = described_class.new('foo', [], {'base_path' => 'foo_dir'})
+
+ expect(subject.base_directory).to eq(File.join(Dir.pwd, 'foo_dir'))
+ end
+ end
+
+ describe '#destination_directory' do
+ it 'default directory' do
+ expected = File.join(Dir.pwd, '_data', 'contentful', 'spaces')
+ expect(subject.destination_directory).to eq(expected)
+ end
+
+ it 'overridden directory' do
+ subject = described_class.new('foo', [], {'base_path' => 'foo_dir'})
+
+ expected = File.join(Dir.pwd, 'foo_dir', '_data', 'contentful', 'spaces')
+ expect(subject.destination_directory).to eq(expected)
+ end
+ end
+
+ it '#destination_file' do
+ entry_double = { 'sys' => { 'id' => 'bar' } }
+ expected = File.join('foo', 'bar.yaml')
+ expect(subject.destination_file('foo', entry_double)).to eq(expected)
+ end
+
+ describe '#setup_directory' do
+ it 'default directory' do
+ expected = File.join(Dir.pwd, '_data', 'contentful', 'spaces')
+ expect(FileUtils).to receive(:mkdir_p).with(expected)
+
+ subject.setup_directory(expected)
+ end
+
+ it 'overridden directory' do
+ subject = described_class.new('foo', [], {'base_path' => 'foo_dir'})
+
+ expected = File.join(Dir.pwd, 'foo_dir', '_data', 'contentful', 'spaces')
+ expect(FileUtils).to receive(:mkdir_p).with(expected)
+
+ subject.setup_directory(expected)
+ end
+ end
+
+ describe '#run' do
+ before do
+ allow(subject).to receive(:setup_directory)
+ end
+
+ it 'does nothing with no entries' do
+ subject.run
+ end
+
+ it 'serializes entries' do
+ expect_any_instance_of(::Jekyll::Contentful::Serializer).to receive(:serialize) { {} }
+
+ subject.run
+ end
+
+ it 'creates a file per entry' do
+ subject = described_class.new('foo', [EntryDouble.new('bar', ContentTypeDouble.new('bar_ct'))])
+
+ expected_directory_path = File.join(Dir.pwd, '_data', 'contentful', 'spaces', 'foo', 'bar_ct')
+ expect(FileUtils).to receive(:mkdir_p).with(expected_directory_path)
+ expect(File).to receive(:open).with(File.join(expected_directory_path, 'bar.yaml'), 'w')
+
+ subject.run
+ end
+ end
+ end
+end
+
diff --git a/spec/jekyll-contentful/data_exporter_spec.rb b/spec/jekyll-contentful/single_file_data_exporter_spec.rb
similarity index 95%
rename from spec/jekyll-contentful/data_exporter_spec.rb
rename to spec/jekyll-contentful/single_file_data_exporter_spec.rb
index 0d57261..2c2c9d2 100644
--- a/spec/jekyll-contentful/data_exporter_spec.rb
+++ b/spec/jekyll-contentful/single_file_data_exporter_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
require 'stringio'
-describe Jekyll::Contentful::DataExporter do
+describe Jekyll::Contentful::SingleFileDataExporter do
subject { described_class.new('foo', []) }
describe 'instance methods' do
@@ -57,7 +57,7 @@
expected = File.join(Dir.pwd, '_data', 'contentful', 'spaces')
expect(FileUtils).to receive(:mkdir_p).with(expected)
- subject.setup_directory
+ subject.setup_directory(expected)
end
it 'overridden directory' do
@@ -66,7 +66,7 @@
expected = File.join(Dir.pwd, 'foo_dir', '_data', 'contentful', 'spaces')
expect(FileUtils).to receive(:mkdir_p).with(expected)
- subject.setup_directory
+ subject.setup_directory(expected)
end
end