wax_tasks 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dcf7d468f41464dd970e43b0f4a22b857b1e412872d9fb1a3467ab63d8482b80
4
- data.tar.gz: 3d8b8640ec00cbf86ed1c06b39935745abf24001ee858d9e9a7dec2ee6d075f9
3
+ metadata.gz: a05cb7d5dd4a2218f7c20546a7bb40762ff50c1382457ab5dc8573f5a8131eb9
4
+ data.tar.gz: d80600e1d481d7aa91c78fc38fb214aa234f86859ff1ae8660310f17586b5ed0
5
5
  SHA512:
6
- metadata.gz: f2315b406a0d970572b617571e140a29e82a09125dfbc5a700059f21da63b4b9f5e5e9bb4195dcdcdcb9d904d33f7319605c9b8c581a70fc1fb233eb41635e03
7
- data.tar.gz: 1742b039101f3f9b7962dbe1685d0900f1da91a5bc50b263c4987bffae0ae5c6532e0ba61b473e90b9c72f687c8a529fa1bf0625df980e51bb3ba975e261b054
6
+ metadata.gz: 36879c674be8917117b4219e485c987386370c8d8c89d6d8fdc8bc0149a6d05265ede31b4f4720a1aa48d9cca5db1d2e10a8511663f0aaab9ee34a48bbb96edd
7
+ data.tar.gz: 8b9ba90bd8a415fcacc969bd787862d8d37e1b7f222341bd23a9c9b08c33cd5eb9fd641f31d5a02b0df99707009ffb57969d945d462698df10c45bde58d0e758
data/Gemfile CHANGED
@@ -1,6 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
3
 
4
+ # dev/test utilities
4
5
  gem 'diane', require: false
5
6
  gem 'rubocop', require: false
6
7
  gem 'simplecov', require: false
8
+ gem 'yard', require: false
@@ -1,9 +1,11 @@
1
1
  require 'wax_tasks'
2
2
 
3
3
  namespace :wax do
4
+ desc 'generate iiif derivatives from local image files'
4
5
  task :iiif do
5
6
  ARGS = ARGV.drop(1).each { |a| task a.to_sym }
6
7
  abort "You must specify a collection after 'wax:iiif'" if ARGS.empty?
7
- ARGS.each { |name| IiifCollection.new(name).process }
8
+ task_runner = WaxTasks::TaskRunner.new
9
+ task_runner.iiif(ARGS)
8
10
  end
9
11
  end
@@ -0,0 +1,14 @@
1
+ require 'wax_tasks'
2
+
3
+ namespace :wax do
4
+ desc 'write a simple package.json for monitoring js dependencies'
5
+ task :jspackage do
6
+ task_runner = WaxTasks::TaskRunner.new
7
+ package = task_runner.js_package
8
+ unless package.empty?
9
+ path = WaxTasks::Utils.make_path(task_runner.site[:source_dir],
10
+ 'package.json')
11
+ File.open(path, 'w') { |f| f.write(package.to_json) }
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ require 'wax_tasks'
2
+
3
+ namespace :wax do
4
+ desc 'build lunr search index (with default UI if UI=true)'
5
+ task :lunr do
6
+ task_runner = WaxTasks::TaskRunner.new
7
+ task_runner.lunr(generate_ui: !!ENV['UI'])
8
+ end
9
+ end
@@ -4,7 +4,8 @@ namespace :wax do
4
4
  desc 'generate collection md pages from yaml or csv data source'
5
5
  task :pagemaster do
6
6
  ARGS = ARGV.drop(1).each { |a| task a.to_sym }
7
- abort "You must specify a collection after 'wax:pagemaster'" if ARGS.empty?
8
- ARGS.each { |name| PagemasterCollection.new(name).generate_pages }
7
+ raise 'You must specify a collection after wax:pagemaster' if ARGS.empty?
8
+ task_runner = WaxTasks::TaskRunner.new
9
+ task_runner.pagemaster(ARGS)
9
10
  end
10
11
  end
@@ -0,0 +1,13 @@
1
+ require 'wax_tasks'
2
+
3
+ namespace :wax do
4
+ desc 'push compiled Jekyll site to git branch BRANCH'
5
+ task :push do
6
+ ARGS = ARGV.drop(1).each { |a| task a.to_sym }
7
+ raise 'You must specify a branch after \'wax:push:branch\'' if ARGS.empty?
8
+
9
+ target = WaxTasks::Utils.slug(ARGS.first)
10
+ task_runner = WaxTasks::TaskRunner.new
11
+ task_runner.push_branch(target)
12
+ end
13
+ end
@@ -1,7 +1,7 @@
1
1
  require 'html-proofer'
2
2
 
3
3
  namespace :wax do
4
- desc 'run htmlproofer, rspec if exists'
4
+ desc 'run htmlproofer, rspec if .rspec file exists'
5
5
  task :test do
6
6
  opts = {
7
7
  check_external_hash: true,
@@ -0,0 +1,110 @@
1
+ require 'jekyll'
2
+ require 'logger'
3
+ require 'time'
4
+ require 'tmpdir'
5
+
6
+ module WaxTasks
7
+ # Parent class representing a Git Branch
8
+ # that cannot be created directly. Only child classes
9
+ # (LocalBranch, TravisBranch) can be initialized.
10
+ #
11
+ # @attr target [String] the name of the Git branch to deploy to
12
+ # @attr origin [String] the current repository remote
13
+ # @attr commit_msg [String] the commit message to use on push
14
+ # @attr baseurl [String] the site baseurl to build with (if on gh-pages)
15
+ # @attr success_msg [String] informative message to be output to console
16
+ class Branch
17
+ attr_reader :target, :origin, :commit_msg, :baseurl, :success
18
+ private_class_method :new
19
+
20
+ # This method ensures child classes can be instantiated eventhough
21
+ # Branch.new cannot be.
22
+ def self.inherited(*)
23
+ public_class_method :new
24
+ end
25
+
26
+ # @param site [Hash] the site config from (TaskRunner.site)
27
+ # @param target [String] the name of the Git branch to deploy to
28
+ def initialize(site, target)
29
+ @site = site
30
+ @target = target
31
+ end
32
+
33
+ # Rebuild the Jekyll site with branch @baseurl
34
+ # @return [Nil]
35
+ def rebuild
36
+ if @baseurl.empty?
37
+ msg = 'Building the gh-pages _site without a baseurl is not recommended'
38
+ Logger.new($stdout).warn(msg.orange)
39
+ end
40
+ FileUtils.rm_r(SITE_DIR) if File.directory?(SITE_DIR)
41
+ opts = {
42
+ source: '.',
43
+ destination: SITE_DIR,
44
+ baseurl: @baseurl,
45
+ verbose: true
46
+ }
47
+ Jekyll::Site.new(Jekyll.configuration(opts)).process
48
+ end
49
+
50
+ # Add, commmit, and push compiled Jekyll site to @target branch
51
+ # @return [Nil]
52
+ def push
53
+ if @site[:env] == 'prod'
54
+ rebuild if @target == 'gh-pages'
55
+ raise Error::MissingSite, "Cannot find #{SITE_DIR}" unless Dir.exist? SITE_DIR
56
+ Dir.chdir(SITE_DIR)
57
+ system 'git init && git add .'
58
+ system "git commit -m '#{@commit_msg}'"
59
+ system "git remote add origin #{@origin}"
60
+ puts @success_msg.cyan
61
+ system "git push origin master:refs/heads/#{@target} --force"
62
+ else
63
+ puts "Skipping build for branch '#{@target}' on env='test'".orange
64
+ end
65
+ end
66
+ end
67
+
68
+ # Branch object for `$ wax:push` task when run on Travis-CI VM
69
+ # using encrypted Travis environment vars
70
+ #
71
+ # @attr repo_slug [String] the 'user/repo_name'
72
+ # @attr user [String] the GitHub user making the commit/push
73
+ # @attr token [String] secret git access token
74
+ # @attr commit_msg [String] the commit message to use on push
75
+ # @attr origin [String] the current repository remote
76
+ # @attr baseurl [String] the site baseurl to build with (if on gh-pages)
77
+ # @attr success_msg [String] informative message to be output to console
78
+ class TravisBranch < Branch
79
+ def initialize(site, target)
80
+ super(site, target)
81
+
82
+ @repo_slug = ENV['TRAVIS_REPO_SLUG']
83
+ @user = @repo_slug.split('/').first
84
+ @token = ENV['ACCESS_TOKEN']
85
+
86
+ @commit_msg = "Updated via #{ENV['TRAVIS_COMMIT']} @#{Time.now.utc}"
87
+ @origin = "https://#{@user}:#{@token}@github.com/#{@repo_slug}.git"
88
+ @baseurl = @repo_slug.split('/').last
89
+ @success_msg = "Deploying to #{@target} branch from Travis as #{@user}."
90
+ end
91
+ end
92
+
93
+ # Branch object for `$ wax:push` task when run on local machine
94
+ # using local credentials
95
+ #
96
+ # @attr origin [String] the current repository remote
97
+ # @attr commit_msg [String] the commit message to use on push
98
+ # @attr baseurl [String] the site baseurl to build with (if on gh-pages)
99
+ # @attr success_msg [String] informative message to be output to console
100
+ class LocalBranch < Branch
101
+ def initialize(site, target)
102
+ super(site, target)
103
+
104
+ @origin = `git config --get remote.origin.url`.strip
105
+ @commit_msg = "Updated via local task at #{Time.now.utc}"
106
+ @baseurl = @origin.split('/').last.gsub('.git', '')
107
+ @success_msg = "Deploying to #{@target} branch from local task."
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,61 @@
1
+ module WaxTasks
2
+ # Parent class representing a Jekyll collection
3
+ # that cannot be created directly. Only child classes
4
+ # (IiifCollection, LunrCollection, PagemasterCollection)
5
+ # can be initialized.
6
+ #
7
+ # @attr config [Hash] the collection config within site config
8
+ # @attr name [String] the name of the collection in site:collections
9
+ # @attr page_dir [String] the directory path for generated collection pages
10
+ # @attr site [Hash] the site config
11
+ class Collection
12
+ attr_reader :name, :page_dir
13
+ private_class_method :new
14
+
15
+ # This method ensures child classes can be instantiated though
16
+ # Collection.new cannot be.
17
+ def self.inherited(*)
18
+ public_class_method :new
19
+ end
20
+
21
+ # Creates a new collection with name @name given site config @site
22
+ #
23
+ # @param name [String] the name of the collection in site:collections
24
+ # @param site [Hash] the site config
25
+ def initialize(name, site)
26
+ @name = name
27
+ @site = site
28
+ @config = collection_config
29
+ @page_dir = Utils.make_path(@site[:source_dir],
30
+ @site[:collections_dir],
31
+ @name)
32
+ end
33
+
34
+ # Finds the collection config within the site config
35
+ #
36
+ # @return [Hash] the config for the collection
37
+ def collection_config
38
+ @site[:collections].fetch(@name)
39
+ rescue StandardError => e
40
+ raise Error::InvalidCollection, "Cannot load collection config for #{@name}.\n#{e}"
41
+ end
42
+
43
+ # Ingests the collection source data as an Array of Hashes
44
+ #
45
+ # @param source [String] the path to the CSV, JSON, or YAML source file
46
+ # @return [Array] the collection data
47
+ def ingest_file(source)
48
+ raise Error::MissingSource, "Cannot find #{source}" unless File.exist? source
49
+
50
+ case File.extname(source)
51
+ when '.csv' then data = WaxTasks::Utils.validate_csv(source)
52
+ when '.json' then data = WaxTasks::Utils.validate_json(source)
53
+ when /\.ya?ml/ then data = WaxTasks::Utils.validate_yaml(source)
54
+ else raise Error::InvalidSource, "Cannot load #{File.extname(source)} files. Culprit: #{source}"
55
+ end
56
+
57
+ WaxTasks::Utils.assert_pids(data)
58
+ WaxTasks::Utils.assert_unique(data)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,71 @@
1
+ module WaxTasks
2
+ # Custom WaxTasks Errors module
3
+ module Error
4
+ # Custom WaxTasks Error class with magenta console output
5
+ class WaxTasksError < StandardError
6
+ def initialize(msg = '')
7
+ super(msg.magenta)
8
+ end
9
+ end
10
+
11
+ # Custom Error:
12
+ # Site config cannot be found / parsed
13
+ class InvalidSiteConfig < WaxTasksError; end
14
+
15
+ # Custom Error:
16
+ # Collection specified cannot be found / parsed in site config
17
+ class InvalidCollection < WaxTasksError; end
18
+
19
+ # Custom Error:
20
+ # Collection data source type is not allowed or is an invalid file
21
+ class InvalidSource < WaxTasksError; end
22
+
23
+ # Custom Error:
24
+ # Data source file could not be found
25
+ class MissingSource < WaxTasksError; end
26
+
27
+ # Custom Error:
28
+ # While loading markdown pages to index, one could not be read
29
+ class LunrPageLoad < WaxTasksError; end
30
+
31
+ # Custom Error:
32
+ # Lunr collection does not have fields specified to index
33
+ class MissingFields < WaxTasksError; end
34
+
35
+ # Custom Error:
36
+ # Page layout was not specified for a pagemaster collection
37
+ class MissingLayout < WaxTasksError; end
38
+
39
+ # Custom Error:
40
+ # Collection item does not have a required pid value
41
+ class MissingPid < WaxTasksError; end
42
+
43
+ # Custom Error:
44
+ # Collection item has a non-unique pud value
45
+ class NonUniquePid < WaxTasksError; end
46
+
47
+ # Custom Error:
48
+ # Collection page item could not be generated
49
+ class PageFailure < WaxTasksError; end
50
+
51
+ # Custom Error:
52
+ # CSV file failed to lint + could not be loaded
53
+ class InvalidCSV < WaxTasksError; end
54
+
55
+ # Custom Error:
56
+ # JSON file failed to lint + could not be loaded
57
+ class InvalidJSON < WaxTasksError; end
58
+
59
+ # Custom Error:
60
+ # YAML file failed to lint + could not be loaded
61
+ class InvalidYAML < WaxTasksError; end
62
+
63
+ # Custom Error:
64
+ # No collections in site config have lunr_index parameters
65
+ class NoLunrCollections < WaxTasksError; end
66
+
67
+ # Custom Error:
68
+ # Cannot find _site directory to push to GitHub
69
+ class MissingSite < WaxTasksError; end
70
+ end
71
+ end
@@ -0,0 +1,105 @@
1
+ require 'wax_iiif'
2
+
3
+ module WaxTasks
4
+ # A Jekyll collection with IIIF configuration + data
5
+ #
6
+ # @attr src_data [String] the path to the data source file
7
+ # @attr iiif_config [Hash] the iiif configuration for the collection
8
+ # @attr meta [Array] metadata k,v rules
9
+ # @attr variants [Hash] image variants to generate e.g. { med: 650 }
10
+ # @attr src_dir [String] path to existing iiif source images
11
+ # @attr target_dir [String] target path for iiif derivatives
12
+ class IiifCollection < Collection
13
+ attr_reader :variants, :meta, :target_dir
14
+
15
+ # Creates a new IiifCollection with name @name given site config @site
16
+ def initialize(name, site)
17
+ super(name, site)
18
+
19
+ @src_data = @config.fetch('source', nil)
20
+ @iiif_config = @config.fetch('iiif', {})
21
+ @meta = @iiif_config.fetch('meta', nil)
22
+ @variants = validated_variants
23
+ @src_dir = Utils.make_path(@site[:source_dir],
24
+ '_data/iiif',
25
+ @name)
26
+ @target_dir = Utils.make_path(@site[:source_dir],
27
+ 'iiif',
28
+ @name)
29
+ end
30
+
31
+ # Main method for generating iiif derivatives and json
32
+ # @return [Nil]
33
+ def process
34
+ raise Error::MissingIiifSrc, "Cannot find IIIF source directory #{@src_dir}" unless Dir.exist?(@src_dir)
35
+ FileUtils.mkdir_p(@target_dir, verbose: false)
36
+ builder = iiif_builder
37
+ builder.load(iiif_records)
38
+ builder.process_data(true)
39
+ end
40
+
41
+ # Creates a IiifS3::Builder object from collection config
42
+ # @return [Object]
43
+ def iiif_builder
44
+ build_opts = {
45
+ base_url: "#{@site[:baseurl]}/iiif/#{@name}",
46
+ output_dir: @target_dir,
47
+ verbose: true,
48
+ variants: @variants
49
+ }
50
+ IiifS3::Builder.new(build_opts)
51
+ end
52
+
53
+ # Gets custom image variants from collection config if available
54
+ # Else returns default variants { med: 600, lg: 1140 } to Builder
55
+ #
56
+ # @return [Hash]
57
+ def validated_variants
58
+ vars = @iiif_config.fetch('variants', false)
59
+ if vars.is_a?(Array) && vars.all? { |v| v.is_a?(Integer) }
60
+ variants = {}
61
+ vars.each_with_index do |v, i|
62
+ variants["custom_variant_#{i}".to_sym] = v
63
+ end
64
+ else
65
+ variants = { med: 600, lg: 1140 }
66
+ end
67
+ variants
68
+ end
69
+
70
+ # Creates an array of IIIfS3 ImageRecords from the collection config
71
+ # for the IiifS3 Builder to process
72
+ #
73
+ # @return [Array]
74
+ def iiif_records
75
+ records = []
76
+ source_images = Dir["#{@src_dir}/*"].sort!
77
+ if @meta && @src_data
78
+ src_path = Utils.make_path(@site[:source_dir], '_data', @src_data)
79
+ metadata = ingest_file(src_path)
80
+ else
81
+ metadata = false
82
+ end
83
+ source_images.each { |src_img| records << iiif_record(src_img, metadata) }
84
+ records
85
+ end
86
+
87
+ # Creates an individual IiifS3 ImageRecord
88
+ # with metadata from source data file if available
89
+ #
90
+ # @param src_img [String] path to the original source image
91
+ # @param metadata [Hash] metadata to add to the item if available
92
+ # @return [Object]
93
+ def iiif_record(src_img, metadata)
94
+ basename = File.basename(src_img, '.*').to_s
95
+ record_opts = { id: basename, path: src_img, label: basename }
96
+ if metadata
97
+ src_item = metadata.find { |i| i['pid'].to_s == basename }
98
+ @meta.each do |i|
99
+ record_opts[i.first[0].to_sym] = src_item.fetch(i.first[1], '')
100
+ end
101
+ end
102
+ IiifS3::ImageRecord.new(record_opts)
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,59 @@
1
+ module WaxTasks
2
+ # A Jekyll collection to be Indexed in a Lunr Index / JSON file
3
+ # for client-side search.
4
+ #
5
+ # @attr index_config [Hash] the collection's lunr_index config
6
+ # @attr content [Boolean] whether/not page content should be indexed
7
+ # @attr fields [Array] the fields (i.e., keys) that should be indexed
8
+ # @attr data [Array] hash array of data from the ingested pages
9
+ class LunrCollection < Collection
10
+ attr_accessor :fields, :data
11
+
12
+ # Creates a new LunrCollection with name @name given site config @site
13
+ def initialize(name, site)
14
+ super(name, site)
15
+
16
+ @index_config = @config['lunr_index']
17
+ @content = @index_config.fetch('content', false)
18
+ @fields = @index_config.fetch('fields', [])
19
+ @data = ingest_pages
20
+
21
+ raise Error::MissingFields, "There are no fields for #{@name}.".magenta if @fields.empty?
22
+ end
23
+
24
+ # Finds the @page_dir of markdown pages for the collection and ingests
25
+ # them as an array of hashes
26
+ #
27
+ # @return [Array] array of the loaded markdown pages loaded as hashes
28
+ def ingest_pages
29
+ data = []
30
+ pages = Dir.glob("#{@page_dir}/*.md")
31
+ puts "There are no pages in #{@page_dir} to index.".cyan if pages.empty?
32
+ pages.each do |p|
33
+ begin
34
+ data << load_page(p)
35
+ rescue StandardError => e
36
+ raise Error::LunrPageLoad, "Cannot load page #{p}\n#{e}"
37
+ end
38
+ end
39
+ data
40
+ end
41
+
42
+ # Reads in a markdown file and converts it to a hash
43
+ # with the values from @fields.
44
+ # Adds the content of the file (below the YAML) if @content == true
45
+ #
46
+ # @param page [String] the path to a markdown page to load
47
+ def load_page(page)
48
+ yaml = YAML.load_file(page)
49
+ hash = {
50
+ 'link' => "{{'#{yaml.fetch('permalink')}' | relative_url }}",
51
+ 'collection' => @name
52
+ }
53
+ hash['content'] = File.read(page).html_strip.remove_diacritics if @content
54
+ fields = @fields.push('pid').uniq
55
+ fields.each { |f| hash[f] = yaml[f].normalize }
56
+ hash
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,67 @@
1
+ module WaxTasks
2
+ # A LunrIndex document that combines data from all collections
3
+ # in site config that have `lunr_index` parameters.
4
+ #
5
+ # @attr collections [Array] a list of LunrCollection objects
6
+ # @attr fields [Array] shared list of fields to index among LunrCollections
7
+ class LunrIndex
8
+ attr_accessor :collections, :fields
9
+
10
+ # Creates a new LunrIndex object
11
+ def initialize(collections)
12
+ @collections = collections
13
+ @fields = total_fields
14
+ end
15
+
16
+ # @return [Array] shared list of fields to index among LunrCollections
17
+ def total_fields
18
+ total_fields = @collections.map(&:fields).reduce([], :concat)
19
+ total_fields.uniq
20
+ end
21
+
22
+ # @return [String] writes index data as pretty JSON with YAML front-matter
23
+ def to_s
24
+ data = @collections.map(&:data).flatten
25
+ data.each_with_index.map { |d, id| d['lunr_index'] = id }
26
+ "---\nlayout: none\n---\n#{JSON.pretty_generate(data)}"
27
+ end
28
+
29
+ # Creates a default LunrUI / JS file for displaying the Index
30
+ #
31
+ # @return [String]
32
+ def default_ui
33
+ <<~HEREDOC
34
+ ---
35
+ layout: none
36
+ ---
37
+ $.getJSON({{ site.baseurl }}/js/lunr-index.json, function(index_json) {
38
+ window.index = new elasticlunr.Index;
39
+ window.store = index_json;
40
+ index.saveDocument(false);
41
+ index.setRef('lunr_id');
42
+ #{@fields.map { |f| "index.addField('#{f}');" }.join("\n")}
43
+ // add docs
44
+ for (i in store){
45
+ index.addDoc(store[i]);
46
+ }
47
+ $('input#search').on('keyup', function() {
48
+ var results_div = $('#results');
49
+ var query = $(this).val();
50
+ var results = index.search(query, { boolean: 'AND', expand: true });
51
+ results_div.empty();
52
+ if (results.length > 10) {
53
+ results_div.prepend("<p><small>Displaying 10 of " + results.length + " results.</small></p>");
54
+ }
55
+ for (var r in results.slice(0, 9)) {
56
+ var ref = results[r].ref;
57
+ var item = store[ref];
58
+ #{@fields.map { |f| "var #{f} = item.#{f};" }.join("\n")}
59
+ var result = '<div class="result"><b><a href="' + item.link + '">' + title + '</a></b></p></div>';
60
+ results_div.append(result);
61
+ }
62
+ });
63
+ });
64
+ HEREDOC
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,67 @@
1
+ module WaxTasks
2
+ # A Jekyll collection with a data source file that
3
+ # can generate markdown pages from that data.
4
+ #
5
+ # @attr source [String] the path to the data source file
6
+ # @attr layout [String] the Jekyll layout to be used by the generated pages
7
+ # @attr data [Array] array of hashes representing the ingested data file
8
+ # @attr ordered [Boolean] whether/not the order of items should be preserved
9
+ class PagemasterCollection < Collection
10
+ attr_reader :source, :layout, :data, :ordered
11
+
12
+ # Creates a new PagemasterCollection with name @name given site config @site
13
+ def initialize(name, site)
14
+ super(name, site)
15
+
16
+ @source = source_path
17
+ @layout = assert_layout
18
+ @data = ingest_file(@source)
19
+ @ordered = @config.fetch('keep_order', false)
20
+ end
21
+
22
+ # Constructs the path to the data source file
23
+ #
24
+ # @return [String] the path to the data source file
25
+ def source_path
26
+ raise WaxTasks::Error::MissingSource, "Missing collection source in _config.yml for #{@name}" unless @config.key? 'source'
27
+ WaxTasks::Utils.make_path(@site[:source_dir], '_data', @config['source'])
28
+ end
29
+
30
+ # Confirms + requires `layout` value in the collection @config
31
+ #
32
+ # @return [String] the Jekyll layout to be used by the generated pages
33
+ def assert_layout
34
+ raise WaxTasks::Error::MissingLayout, "Missing collection layout in _config.yml for #{@name}" unless @config.key? 'layout'
35
+ @config['layout']
36
+ end
37
+
38
+ # Writes markdown pages from the ingested data to @page_dir
39
+ # with layout, permalink, and order info added (if applicable)
40
+ #
41
+ # @return [Array] a copy of the pages as hashes, for testing
42
+ def generate_pages
43
+ FileUtils.mkdir_p(@page_dir)
44
+ pages = []
45
+ @data.each_with_index do |item, idx|
46
+ page_slug = item.fetch('pid').to_s.slug
47
+ path = "#{@page_dir}/#{page_slug}.md"
48
+ item['permalink'] = "/#{@name}/#{page_slug}#{@site[:permalink]}"
49
+ item['layout'] = @layout
50
+ item['order'] = padded_int(idx, @data.length) if @ordered
51
+ pages << item
52
+ next "#{page_slug}.md already exits. Skipping." if File.exist?(path)
53
+ File.open(path, 'w') { |f| f.write("#{item.to_yaml}---") }
54
+ end
55
+ puts "#{@data.length} pages were generated to #{@page_dir} directory.".cyan
56
+ pages
57
+ end
58
+
59
+ # Constructs the order variable for each page (if the collection
60
+ # needs to preserve the order of items from the file)
61
+ #
62
+ # @return [Integer] the order if the item padded with '0's for sorting
63
+ def padded_int(idx, max_idx)
64
+ idx.to_s.rjust(Math.log10(max_idx).to_i + 1, '0')
65
+ end
66
+ end
67
+ end