cloudcannon-jekyll 0.2.1 → 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: 9ae3c8abe082ec3f37215dec374610ec9afdbcfdf657088948285375e847410f
4
- data.tar.gz: 44974881ddba3a62062337da11a56d1fbdd406fa04cead477b216866d88bf5cc
3
+ metadata.gz: e4dd4e81ac500818217dfbceb63a6a8ed6ecef91583c1e84d08c43fcbeac9294
4
+ data.tar.gz: c6da0f3528124a84695ea6410f9199dcd3617a9711a4a0859be83f43107ef11b
5
5
  SHA512:
6
- metadata.gz: 8d894aea066bba58238ac0a2dbcc277eee56c84d3aeddea107089db51717266f313001d187ac6f5bf077f3f46c044b5842e3e02afa96a0d38fcc8f967889a1c2
7
- data.tar.gz: f51833d3e91c35ca0e2fa0020b4844a0727c969bf026d01f83922c384ec5b4a0bc68afa11032434a8947281664daf0f5b89f44066d4fb0b76969e8a056486923
6
+ metadata.gz: f76962928b6592d53881f14e407a1cd492790e9b170e515307a6d2b9c001953b5866a89481ab9f1a1b1642ecad3cbb4ae02919c1f8e412fc00a2af060bf7cc91
7
+ data.tar.gz: 666d55022ea8f7255448db6a97e083e7332d06ec25dae0a07cef221322e4b2745a45f5c77979a636e5d0e4c0fff778f52eb22982662917fba8a2c68bec46a905
@@ -0,0 +1,19 @@
1
+ name: Mark stale issues
2
+
3
+ on:
4
+ schedule:
5
+ - cron: "30 1 * * *"
6
+
7
+ jobs:
8
+ stale:
9
+
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/stale@v1
14
+ with:
15
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
16
+ stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days'
17
+ stale-issue-label: 'no-issue-activity'
18
+ days-before-stale: 30
19
+ days-before-close: 5
@@ -0,0 +1,6 @@
1
+ detectors:
2
+ LongParameterList:
3
+ max_params: 4 # Matches the Rubocop setting
4
+
5
+ exclude_paths:
6
+ - spec
@@ -28,15 +28,12 @@ Naming/MemoizedInstanceVariableName:
28
28
  Metrics/CyclomaticComplexity:
29
29
  Exclude:
30
30
  - lib/cloudcannon-jekyll/jsonify-filter.rb # TODO remove this and fix warnings
31
+ - lib/cloudcannon-jekyll/readers/old-data-reader.rb # TODO remove this and fix warnings
31
32
 
32
33
  Metrics/PerceivedComplexity:
33
34
  Exclude:
34
35
  - lib/cloudcannon-jekyll/jsonify-filter.rb # TODO remove this and fix warnings
35
36
 
36
- Metrics/MethodLength:
37
- Exclude:
38
- - lib/cloudcannon-jekyll/jsonify-filter.rb # TODO remove this and fix warnings
39
-
40
37
  Metrics/AbcSize:
41
38
  Exclude:
42
39
  - lib/cloudcannon-jekyll/jsonify-filter.rb # TODO remove this and fix warnings
data/HISTORY.md CHANGED
@@ -1,3 +1,22 @@
1
+ # 0.3.0
2
+
3
+ * Added drafts to collections in details
4
+ * Added drafts and data to collections in config
5
+ * Added category folder drafts and posts to collections in config
6
+ * Added `_path` field to each collection definition in config
7
+ * Removed some unused fields
8
+ * Renamed static to static-pages in details and removed `robots.txt` and `sitemap.xml` exceptions
9
+ * Add `url` to static-pages
10
+ * Normalise `_path` in static-pages
11
+ * Added max depth parameter for jsonify filter and increase it for array structures in config output
12
+
13
+ # 0.2.2
14
+
15
+ * Added JSON handling for integers in hash keys
16
+ * Fix typo for collections key in older Jekyll versions
17
+ * Change date format to ISO8601
18
+ * Validate against new version of config schema
19
+
1
20
  # 0.2.1
2
21
 
3
22
  * Add gem information and time to output config file
@@ -10,9 +10,9 @@ require_relative "cloudcannon-jekyll/version"
10
10
 
11
11
  Liquid::Template.register_filter(CloudCannonJekyll::JsonifyFilter)
12
12
 
13
- # Hooks didn't exist in Jekyll 2 so we monkey patch to get an :after_reset hook
14
- if Jekyll::VERSION.start_with? "2"
13
+ if Jekyll::VERSION.start_with? "2."
15
14
  module Jekyll
15
+ # Hooks didn't exist in Jekyll 2 so we monkey patch to get an :after_reset hook
16
16
  class Site
17
17
  alias_method :jekyll_reset, :reset
18
18
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "time": {{ site.time | cc_jsonify }},
2
+ "time": {{ site.time | date_to_xmlschema | cc_jsonify }},
3
3
  "cloudcannon": {
4
4
  "name": "cloudcannon-jekyll",
5
5
  "version": {{ gem_version | cc_jsonify }}
@@ -8,7 +8,7 @@
8
8
  "include": {{ config.include | cc_jsonify }},
9
9
  "exclude": {{ config.exclude | cc_jsonify }},
10
10
  {% if config.baseurl %}"base-url": {{ config.baseurl | cc_jsonify }},{% endif %}
11
- {% if config.collections %}"comments": {{ config.collections | cc_jsonify: 'collections' }},{% endif %}
11
+ "collections": {{ collections | cc_jsonify: 'collections' }},
12
12
  {% if config._comments %}"comments": {{ config._comments | cc_jsonify }},{% endif %}
13
13
  {% if config._options %}"input-options": {{ config._options | cc_jsonify }},{% endif %}
14
14
  {% if config.defaults %}"defaults": {{ config.defaults | cc_jsonify }},{% endif %}
@@ -25,11 +25,12 @@
25
25
  "uploads": {{ config.uploads_dir | cc_jsonify }},
26
26
  "plugins": {{ config.plugins_dir | cc_jsonify }},
27
27
  "data": {{ config.data_dir | cc_jsonify }},
28
+ "pages": "",
28
29
  "collections": {{ config.collections_dir | cc_jsonify }},
29
30
  "includes": {{ config.includes_dir | cc_jsonify }},
30
31
  "layouts": {{ config.layouts_dir | cc_jsonify }}
31
32
  },
32
- {% if config._array_structures %}"array-structures": {{ config._array_structures | cc_jsonify }},{% endif %}
33
+ {% if config._array_structures %}"array-structures": {{ config._array_structures | cc_jsonify: nil, 20 }},{% endif %}
33
34
  {% assign select_data = config | cc_select_data_jsonify %}{% if select_data %}"select-data": {{ select_data }},{% endif %}
34
35
  "source": {{ config.source | replace: pwd, "" | cc_jsonify }}
35
36
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "time": {{ site.time | cc_jsonify }},
2
+ "time": {{ site.time | date_to_xmlschema | cc_jsonify }},
3
3
  "cloudcannon": {
4
4
  "name": "cloudcannon-jekyll",
5
5
  "version": {{ gem_version | cc_jsonify }}
@@ -8,7 +8,7 @@
8
8
  "include": {{ config.include | cc_jsonify }},
9
9
  "exclude": {{ config.exclude | cc_jsonify }},
10
10
  {% if config.baseurl %}"base-url": {{ config.baseurl | cc_jsonify }},{% endif %}
11
- {% if config.collections %}"comments": {{ config.collections | cc_jsonify: 'collections' }},{% endif %}
11
+ "collections": {{ collections | cc_jsonify: 'collections' }},
12
12
  {% if config._comments %}"comments": {{ config._comments | cc_jsonify }},{% endif %}
13
13
  {% if config._options %}"input-options": {{ config._options | cc_jsonify }},{% endif %}
14
14
  {% if config.defaults %}"defaults": {{ config.defaults | cc_jsonify }},{% endif %}
@@ -25,11 +25,12 @@
25
25
  "uploads": {{ config.uploads_dir | cc_jsonify }},
26
26
  "plugins": {{ config.plugins_dir | cc_jsonify }},
27
27
  "data": {{ config.data_dir | cc_jsonify }},
28
+ "pages": "",
28
29
  "collections": {{ config.collections_dir | cc_jsonify }},
29
30
  "includes": {{ config.includes_dir | cc_jsonify }},
30
31
  "layouts": {{ config.layouts_dir | cc_jsonify }}
31
32
  },
32
- {% if config._array_structures %}"array-structures": {{ config._array_structures | cc_jsonify }},{% endif %}
33
+ {% if config._array_structures %}"array-structures": {{ config._array_structures | cc_jsonify: nil, 20 }},{% endif %}
33
34
  {% assign select_data = config | cc_select_data_jsonify %}{% if select_data %}"select-data": {{ select_data }},{% endif %}
34
35
  "source": {{ config.source | replace: pwd, "" | cc_jsonify }}
35
36
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "time": {{ site.time | cc_jsonify }},
2
+ "time": {{ site.time | date_to_xmlschema | cc_jsonify }},
3
3
  "cloudcannon": {
4
4
  "name": "cloudcannon-jekyll",
5
5
  "version": {{ gem_version | cc_jsonify }}
@@ -12,9 +12,7 @@
12
12
  {% if config.baseurl -%}
13
13
  "base-url": {{ config.baseurl | cc_jsonify }},
14
14
  {%- endif %}
15
- {% if config.collections -%}
16
- "collections": {{ config.collections | cc_jsonify: 'collections' }},
17
- {%- endif %}
15
+ "collections": {{ collections | cc_jsonify: 'collections' }},
18
16
  {% if config._comments -%}
19
17
  "comments": {{ config._comments | cc_jsonify }},
20
18
  {%- endif %}
@@ -43,12 +41,13 @@
43
41
  "uploads": {{ config.uploads_dir | cc_jsonify }},
44
42
  "plugins": {{ config.plugins_dir | cc_jsonify }},
45
43
  "data": {{ config.data_dir | cc_jsonify }},
44
+ "pages": "",
46
45
  "collections": {{ config.collections_dir | cc_jsonify }},
47
46
  "includes": {{ config.includes_dir | cc_jsonify }},
48
47
  "layouts": {{ config.layouts_dir | cc_jsonify }}
49
48
  },
50
49
  {% if config._array_structures -%}
51
- "array-structures": {{ config._array_structures | cc_jsonify }},
50
+ "array-structures": {{ config._array_structures | cc_jsonify: nil, 20 }},
52
51
  {%- endif %}
53
52
  {% assign select_data = config | cc_select_data_jsonify -%}
54
53
  {% if select_data -%}
@@ -1,5 +1,5 @@
1
1
  {
2
- "time": {{ site.time | cc_jsonify }},
2
+ "time": {{ site.time | date_to_xmlschema | cc_jsonify }},
3
3
  "cloudcannon": {
4
4
  "name": "cloudcannon-jekyll",
5
5
  "version": {{ gem_version | cc_jsonify }}
@@ -18,10 +18,11 @@
18
18
  {% for data in site.data %}{% assign key = data[0] %}{% if site.cloudcannon.data[key] %}{% if data_seen %},{% endif %}{{ data[0] | cc_jsonify }}: {{ data[1] | cc_jsonify }}{% assign data_seen = true %}{% endif %}{% endfor %}},
19
19
  {% elsif site.cloudcannon.data %}"data": {{ site.data | cc_jsonify }},{% endif %}
20
20
  "collections": {
21
+ "drafts": {{ drafts | cc_jsonify }},
21
22
  "posts": {{ site.posts | reverse | cc_jsonify }}{% if site.collections.size > 0 %},{% endif %}
22
23
  {% for collection in site.collections %}"{{ collection[0] | xml_escape }}": {{ collection[1].docs | cc_jsonify }}{% unless forloop.last %},{% endunless %}
23
24
  {% endfor %}
24
25
  },
25
26
  "pages": {{ site.pages | cc_jsonify }},
26
- "static": {{ site.static_files | cc_static_files_jsonify }}
27
+ "static-pages": {{ site.static_files | cc_static_files_jsonify }}
27
28
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "time": {{ site.time | cc_jsonify }},
2
+ "time": {{ site.time | date_to_xmlschema | cc_jsonify }},
3
3
  "cloudcannon": {
4
4
  "name": "cloudcannon-jekyll",
5
5
  "version": {{ gem_version | cc_jsonify }}
@@ -18,9 +18,10 @@
18
18
  {% for data in site.data %}{% assign key = data[0] %}{% if site.cloudcannon.data[key] %}{% if data_seen %},{% endif %}{{ data[0] | cc_jsonify }}: {{ data[1] | cc_jsonify }}{% assign data_seen = true %}{% endif %}{% endfor %}},
19
19
  {% elsif site.cloudcannon.data %}"data": {{ site.data | cc_jsonify }},{% endif %}
20
20
  "collections": {
21
+ "drafts": {{ drafts | cc_jsonify }}{% if site.collections.size > 0 %},{% endif %}
21
22
  {% for collection in site.collections %}"{{ collection.label | xml_escape }}": {{ collection.docs | cc_jsonify }}{% unless forloop.last %},{% endunless %}
22
23
  {% endfor %}
23
24
  },
24
25
  "pages": {{ site.pages | cc_jsonify }},
25
- "static": {{ site.static_files | cc_static_files_jsonify }}
26
+ "static-pages": {{ site.static_files | cc_static_files_jsonify }}
26
27
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "time": {{ site.time | cc_jsonify }},
2
+ "time": {{ site.time | date_to_xmlschema | cc_jsonify }},
3
3
  "cloudcannon": {
4
4
  "name": "cloudcannon-jekyll",
5
5
  "version": {{ gem_version | cc_jsonify }}
@@ -30,11 +30,12 @@
30
30
  "data": {{ site.data | cc_jsonify }},
31
31
  {%- endif %}
32
32
  "collections": {
33
+ "drafts": {{ drafts | cc_jsonify }}{% if site.collections.size > 0 %},{% endif %}
33
34
  {%- for collection in site.collections -%}
34
35
  "{{ collection.label | xml_escape }}": {{ collection.docs | cc_jsonify }}
35
36
  {%- unless forloop.last %},{% endunless %}
36
37
  {%- endfor -%}
37
38
  },
38
39
  "pages": {{ site.pages | cc_jsonify }},
39
- "static": {{ site.static_files | cc_static_files_jsonify }}
40
+ "static-pages": {{ site.static_files | cc_static_files_jsonify }}
40
41
  }
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CloudCannonJekyll
4
+ # Processes Jekyll configuration to enable the plugin is run and fix common issues
4
5
  class Configuration
5
6
  def self.processed?(site)
6
7
  site.instance_variable_get(:@_cloudcannon_jekyll_processed) == true
@@ -16,7 +17,7 @@ module CloudCannonJekyll
16
17
  config = config.fix_common_issues if config.respond_to? :fix_common_issues
17
18
  config = config.add_default_excludes if config.respond_to? :add_default_excludes
18
19
 
19
- key = Jekyll::VERSION.start_with?("2") ? "gems" : "plugins"
20
+ key = Jekyll::VERSION.start_with?("2.") ? "gems" : "plugins"
20
21
 
21
22
  config[key] = Array(config[key])
22
23
  config[key].push("cloudcannon-jekyll") unless config[key].include? "cloudcannon-jekyll"
@@ -2,32 +2,120 @@
2
2
 
3
3
  require "jekyll"
4
4
  require "fileutils"
5
+ require_relative "reader"
5
6
 
6
7
  module CloudCannonJekyll
8
+ # Generates JSON files containing build config and build output details
7
9
  class Generator < Jekyll::Generator
8
10
  priority :lowest
9
11
 
10
12
  def generate(site)
11
13
  @site = site
14
+ @reader = Reader.new(@site)
15
+
16
+ collections_config = @site.config["collections"].dup || {}
12
17
 
13
18
  payload = @site.site_payload.merge({
14
19
  "gem_version" => CloudCannonJekyll::VERSION,
20
+ })
21
+
22
+ drafts = add_blogging_config(collections_config)
23
+ add_collection_paths(collections_config)
24
+ add_data_config(collections_config)
25
+
26
+ generate_file("config", payload.merge({
15
27
  "pwd" => Dir.pwd,
16
28
  "config" => @site.config,
17
- })
29
+ "collections" => collections_config,
30
+ }))
31
+
32
+ generate_file("details", payload.merge({
33
+ "drafts" => drafts,
34
+ }))
35
+ end
18
36
 
19
- generate_file("details", payload)
20
- generate_file("config", payload)
37
+ def collections_dir
38
+ return "" if Jekyll::VERSION.start_with? "2."
21
39
 
22
- @site.keep_files ||= []
23
- @site.keep_files << path("details")
24
- @site.keep_files << path("config")
40
+ @site.config["collections_dir"] || ""
41
+ end
42
+
43
+ def data_dir
44
+ @site.config["data_dir"] || "_data"
45
+ end
46
+
47
+ def add_category_folder_config(collections_config, posts_config = {})
48
+ posts = @site.posts || @site.collections["posts"]
49
+ seen = {}
50
+
51
+ posts.map do |post|
52
+ parts = post.relative_path.split("/_posts/")
53
+ path = parts.first
54
+
55
+ # Ignore unless it's an unseen category folder post
56
+ next if parts.length < 2 || path.empty? || seen[path]
57
+
58
+ # Could check this to ensure raw files exist since posts can be generated without files
59
+ # next if @reader.read_posts(parts[0]).empty?
60
+
61
+ seen[path] = true
62
+ folder = path.sub(%r!^\/+!, "")
63
+ collections_path = "#{collections_dir}/#{folder}".gsub(%r!\/+!, "/").sub(%r!^\/+!, "")
64
+
65
+ collections_config["#{folder}/posts"] = posts_config.merge({
66
+ "_path" => "#{collections_path}/_posts",
67
+ })
68
+
69
+ # Adding the category draft config like this isn't ideal, since you could have drafts
70
+ # without posts, but it's a decent trade off vs looking for _drafts folders
71
+ collections_config["#{folder}/drafts"] = posts_config.merge({
72
+ "_path" => "#{collections_path}/_drafts",
73
+ })
74
+
75
+ path
76
+ end
77
+ end
78
+
79
+ # Add data to collections config if raw data files exist
80
+ def add_data_config(collections_config)
81
+ data_files = @reader.read_data(data_dir)
82
+ collections_config["data"] = { "_path" => data_dir } if data_files&.keys&.any?
83
+ end
84
+
85
+ # Add posts/drafts to collections config
86
+ def add_blogging_config(collections_config)
87
+ collections_config["posts"] = { "output" => true } if Jekyll::VERSION.start_with? "2."
88
+ drafts = @reader.read_drafts(collections_dir)
89
+
90
+ if collections_config.key?("posts")
91
+ collections_config["drafts"] = collections_config["posts"].dup
92
+ elsif drafts.any?
93
+ collections_config["drafts"] = {}
94
+ end
95
+
96
+ folders = add_category_folder_config(collections_config, collections_config["posts"])
97
+ folders.compact.each do |folder|
98
+ drafts += @reader.read_drafts(folder)
99
+ end
100
+
101
+ drafts
102
+ end
103
+
104
+ # Add _path to each collection config
105
+ def add_collection_paths(collections_config)
106
+ collections_config.each do |key, collection|
107
+ next if collection.key?("_path")
108
+
109
+ collection["_path"] = File.join(collections_dir, "_#{key}").sub(%r!^\/+!, "")
110
+ end
25
111
  end
26
112
 
27
113
  def generate_file(filename, data)
28
114
  dest = destination_path(filename)
29
115
  FileUtils.mkdir_p(File.dirname(dest))
30
- File.open(dest, "w") { |f| f.write(file_content(filename, data)) }
116
+ File.open(dest, "w") { |file| file.write(file_content(filename, data)) }
117
+ @site.keep_files ||= []
118
+ @site.keep_files << path(filename)
31
119
  end
32
120
 
33
121
  def version_path_suffix
@@ -50,13 +138,13 @@ module CloudCannonJekyll
50
138
  end
51
139
 
52
140
  def file_content(filename, data)
53
- json = PageWithoutAFile.new(@site, File.dirname(__FILE__), "", path(filename))
54
- json.content = File.read(source_path(filename))
55
- json.data["layout"] = nil
56
- json.data["sitemap"] = false
57
- json.data["permalink"] = "/#{path(filename)}"
58
- json.render({}, data)
59
- json.output
141
+ page = PageWithoutAFile.new(@site, File.dirname(__FILE__), "", path(filename))
142
+ page.content = File.read(source_path(filename))
143
+ page.data["layout"] = nil
144
+ page.data["sitemap"] = false
145
+ page.data["permalink"] = "/#{path(filename)}"
146
+ page.render({}, data)
147
+ page.output
60
148
  end
61
149
  end
62
150
  end
@@ -3,7 +3,10 @@
3
3
  require "jekyll"
4
4
 
5
5
  module CloudCannonJekyll
6
+ # Filter for converting Jekyll objects into JSON
6
7
  module JsonifyFilter
8
+ STATIC_EXTENSIONS = [".html", ".htm"].freeze
9
+
7
10
  CC_JSONIFY_KEY_SWAPS = {
8
11
  "collections" => {
9
12
  "_sort_key" => "_sort-key",
@@ -42,102 +45,101 @@ module CloudCannonJekyll
42
45
  @simple_types.include?(input.class) || [true, false].include?(input)
43
46
  end
44
47
 
45
- def self.static_file_to_json(input, depth)
48
+ def self.static_file_to_json(input, depth, max_depth)
49
+ path = input.relative_path.sub(%r!^\/+!, "")
50
+ url = Jekyll::VERSION.start_with?("2.") ? "/#{path}" : input.url
51
+
46
52
  out = [
47
- "\"extname\": #{JsonifyFilter.to_json(input.extname, depth + 1)}",
48
- "\"path\": #{JsonifyFilter.to_json(input.relative_path, depth + 1)}",
53
+ "\"path\": #{JsonifyFilter.to_json(path, depth, max_depth)}",
54
+ "\"url\": #{JsonifyFilter.to_json(url, depth, max_depth)}",
49
55
  ]
50
56
 
51
- # modified_time isn't defined in Jekyll 2.4.0
52
- if input.respond_to? :modified_time
53
- out.push("\"modified_time\": #{JsonifyFilter.to_json(input.modified_time, depth + 1)}")
54
- end
55
-
56
57
  "{#{out.join(",")}}"
57
58
  end
58
59
 
59
- def self.document_data_to_json(data, out, prevent, depth)
60
+ def self.document_data_to_a(data, prevent, depth, max_depth)
60
61
  prevent += %w(content output next previous excerpt)
61
62
 
62
- data.each do |key, value|
63
+ out = data.map do |key, value|
63
64
  next if prevent.include? key
64
65
 
65
66
  prevent.push key
66
- out.push("#{key.to_json}: #{JsonifyFilter.to_json(value, depth + 1)}")
67
+ "#{key.to_json}: #{JsonifyFilter.to_json(value, depth, max_depth)}"
67
68
  end
68
69
 
69
- "{#{out.join(",")}}"
70
+ out.compact
70
71
  end
71
72
 
72
- def self.legacy_post_to_json(input, depth)
73
+ def self.legacy_post_to_json(input, depth, max_depth)
73
74
  prevent = %w(dir name path url date id categories tags)
74
75
 
75
76
  out = [
76
- "\"dir\": #{JsonifyFilter.to_json(input.dir, depth + 1)}",
77
- "\"name\": #{JsonifyFilter.to_json(input.name, depth + 1)}",
78
- "\"path\": #{JsonifyFilter.to_json(input.path, depth + 1)}",
79
- "\"url\": #{JsonifyFilter.to_json(input.url, depth + 1)}",
80
- "\"date\": #{JsonifyFilter.to_json(input.date, depth + 1)}",
81
- "\"id\": #{JsonifyFilter.to_json(input.id, depth + 1)}",
82
- "\"categories\": #{JsonifyFilter.to_json(input.categories, depth + 1)}",
83
- "\"tags\": #{JsonifyFilter.to_json(input.tags, depth + 1)}",
77
+ "\"name\": #{JsonifyFilter.to_json(input.name, depth, max_depth)}",
78
+ "\"path\": #{JsonifyFilter.to_json(input.path, depth, max_depth)}",
79
+ "\"url\": #{JsonifyFilter.to_json(input.url, depth, max_depth)}",
80
+ "\"date\": #{JsonifyFilter.to_json(input.date, depth, max_depth)}",
81
+ "\"id\": #{JsonifyFilter.to_json(input.id, depth, max_depth)}",
82
+ "\"categories\": #{JsonifyFilter.to_json(input.categories, depth, max_depth)}",
83
+ "\"tags\": #{JsonifyFilter.to_json(input.tags, depth, max_depth)}",
84
84
  ]
85
85
 
86
- JsonifyFilter.document_data_to_json(input.data, out, prevent, depth)
86
+ out += JsonifyFilter.document_data_to_a(input.data, prevent, depth, max_depth)
87
+ "{#{out.join(",")}}"
87
88
  end
88
89
 
89
- def self.page_to_json(input, depth)
90
+ def self.page_to_json(input, depth, max_depth)
90
91
  prevent = %w(dir name path url)
91
92
 
92
93
  out = [
93
- "\"dir\": #{JsonifyFilter.to_json(input.dir, depth + 1)}",
94
- "\"name\": #{JsonifyFilter.to_json(input.name, depth + 1)}",
95
- "\"path\": #{JsonifyFilter.to_json(input.path, depth + 1)}",
96
- "\"url\": #{JsonifyFilter.to_json(input.url, depth + 1)}",
94
+ "\"name\": #{JsonifyFilter.to_json(input.name, depth, max_depth)}",
95
+ "\"path\": #{JsonifyFilter.to_json(input.path, depth, max_depth)}",
96
+ "\"url\": #{JsonifyFilter.to_json(input.url, depth, max_depth)}",
97
97
  ]
98
98
 
99
99
  # Merge Jekyll Defaults into data for pages (missing at v3.8.5)
100
- defaults = input.site.frontmatter_defaults.all(input.relative_path, :pages).tap do |h|
101
- h.delete("date")
100
+ defaults = input.site.frontmatter_defaults.all(input.relative_path, :pages).tap do |default|
101
+ default.delete("date")
102
102
  end
103
103
 
104
104
  data = Jekyll::Utils.deep_merge_hashes(defaults, input.data)
105
- JsonifyFilter.document_data_to_json(data, out, prevent, depth)
105
+
106
+ out += JsonifyFilter.document_data_to_a(data, prevent, depth, max_depth)
107
+ "{#{out.join(",")}}"
106
108
  end
107
109
 
108
- def self.document_to_json(input, depth)
110
+ def self.document_to_json(input, depth, max_depth)
109
111
  prevent = %w(dir id relative_path url collection)
110
112
 
111
113
  out = [
112
- "\"path\": #{JsonifyFilter.to_json(input.relative_path, depth + 1)}",
113
- "\"relative_path\": #{JsonifyFilter.to_json(input.relative_path, depth + 1)}",
114
- "\"url\": #{JsonifyFilter.to_json(input.url, depth + 1)}",
114
+ "\"path\": #{JsonifyFilter.to_json(input.relative_path, depth, max_depth)}",
115
+ "\"url\": #{JsonifyFilter.to_json(input.url, depth, max_depth)}",
115
116
  ]
116
117
 
117
- unless input.collection.nil?
118
- out.push("\"collection\": #{JsonifyFilter.to_json(input.collection.label, depth + 1)}")
118
+ collection = input.collection
119
+ unless collection.nil?
120
+ collection_json = JsonifyFilter.to_json(collection.label, depth, max_depth)
121
+ out.push("\"collection\": #{collection_json}")
119
122
  end
120
123
 
121
- # id isn't defined in Jekyll 2.4.0
122
- out.push("\"id\": #{JsonifyFilter.to_json(input.id, depth + 1)}") if input.respond_to? :id
123
-
124
- JsonifyFilter.document_data_to_json(input.data, out, prevent, depth)
124
+ out += JsonifyFilter.document_data_to_a(input.data, prevent, depth, max_depth)
125
+ "{#{out.join(",")}}"
125
126
  end
126
127
 
127
- def self.array_to_json(input, depth, key_swaps = {})
128
+ def self.array_to_json(input, depth, max_depth, key_swaps = {})
128
129
  array = input.map do |value|
129
- JsonifyFilter.to_json(value, depth + 1, key_swaps)
130
+ JsonifyFilter.to_json(value, depth, max_depth, key_swaps)
130
131
  end
131
132
 
132
133
  "[#{array.join(",")}]"
133
134
  end
134
135
 
135
- def self.hash_to_json(input, depth, key_swaps = {})
136
- hash = input.map do |key, value|
137
- "#{(key_swaps[key] || key).to_json}: #{JsonifyFilter.to_json(value, depth + 1, key_swaps)}"
136
+ def self.hash_to_json(input, depth, max_depth, key_swaps = {})
137
+ out = input.map do |key, value|
138
+ string_key = (key_swaps[key] || key).to_s.to_json
139
+ "#{string_key}: #{JsonifyFilter.to_json(value, depth, max_depth, key_swaps)}"
138
140
  end
139
141
 
140
- "{#{hash.join(",")}}"
142
+ "{#{out.join(",")}}"
141
143
  end
142
144
 
143
145
  def self.config_to_select_data_json(input, depth)
@@ -155,7 +157,7 @@ module CloudCannonJekyll
155
157
  next if prevent.include? key
156
158
 
157
159
  prevent.push key
158
- "#{key.to_json}: #{JsonifyFilter.to_json(value, depth + 1)}"
160
+ "#{key.to_s.to_json}: #{JsonifyFilter.to_json(value, depth)}"
159
161
  end
160
162
 
161
163
  out.compact!
@@ -163,39 +165,37 @@ module CloudCannonJekyll
163
165
  "{#{out.join(",")}}" if out.any?
164
166
  end
165
167
 
166
- def self.to_json(input, depth, key_swaps = {})
167
- if depth > 8 || (depth > 2 && JsonifyFilter.document_type?(input))
168
+ def self.to_json(input, depth, max_depth = 9, key_swaps = {})
169
+ depth += 1
170
+
171
+ if depth > max_depth || (depth > 2 && JsonifyFilter.document_type?(input))
168
172
  '"MAXIMUM_DEPTH"'
169
173
  elsif JsonifyFilter.simple_type?(input)
170
174
  input.to_json
171
175
  elsif input.is_a?(Jekyll::StaticFile)
172
- JsonifyFilter.static_file_to_json(input, depth)
176
+ JsonifyFilter.static_file_to_json(input, depth, max_depth)
173
177
  elsif input.is_a?(Jekyll::Page)
174
- JsonifyFilter.page_to_json(input, depth)
178
+ JsonifyFilter.page_to_json(input, depth, max_depth)
175
179
  elsif Jekyll::VERSION.start_with?("2.") && input.is_a?(Jekyll::Post)
176
- JsonifyFilter.legacy_post_to_json(input, depth)
180
+ JsonifyFilter.legacy_post_to_json(input, depth, max_depth)
177
181
  elsif input.is_a?(Jekyll::Document)
178
- JsonifyFilter.document_to_json(input, depth)
182
+ JsonifyFilter.document_to_json(input, depth, max_depth)
179
183
  elsif input.is_a?(Array)
180
- JsonifyFilter.array_to_json(input, depth, key_swaps)
184
+ JsonifyFilter.array_to_json(input, depth, max_depth, key_swaps)
181
185
  elsif input.is_a?(Hash)
182
- JsonifyFilter.hash_to_json(input, depth, key_swaps)
186
+ JsonifyFilter.hash_to_json(input, depth, max_depth, key_swaps)
183
187
  else
184
188
  input.class.to_s.prepend("UNSUPPORTED:").to_json
185
189
  end
186
190
  end
187
191
 
188
192
  def cc_static_files_jsonify(input)
189
- out = []
190
- input.each do |page|
191
- next if page.extname != ".html" &&
192
- page.extname != ".htm" &&
193
- page.path != "/robots.txt" &&
194
- page.path != "/sitemap.xml"
195
-
196
- out.push(JsonifyFilter.to_json(page, 1))
193
+ out = input.map do |page|
194
+ JsonifyFilter.to_json(page, 1) if STATIC_EXTENSIONS.include?(page.extname)
197
195
  end
198
196
 
197
+ out.compact!
198
+
199
199
  "[#{out.join(",")}]"
200
200
  end
201
201
 
@@ -207,11 +207,11 @@ module CloudCannonJekyll
207
207
  end
208
208
  end
209
209
 
210
- def cc_jsonify(input, key_swaps_key = nil)
210
+ def cc_jsonify(input, key_swaps_key = nil, max_depth = 8)
211
211
  if CC_JSONIFY_KEY_SWAPS.key? key_swaps_key
212
- JsonifyFilter.to_json(input, 0, CC_JSONIFY_KEY_SWAPS[key_swaps_key])
212
+ JsonifyFilter.to_json(input, 0, max_depth, CC_JSONIFY_KEY_SWAPS[key_swaps_key])
213
213
  else
214
- JsonifyFilter.to_json(input, 0)
214
+ JsonifyFilter.to_json(input, 0, max_depth)
215
215
  end
216
216
  end
217
217
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CloudCannonJekyll
4
+ # Utility class to help generate files with no source file
4
5
  class PageWithoutAFile < Jekyll::Page
5
6
  def read_yaml(*)
6
7
  @data ||= {}
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll"
4
+
5
+ if !Jekyll::VERSION.start_with? "2."
6
+ require_relative "readers/data-reader"
7
+ else
8
+ require_relative "readers/old-data-reader"
9
+ end
10
+
11
+ module CloudCannonJekyll
12
+ # Wraps read functions into one class
13
+ class Reader
14
+ attr_reader :site
15
+
16
+ def initialize(site)
17
+ @site = site
18
+ end
19
+
20
+ def read_data(dir = "_data")
21
+ if Jekyll::VERSION.start_with? "2."
22
+ CloudCannonJekyll::OldDataReader.new(@site).read(dir)
23
+ else
24
+ CloudCannonJekyll::DataReader.new(@site).read(dir)
25
+ end
26
+ end
27
+
28
+ def read_drafts(dir = "")
29
+ if Jekyll::VERSION.start_with? "2."
30
+ @site.read_content(dir, "_drafts", Jekyll::Draft)
31
+ else
32
+ Jekyll::PostReader.new(@site).read_drafts(dir)
33
+ end
34
+ end
35
+
36
+ def read_posts(dir = "")
37
+ if Jekyll::VERSION.start_with? "2."
38
+ @site.read_content(dir, "_posts", Jekyll::Post)
39
+ else
40
+ Jekyll::PostReader.new(@site).read_posts(dir)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll"
4
+
5
+ module CloudCannonJekyll
6
+ # Reads data files and creates a collections-style hash representation
7
+ class DataReader < Jekyll::DataReader
8
+ # Determines how to read a data file.
9
+ # This is overridden return a hash instead of reading the file.
10
+ #
11
+ # Returns a hash with the path to the data file.
12
+ def read_data_file(path)
13
+ {
14
+ "path" => path,
15
+ }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll"
4
+
5
+ module CloudCannonJekyll
6
+ # Reads data files and creates a collections-style hash representation
7
+ # Aims to replicate the data reading logic in Jekyll 2.5
8
+ class OldDataReader
9
+ attr_reader :site
10
+
11
+ def initialize(site)
12
+ @site = site
13
+ @safe = site.safe
14
+ @content = {}
15
+ end
16
+
17
+ def read(dir)
18
+ base = Jekyll.sanitized_path(@site.source, dir)
19
+ read_data_to(base, @content)
20
+ @content
21
+ end
22
+
23
+ def read_data_to(dir, data)
24
+ return unless File.directory?(dir) && (!@safe || !File.symlink?(dir))
25
+
26
+ entries = Dir.chdir(dir) do
27
+ Dir["*.{yaml,yml,json,csv}"] + Dir["*"].select { |fn| File.directory?(fn) }
28
+ end
29
+
30
+ entries.each do |entry|
31
+ path = Jekyll.sanitized_path(dir, entry)
32
+ next if File.symlink?(path) && @safe
33
+
34
+ key = sanitize_filename(File.basename(entry, ".*"))
35
+ if File.directory?(path)
36
+ read_data_to(path, data[key] = {})
37
+ else
38
+ data[key] = read_data_file(path)
39
+ end
40
+ end
41
+ end
42
+
43
+ def read_data_file(path)
44
+ {
45
+ "path" => path,
46
+ }
47
+ end
48
+
49
+ def sanitize_filename(name)
50
+ name.gsub!(%r![^\w\s_-]+!, "")
51
+ name.gsub!(%r!(^|\b\s)\s+($|\s?\b)!, '\\1\\2')
52
+ name.gsub(%r!\s+!, "_")
53
+ end
54
+ end
55
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CloudCannonJekyll
4
- VERSION = "0.2.1"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudcannon-jekyll
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - CloudCannon
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-14 00:00:00.000000000 Z
11
+ date: 2020-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -107,7 +107,9 @@ executables: []
107
107
  extensions: []
108
108
  extra_rdoc_files: []
109
109
  files:
110
+ - ".github/workflows/stale.yml"
110
111
  - ".gitignore"
112
+ - ".reek.yml"
111
113
  - ".rspec"
112
114
  - ".rubocop.yml"
113
115
  - ".travis.yml"
@@ -128,6 +130,9 @@ files:
128
130
  - lib/cloudcannon-jekyll/generator.rb
129
131
  - lib/cloudcannon-jekyll/jsonify-filter.rb
130
132
  - lib/cloudcannon-jekyll/page-without-a-file.rb
133
+ - lib/cloudcannon-jekyll/reader.rb
134
+ - lib/cloudcannon-jekyll/readers/data-reader.rb
135
+ - lib/cloudcannon-jekyll/readers/old-data-reader.rb
131
136
  - lib/cloudcannon-jekyll/version.rb
132
137
  - script/ci-smoke-test
133
138
  - script/cibuild
@@ -137,7 +142,7 @@ homepage: https://github.com/cloudcannon/cloudcannon-jekyll
137
142
  licenses:
138
143
  - MIT
139
144
  metadata: {}
140
- post_install_message:
145
+ post_install_message:
141
146
  rdoc_options: []
142
147
  require_paths:
143
148
  - lib
@@ -153,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
158
  version: '0'
154
159
  requirements: []
155
160
  rubygems_version: 3.0.3
156
- signing_key:
161
+ signing_key:
157
162
  specification_version: 4
158
163
  summary: CloudCannon Jekyll integration
159
164
  test_files: []