jekyll-data 0.4.0 → 1.0.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
  SHA1:
3
- metadata.gz: fd5090a5a9fecc23edb990f2af43701cdf018fc2
4
- data.tar.gz: 5d9c0af30ca3738e65114eb9ac29514b8c7c2fc9
3
+ metadata.gz: b58db9039555a41b84b5c3d663b9bc689267f10a
4
+ data.tar.gz: 24db34fd2650c035b8a07a11ecf30cd47b152675
5
5
  SHA512:
6
- metadata.gz: 89371b0891b485f65b138a30b13af973b4397a058eeaf3130eaaf7a75ac4db733864d79bcf12a1637813be2b4872fe6d74395956225f9a2d7e72bd7d80f931e9
7
- data.tar.gz: 43d1d7e23a4ed9d40d6154f5100bf192865104259ebb52dc33ecd64c46151e83ad974df6837d5fce6066b72dfd252fd7efe2d7b8e2497e9507d37e084731859f
6
+ metadata.gz: 7eaf71e652e9ed84805277cc8135c428f90c2239c3dd9563a4504b42db949ef2e8520cb637b26715380b8118203e39088d16b4690398cbb8437e64fac784d1d1
7
+ data.tar.gz: cf41dc8dfc5ae0e63176d862c59b6316232a224ce29fe29c7e14094ac0eb5f9fd4137ac98168cdcabb1ca793ae4b4bc1d68667af45b8f9aff7792ee3c6f0901b
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2016 Ashwin Maroli
3
+ Copyright (c) 2016-2017 Ashwin Maroli & Contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -5,11 +5,13 @@
5
5
 
6
6
  [travis]: https://travis-ci.org/ashmaroli/jekyll-data
7
7
 
8
- Introducing a plugin that reads data files within **jekyll theme-gems** and adds the resulting hash to the site's internal data hash. If a **`_config.yml`** is present at the root of the theme-gem, it will be read as well.
8
+ Introducing a plugin that reads data files within **jekyll theme-gems** and adds the resulting hash to the site's internal data hash. If a **`_config.yml`** is present at the root of the theme-gem, it will be evaluated and the extracted hash data will be incorporated into the site's existing config hash.
9
+
9
10
 
10
11
  ## Installation
11
12
 
12
- Simply add the plugin to your site's Gemfile and config file like every other jekyll plugin gems..
13
+ Simply add the plugin to your site's Gemfile and config file like every other jekyll plugin gem:
14
+
13
15
  ```ruby
14
16
  # Gemfile
15
17
 
@@ -17,118 +19,102 @@ group :jekyll_plugins do
17
19
  gem "jekyll-data"
18
20
  end
19
21
  ```
20
- ```yaml
21
- # _config.yml
22
+ ..and run
22
23
 
23
- gems:
24
- - jekyll-data
24
+ bundle install
25
+
26
+
27
+ > **Note: If the plugin has been marked as a `runtime_dependency` by the theme-gem's author it will be installed automatically with the theme-gem. Yet, it is recommended that the plugin be added to `:jekyll_plugins` group in the Gemfile rather than the `gems:` array in the config file while building or serving the site to avoid 'overriding' the `gems:` array data that may have been read-in from the theme-gem.**
25
28
 
26
- ```
27
- ..and run
28
- ```
29
- bundle install
30
- ```
31
29
 
32
30
  ## Usage
33
31
 
34
32
  **Note:** *This plugin will only run in conjunction with a gem-based Jekyll-theme.*
35
33
 
36
- As long as the plugin gem has been installed properly, and is included in both the Gemfile & the config file, data-files supported by Jekyll and present in the `_data` directory at the root of your theme gem will be read. Their contents will be added to the site's internal data hash, provided, an identical data hash doesn't already exist at the site-source.
34
+ As long as the plugin-gem has been installed properly, and is included in the Gemfile's `:jekyll_plugins` group, data files supported by Jekyll and present in the `_data` directory at the root of your theme-gem will be read. Their contents will be added to the site's internal data hash, provided, an identical data hash doesn't already exist at the site-source.
35
+
36
+ If the theme-gem also includes a `_config.yml` at its root, then it will be read as well. The resulting config hash will be mixed into the site's existing config hash, filling in where the *keys* are not already defined. In other words, the config file at `source` will override corresponding identical keys in a `_config.yml` within the theme-gem which would in turn override corresponding `DEFAULTS` from Jekyll:
37
+
38
+ **DEFAULTS** < **_config.yml in theme-gem** < **_config.yml at source** < **Override configs via command-line**.
37
39
 
38
- If the theme-gem also includes a `_config.yml` at its root, then it will be read as well. The resulting config hash will be mixed into the site's existing config hash, filling in where the *keys* are not already defined. In other words, the site's config hash without this plugin, will override the conflicting config hash generated by this plugin from reading the included `_config.yml`
39
40
 
40
41
  ### Theme Configuration
41
42
 
42
- Jekyll themes (built prior to Jekyll 3.2) usually ship with configuration settings defined in the config file, which are then used within the theme's template files directly under the `site` namespace (e.g. `{{ site.myvariable }}`). This is not possible with theme gems as a config file and data-files within gems are not natively read (as of Jekyll 3.3), and hence require end-users to inspect a *demo* or *example* directory to source those files.
43
+ Jekyll themes (built prior to `Jekyll 3.2`) usually ship with configuration settings defined in the config file, which are then used within the theme's template files directly under the `site` namespace (e.g. `{{ site.myvariable }}`). This is not possible with theme-gems as a config file and data files within gems are not natively read (as of Jekyll 3.3), and hence require end-users to inspect a *demo* or *example* directory to source those files.
43
44
 
44
- This plugin provides a couple of solutions to that hurdle:
45
+ This plugin provides a solution to that hurdle:
45
46
 
46
- - settings via `_config.yml`
47
- ----------------------------
48
- This plugin reads the config file (at present only `_config.yml`) and uses the data to modify the site's config hash. This allows the gem to continue using `{{ site.myvariable }}` within its templates.
49
- - settings via `_data/[theme-name].*`
50
- --------------------------------------
51
- An alternate route is to have theme-specific settings defined as a hash, in a valid data file named the same as the theme-gem.
52
- The defined settings will be accessible via `{{ theme.myvariable }}`.
53
- e.g. if *minima* were to ship a YAML file with *minima*-specific settings (say, `post_excerpt: enabled`), then the gem would've a **_data/minima.yml** and this particular setting can be accessed in its templates via `{{ theme.post_excerpt }}` which is functionally equivalent to `{{ site.data.minima.post_excerpt }}`
54
- *Note: The `{{ theme.variable }}` is only available if the data-file is named the same as the theme-gem.*
47
+ JekyllData now reads the config file (at present only `_config.yml`) present within the theme-gem and uses the data to modify the site's config hash. This allows the theme-gem to continue using `{{ site.myvariable }}` within its templates and work out-of-the-box as intended, with minimal user intervention.
55
48
 
56
- ### Regular Data-files
49
+ **Note: the plugins required by the theme may be listed under the `gems:` array and will be automatically `required` by Jekyll while building/serving, provided that the user doesn't have a different `gems:` array in the config file at source. Hence it is recommended to add all other plugins ( including `jekyll-data` ) via the Gemfile's `:jekyll_plugins` group.**
57
50
 
58
- Regular data files that may be used to supplement theme templates (e.g. locales and translated UI text) can be named as desired. Either use a sub-directory to house related data-files or declare all of them as a mapped data block within a single file.
51
+ #### The `theme` namespace
52
+
53
+ From `v1.0`, JekyllData no longer supports reading theme configuration provided as a `[theme-name].***` file within the `_data` directory and instead the `theme` namespace points to a certain key in the bundled `_config.yml`.
54
+
55
+ For `{{ theme.variable }}` to work, the config file should nest all such key-value pairs under the `[theme-name]` key, as outlined in the example below for a theme-gem called `solitude`:
59
56
 
60
57
  ```yaml
61
- # <theme-gem>/_data/apparel.yml
62
-
63
- shirts:
64
- - color: white
65
- size: large
66
- image: s_w_lg.jpg
67
- - color: black
68
- size: large
69
- image: s_b_lg.jpg
70
-
71
- jeans:
72
- - color: khaki
73
- waist: 34
74
- image: j_kh_34.jpg
75
- - color: blue
76
- waist: 32
77
- image: j_bu_32.jpg
78
- ```
79
- is the same as:
80
- ```yaml
81
- # <theme-gem>/_data/apparel/shirts.yml
82
-
83
- - color: white
84
- size: large
85
- image: s_w_lg.jpg
86
- - color: black
87
- size: large
88
- image: s_b_lg.jpg
89
- ```
90
- ```yaml
91
- # <theme-gem>/_data/apparel/jeans.yml
92
-
93
- - color: khaki
94
- waist: 34
95
- image: j_kh_34.jpg
96
- - color: blue
97
- waist: 32
98
- image: j_bu_32.jpg
58
+ # <solitude-0.1.0>/_config.yml
59
+
60
+ # the settings below have been used in this theme's templates via the `theme`
61
+ # namespace. e.g. `{{ theme.recent_posts.style }}` instead of using the more
62
+ # verbose `{{ site.solitude.recent_posts.style }}` though both are functionally
63
+ # the same.
64
+ #
65
+ solitude:
66
+ sidebar : true # enter 'false' to enable horizontal navbar instead.
67
+ theme_variant : Charcoal # choose from 'Ocean', 'Grass', 'Charcoal'
68
+ recent_posts :
69
+ style : list # choose from 'list' and 'grid'.
70
+ quantity : '4' # either '4' or '6'
71
+
99
72
  ```
100
73
 
101
- ### User-overrides
102
74
 
103
- To override directives shipped with a theme gem, simply have an identical hash at the site-source.
104
- e.g.
75
+ ### Data files
76
+
77
+ Data files may be used to supplement theme templates (e.g. locales and translated UI text) and can be named as desired.
78
+ - Organize related small data files in sub-directories. (or)
79
+ - Declare all related data as mapped data blocks within a single file.
80
+
81
+ To illustrate with an example, consider a `locales.yml` that has mappings for `en:`, `fr:`, `it:`.
82
+
105
83
  ```yaml
106
- # <site_source_dir>/_data/navigation.yml
107
-
108
- mainmenu:
109
- - title: Home
110
- url: /
111
- - title: Kitchen Diaries
112
- url: /kitchen-diaries/
113
- - title: Tips & Tricks
114
- url: /tips-n-tricks/
115
- - title: Health Facts
116
- url: /health/
117
- - title: About Me
118
- url: /about/
119
- ```
120
- would have overridden the following:
121
- ```yaml
122
- # <theme-gem>/_data/navigation/mainmenu.yml
123
-
124
- - title: Link Item 1
125
- url: /link-one/
126
- - title: Link Item 2
127
- url: /link-two/
128
- - title: Link Item 3
129
- url: /link-three/
84
+ # <theme-gem>/_data/locales.yml
85
+
86
+ en:
87
+ previous : previous
88
+ next : next
89
+
90
+ fr:
91
+ previous : précédent
92
+ next : prochain
93
+
94
+ it:
95
+ previous : precedente
96
+ next : seguente
130
97
  ```
131
98
 
99
+ the Hash from above would be identical to one had the gem been shipped with a `_data/locales` directory containing individual files for each language data.
100
+
101
+
102
+ ### Overriding Data Files
103
+
104
+ To override data shipped with a theme-gem, simply have an identical hash at the site-source.
105
+
106
+ Irrespective of whether the theme-gem ships with consolidated data files of related entities, or sub-directories containing individual files, the data can be overridden with a single file or with multiple files.
107
+
108
+ For example, if a theme-gem contains the above sample `locales.yml`, then to override the `fr:` key-data simply have either of the following:
109
+ - a **`_data/locales/fr.yml`** with identical subkey(s).
110
+ - a **`_data/locales.yml`** with **`fr:`** with identical subkey(s).
111
+
112
+ --
113
+ > **Note**
114
+ - having an **empty** `_data/locales.yml` at `source` directory will override the **entire `["data"]["locales"]` payload** from the theme-gem as **`false`**.
115
+ - having an **empty** `_data/locales/fr.yml` at `source` directory will override the **enire `["data"]["locales"]["fr"]` payload** from the theme-gem as **`false`**
116
+
117
+
132
118
  ## Contributing
133
119
 
134
120
  Bug reports and pull requests are welcome at the [GitHub Repo](https://github.com/ashmaroli/jekyll-data). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
@@ -1,26 +1,29 @@
1
1
  require "jekyll"
2
2
  require "jekyll-data/version"
3
3
 
4
- # Plugin inclusions
5
- require_relative "jekyll/theme_reader"
6
- require_relative "jekyll/readers/theme_data_reader"
7
- require_relative "jekyll/drops/themed_site_drop"
4
+ module JekyllData
5
+ autoload :Reader, "jekyll-data/reader"
6
+ autoload :ThemedSiteDrop, "jekyll-data/themed_site_drop"
7
+ autoload :ThemeDataReader, "jekyll-data/theme_data_reader"
8
+ autoload :ThemeConfiguration, "jekyll-data/theme_configuration"
9
+ end
8
10
 
9
11
  # Monkey-patches
10
- require_relative "jekyll/theme"
11
- require_relative "jekyll/drops/unified_payload_drop"
12
+ require_relative "jekyll/build_options"
13
+ require_relative "jekyll/data_path"
14
+ require_relative "jekyll/theme_drop"
12
15
 
13
- # replace Jekyll::Reader with a subclass Jekyll::ThemeReader only if the site
14
- # uses a gem-based theme else have this plugin disabled.
16
+ # ----------------------------------------------------------------------------
17
+ # Modify the current site instance if it uses a gem-based theme else have this
18
+ # plugin disabled.
15
19
  #
16
- # Additionally, append to site's config hash with optional config hash from the
17
- # theme gem by filling in keys not already defined.
18
- Jekyll::Hooks.register :site, :after_init do |site|
20
+ # if a '_config.yml' is present at the root of theme-gem, it is evaluated and
21
+ # the extracted hash data is incorprated into the site's config hash.
22
+ # ----------------------------------------------------------------------------
23
+ Jekyll::Hooks.register :site, :after_reset do |site|
19
24
  if site.theme
20
- site.config = Jekyll::Utils.deep_merge_hashes(
21
- Jekyll::ThemeReader.new(site).read_theme_config, site.config
22
- )
23
- site.reader = Jekyll::ThemeReader.new(site)
25
+ file = site.in_theme_dir("_config.yml")
26
+ JekyllData::ThemeConfiguration.reconfigure(site) if File.exist?(file)
24
27
  else
25
28
  Jekyll.logger.abort_with(
26
29
  "JekyllData:",
@@ -29,3 +32,18 @@ Jekyll::Hooks.register :site, :after_init do |site|
29
32
  )
30
33
  end
31
34
  end
35
+
36
+ # ---------------------------------------------------------------------------
37
+ # Replace Jekyll::Reader with a subclass JekyllData::Reader only if the
38
+ # site uses a gem-based theme.
39
+ #
40
+ # If a _config.yml exists at the root of the theme-gem, output its path.
41
+ # Placed here inorder to avoid outputting the path after every regeneration.
42
+ # ---------------------------------------------------------------------------
43
+ Jekyll::Hooks.register :site, :after_init do |site|
44
+ if site.theme
45
+ file = site.in_theme_dir("_config.yml")
46
+ Jekyll.logger.info "Theme Config file:", file if File.exist?(file)
47
+ site.reader = JekyllData::Reader.new(site)
48
+ end
49
+ end
@@ -0,0 +1,223 @@
1
+ # encoding: UTF-8
2
+ require "csv"
3
+
4
+ module JekyllData
5
+ class Reader < Jekyll::Reader
6
+ def initialize(site)
7
+ @site = site
8
+ @theme = site.theme
9
+ @theme_data_files = Dir[File.join(site.theme.root,
10
+ site.config["data_dir"], "**", "*.{yaml,yml,json,csv}")]
11
+ end
12
+
13
+ # Read data files within theme-gem.
14
+ #
15
+ # Returns nothing.
16
+ def read
17
+ super
18
+ read_theme_data
19
+ end
20
+
21
+ # Read data files within a theme gem and add them to internal data
22
+ #
23
+ # Returns a hash appended with new data
24
+ def read_theme_data
25
+ if @theme.data_path
26
+ #
27
+ # show contents of "<theme>/_data/" dir being read while degugging.
28
+ inspect_theme_data
29
+ theme_data = ThemeDataReader.new(site).read(site.config["data_dir"])
30
+ @site.data = Jekyll::Utils.deep_merge_hashes(theme_data, @site.data)
31
+ #
32
+ # show contents of merged site.data hash while debugging with
33
+ # additional --show-data switch.
34
+ inspect_merged_hash if site.config["show-data"] && site.config["verbose"]
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ # Private:
41
+ # (only while debugging)
42
+ #
43
+ # Print a list of data file(s) within the theme-gem
44
+ def inspect_theme_data
45
+ print_clear_line
46
+ Jekyll.logger.debug "Reading:", "Theme Data Files..."
47
+ @theme_data_files.each { |file| Jekyll.logger.debug "", file }
48
+ print_clear_line
49
+ Jekyll.logger.debug "Merging:", "Theme Data Hash..."
50
+
51
+ unless site.config["show-data"] && site.config["verbose"]
52
+ Jekyll.logger.debug "", "use --show-data with --verbose to output " \
53
+ "merged Data Hash.".cyan
54
+ print_clear_line
55
+ end
56
+ end
57
+
58
+ # Private:
59
+ # (only while debugging)
60
+ #
61
+ # Print contents of the merged data hash
62
+ def inspect_merged_hash
63
+ Jekyll.logger.debug "Inspecting:", "Site Data >>"
64
+
65
+ # the width of generated logger[message]
66
+ @width = 50
67
+ @dashes = "-" * @width
68
+
69
+ inspect_hash @site.data
70
+ print_clear_line
71
+ end
72
+
73
+ # --------------------------------------------------------------------
74
+ # Private helper methods to inspect data hash and output contents
75
+ # to logger at level debugging.
76
+ # --------------------------------------------------------------------
77
+
78
+ # Dissect the (merged) site.data hash and print its contents
79
+ #
80
+ # - Print the key string(s)
81
+ # - Individually analyse the hash[key] values and extract contents
82
+ # to output.
83
+ def inspect_hash(hash)
84
+ hash.each do |key, value|
85
+ print_key key
86
+ if value.is_a? Hash
87
+ inspect_inner_hash value
88
+ elsif value.is_a? Array
89
+ extract_hashes_and_print value
90
+ else
91
+ print_string value.to_s
92
+ end
93
+ end
94
+ end
95
+
96
+ # Analyse deeper hashes and extract contents to output
97
+ def inspect_inner_hash(hash)
98
+ hash.each do |key, value|
99
+ if value.is_a? Array
100
+ print_label key
101
+ extract_hashes_and_print value
102
+ elsif value.is_a? Hash
103
+ print_subkey_and_value key, value
104
+ else
105
+ print_hash key, value
106
+ end
107
+ end
108
+ end
109
+
110
+ # If an array of strings, print. Otherwise assume as an
111
+ # array of hashes (sequences) that needs further analysis.
112
+ def extract_hashes_and_print(array)
113
+ array.each do |entry|
114
+ if entry.is_a? String
115
+ print_list entry
116
+ else
117
+ inspect_inner_hash entry
118
+ end
119
+ end
120
+ end
121
+
122
+ #
123
+
124
+ # --------------------------------------------------------------------
125
+ # Private methods for formatting log messages while debugging
126
+ # --------------------------------------------------------------------
127
+
128
+ # Splits a string longer than the value of '@width' into smaller
129
+ # strings and prints each line as a logger[message]
130
+ #
131
+ # string - the long string
132
+ #
133
+ # label - optional text to designate the printed lines.
134
+ def print_long_string(string, label = "")
135
+ strings = string.scan(%r!(.{1,#{@width}})(\s+|\W|\Z)!).map { |s| s.join.strip }
136
+ first_line = strings.first.cyan
137
+
138
+ label.empty? ? print_value(first_line) : print(label, first_line)
139
+ strings[1..-1].each { |s| print_value s.cyan }
140
+ end
141
+
142
+ # Prints key as logger[topic] and value as [message]
143
+ def print_hash(key, value)
144
+ if value.length > @width
145
+ print_long_string value, "#{key}:"
146
+ else
147
+ print "#{key}:", value.cyan
148
+ end
149
+ end
150
+
151
+ def print_list(item)
152
+ if item.length > @width
153
+ print_long_string item, "-"
154
+ else
155
+ print "-", item.cyan
156
+ end
157
+ end
158
+
159
+ def print_string(str)
160
+ if str.length > @width
161
+ print_long_string str
162
+ else
163
+ print_value str.inspect
164
+ end
165
+ end
166
+
167
+ # Prints the site.data[key] in color
168
+ def print_key(key)
169
+ print_clear_line
170
+ print "Data Key:", " #{key} ".center(@width, "=")
171
+ print_clear_line
172
+ end
173
+
174
+ # Prints label, keys and values of mappings
175
+ def print_subkey_and_value(key, value)
176
+ print_label key
177
+ value.each do |subkey, val|
178
+ if val.is_a? Hash
179
+ print_inner_subkey subkey
180
+ inspect_inner_hash val
181
+ elsif val.is_a? Array
182
+ print_inner_subkey subkey
183
+ extract_hashes_and_print val
184
+ elsif val.is_a? String
185
+ print_hash subkey, val
186
+ end
187
+ end
188
+ end
189
+
190
+ # Print only logger[message], [topic] = nil
191
+ def print_value(value)
192
+ if value.is_a? Array
193
+ extract_hashes_and_print value
194
+ else
195
+ print "", value
196
+ end
197
+ end
198
+
199
+ # Print only logger[topic] appended with a colon
200
+ def print_label(key)
201
+ print_value " #{key} ".center(@width, "-")
202
+ end
203
+
204
+ def print_inner_subkey(key)
205
+ print "#{key}:", @dashes
206
+ end
207
+
208
+ def print_dashes
209
+ print "", @dashes
210
+ end
211
+
212
+ def print_clear_line
213
+ print ""
214
+ end
215
+
216
+ # Redefine Jekyll Loggers to have the [topic] indented by 30.
217
+ # (rjust by just 29 to accomodate the additional whitespace added
218
+ # by Jekyll)
219
+ def print(topic, message = "")
220
+ Jekyll.logger.debug topic.rjust(29), message
221
+ end
222
+ end
223
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: UTF-8
2
+
3
+ module JekyllData
4
+ class ThemeConfiguration < Jekyll::Configuration
5
+ class << self
6
+ # Public: Establish a new site.config hash by reading an optional config
7
+ # file within the theme-gem and appending the resulting hash to
8
+ # existing site.config filling in keys not already defined.
9
+ #
10
+ # site: current Jekyll::Site instance.
11
+ #
12
+ # Returns a config Hash to be used by an 'after_reset' hook.
13
+ def reconfigure(site)
14
+ default_hash = Jekyll::Configuration::DEFAULTS
15
+ theme_config = ThemeConfiguration.new(site).read_theme_config
16
+
17
+ # Merge with existing site.config and strip any remaining defaults
18
+ config = Jekyll::Utils.deep_merge_hashes(
19
+ theme_config, site.config
20
+ ).reject { |key, value| value == default_hash[key] }
21
+
22
+ # Merge DEFAULTS < _config.yml in theme-gem < config file(s) from source
23
+ # and redefine site.config
24
+ site.config = Jekyll::Configuration.from(
25
+ Jekyll::Utils.deep_merge_hashes(theme_config, config)
26
+ )
27
+ end
28
+ end
29
+
30
+ #
31
+
32
+ def initialize(site)
33
+ @site = site
34
+ end
35
+
36
+ # Public: Read the '_config.yml' file within the theme-gem.
37
+ # Additionally validates that the extracted config data and the
38
+ # the 'value' of '<site.theme.name> key', when present, is a Hash.
39
+ #
40
+ # Returns a Configuration Hash
41
+ def read_theme_config
42
+ file = @site.in_theme_dir("_config.yml")
43
+ theme_name = @site.theme.name
44
+
45
+ config = safe_load_file(file)
46
+
47
+ check_config_is_hash!(config, file)
48
+ validate_config_hash config[theme_name] unless config[theme_name].nil?
49
+
50
+ config
51
+ end
52
+
53
+ private
54
+
55
+ # Validate the <site.theme.name> key's value to be accessed via the `theme`
56
+ # namespace.
57
+ def validate_config_hash(value)
58
+ unless value.is_a? Hash
59
+ Jekyll.logger.abort_with "JekyllData:", "Theme Configuration should be a " \
60
+ "Hash of key:value pairs or mappings. But got #{value.class} instead."
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,10 +1,10 @@
1
- module Jekyll
2
- class ThemeDataReader < DataReader
1
+ module JekyllData
2
+ class ThemeDataReader < Jekyll::DataReader
3
3
  attr_reader :site, :content
4
4
  def initialize(site)
5
5
  @site = site
6
6
  @content = {}
7
- @entry_filter = EntryFilter.new(site)
7
+ @entry_filter = Jekyll::EntryFilter.new(site)
8
8
  end
9
9
 
10
10
  def read(dir)
@@ -0,0 +1,15 @@
1
+ # encoding: UTF-8
2
+
3
+ module JekyllData
4
+ class ThemedSiteDrop < Jekyll::Drops::SiteDrop
5
+ extend Forwardable
6
+
7
+ mutable false
8
+
9
+ def_delegator :@obj, :site_data, :data
10
+ def_delegators :@obj, :theme
11
+
12
+ private
13
+ def_delegator :@obj, :config, :fallback_data
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module JekyllData
2
- VERSION = "0.4.0".freeze
2
+ VERSION = "1.0.0".freeze
3
3
  end
@@ -0,0 +1,17 @@
1
+ module Jekyll
2
+ class Command
3
+ class << self
4
+ #
5
+ # patch original method to inject a '--show-data' switch to display
6
+ # merged data hash
7
+ #
8
+ alias_method :original_build_options, :add_build_options
9
+
10
+ def add_build_options(c)
11
+ original_build_options(c)
12
+ c.option "show-data", "--show-data",
13
+ "Print merged site-data hash when used with --verbose."
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ module Jekyll
2
+ class Theme
3
+ def data_path
4
+ path_for "_data".freeze
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: UTF-8
2
+
3
+ module Jekyll
4
+ module Drops
5
+ class UnifiedPayloadDrop < Drop
6
+ def site
7
+ @site_drop ||= JekyllData::ThemedSiteDrop.new(@obj)
8
+ end
9
+
10
+ # Register a namespace to easily call subkeys under <theme-name> key
11
+ # in the _config.yml within a theme-gem via its bundled templates.
12
+ # e.g. with this drop, theme-specific variables usually called like
13
+ # {{ site.minima.date_format }} can be shortened to simply
14
+ # {{ theme.date_format }}.
15
+ def theme
16
+ @theme_drop ||= site[site.theme.name]
17
+ end
18
+ end
19
+ end
20
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-data
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ashwin Maroli
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-14 00:00:00.000000000 Z
11
+ date: 2017-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -30,28 +30,34 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.12'
33
+ version: '1.14'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 1.14.3
34
37
  type: :development
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
41
  - - "~>"
39
42
  - !ruby/object:Gem::Version
40
- version: '1.12'
43
+ version: '1.14'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.14.3
41
47
  - !ruby/object:Gem::Dependency
42
- name: rake
48
+ name: cucumber
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
51
  - - "~>"
46
52
  - !ruby/object:Gem::Version
47
- version: '10.0'
53
+ version: '2.1'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
58
  - - "~>"
53
59
  - !ruby/object:Gem::Version
54
- version: '10.0'
60
+ version: '2.1'
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: minitest
57
63
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +72,34 @@ dependencies:
66
72
  - - "~>"
67
73
  - !ruby/object:Gem::Version
68
74
  version: '5.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rake
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '10.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '10.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rubocop
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: 0.47.1
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: 0.47.1
69
103
  description:
70
104
  email:
71
105
  - ashmaroli@gmail.com
@@ -76,12 +110,14 @@ files:
76
110
  - LICENSE.txt
77
111
  - README.md
78
112
  - lib/jekyll-data.rb
113
+ - lib/jekyll-data/reader.rb
114
+ - lib/jekyll-data/theme_configuration.rb
115
+ - lib/jekyll-data/theme_data_reader.rb
116
+ - lib/jekyll-data/themed_site_drop.rb
79
117
  - lib/jekyll-data/version.rb
80
- - lib/jekyll/drops/themed_site_drop.rb
81
- - lib/jekyll/drops/unified_payload_drop.rb
82
- - lib/jekyll/readers/theme_data_reader.rb
83
- - lib/jekyll/theme.rb
84
- - lib/jekyll/theme_reader.rb
118
+ - lib/jekyll/build_options.rb
119
+ - lib/jekyll/data_path.rb
120
+ - lib/jekyll/theme_drop.rb
85
121
  homepage: https://github.com/ashmaroli/jekyll-data
86
122
  licenses:
87
123
  - MIT
@@ -103,8 +139,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
139
  version: '0'
104
140
  requirements: []
105
141
  rubyforge_project:
106
- rubygems_version: 2.6.8
142
+ rubygems_version: 2.6.10
107
143
  signing_key:
108
144
  specification_version: 4
109
- summary: A plugin to read '_config.yml' and data files in Jekyll Theme Gems
145
+ summary: A plugin to read '_config.yml' and data files within Jekyll theme-gems
110
146
  test_files: []
@@ -1,17 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- module Jekyll
4
- module Drops
5
- class ThemedSiteDrop < SiteDrop
6
- extend Forwardable
7
-
8
- mutable false
9
-
10
- def_delegator :@obj, :site_data, :data
11
- def_delegators :@obj, :theme
12
-
13
- private
14
- def_delegator :@obj, :config, :fallback_data
15
- end
16
- end
17
- end
@@ -1,30 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- module Jekyll
4
- module Drops
5
- class UnifiedPayloadDrop < Drop
6
- mutable true
7
-
8
- attr_accessor :page, :layout, :content, :paginator
9
- attr_accessor :highlighter_prefix, :highlighter_suffix
10
-
11
- def jekyll
12
- JekyllDrop.global
13
- end
14
-
15
- def site
16
- @site_drop ||= ThemedSiteDrop.new(@obj)
17
- end
18
-
19
- def theme
20
- theme_name = site.theme.name
21
- site.data[theme_name]
22
- end
23
-
24
- private
25
- def fallback_data
26
- @fallback_data ||= {}
27
- end
28
- end
29
- end
30
- end
@@ -1,66 +0,0 @@
1
- module Jekyll
2
- class Theme
3
- extend Forwardable
4
- attr_reader :name
5
- def_delegator :gemspec, :version, :version
6
-
7
- def initialize(name)
8
- @name = name.downcase.strip
9
- configure_sass
10
- end
11
-
12
- def root
13
- # Must use File.realpath to resolve symlinks created by rbenv
14
- # Otherwise, Jekyll.sanitized path with prepend the unresolved root
15
- @root ||= File.realpath(gemspec.full_gem_path)
16
- rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP
17
- nil
18
- end
19
-
20
- def includes_path
21
- path_for "_includes".freeze
22
- end
23
-
24
- def layouts_path
25
- path_for "_layouts".freeze
26
- end
27
-
28
- def sass_path
29
- path_for "_sass".freeze
30
- end
31
-
32
- def data_path
33
- path_for "_data".freeze
34
- end
35
-
36
- def assets_path
37
- path_for "assets".freeze
38
- end
39
-
40
- def configure_sass
41
- return unless sass_path
42
- require "sass"
43
- Sass.load_paths << sass_path
44
- end
45
-
46
- private
47
-
48
- def path_for(folder)
49
- path = realpath_for(folder)
50
- path if path && File.directory?(path)
51
- end
52
-
53
- def realpath_for(folder)
54
- File.realpath(Jekyll.sanitized_path(root, folder.to_s))
55
- rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP
56
- nil
57
- end
58
-
59
- def gemspec
60
- @gemspec ||= Gem::Specification.find_by_name(name)
61
- rescue Gem::LoadError
62
- raise Jekyll::Errors::MissingDependencyException,
63
- "The #{name} theme could not be found."
64
- end
65
- end
66
- end
@@ -1,209 +0,0 @@
1
- # encoding: UTF-8
2
- require "csv"
3
-
4
- module Jekyll
5
- class ThemeReader < Reader
6
- def initialize(site)
7
- @site = site
8
- @theme_data_files = Dir[File.join(@site.theme.root,
9
- site.config["data_dir"], "**", "*.{yaml,yml,json,csv}")]
10
- end
11
-
12
- # Read data files within theme-gem.
13
- #
14
- # Returns nothing.
15
- def read
16
- super
17
- read_theme_data
18
- end
19
-
20
- # Read data files within a theme gem and add them to internal data
21
- #
22
- # Returns a hash appended with new data
23
- def read_theme_data
24
- if site.theme.data_path
25
- #
26
- # show contents of "<theme>/_data/" dir being read while degugging.
27
- # Additionally validate if a data file with the same name as the
28
- # theme (= theme config or theme config-override) is a Hash.
29
- inspect_theme_data
30
- theme_data = ThemeDataReader.new(site).read(site.config["data_dir"])
31
- @site.data = Utils.deep_merge_hashes(theme_data, @site.data)
32
- #
33
- # check if the merged hash is suitable for generating the site.
34
- # Also show contents of merged site.data hash while debugging.
35
- inspect_merged_hash
36
- end
37
- end
38
-
39
- # Read the '_config.yml' file if present within the theme gem and
40
- # return a data hash otherwise return a hash of Jekyll Defaults.
41
- #
42
- # Returns a hash
43
- def read_theme_config
44
- config = @site.in_theme_dir("_config.yml")
45
- if File.exist?(config)
46
- Configuration.new.read_config_file(config)
47
- else
48
- Configuration::DEFAULTS
49
- end
50
- end
51
-
52
- private
53
-
54
- # Private:
55
- # Print messages only while debugging.
56
- #
57
- # Inspect the theme configuration file (data file with the same name
58
- # as the theme) and print a success message, if valid.
59
- def inspect_theme_data
60
- print_clear_line
61
- print "Reading:", "Theme Data Files..."
62
- @theme_data_files.each do |file|
63
- if File.basename(file, ".*") == @site.theme.name
64
- inspect_theme_config file
65
- print_value file.green
66
- else
67
- print_value file
68
- end
69
- end
70
- print_clear_line
71
- print "Merging:", "Theme Data Hash..."
72
- end
73
-
74
- # Private:
75
- # Print contents of the merged data hash while debugging
76
- def inspect_merged_hash
77
- print "Inspecting:", "Site Data >>"
78
- inspect_hash @site.data
79
- print_clear_line
80
- end
81
-
82
- # Private helper methods to inspect data hash and output contents
83
- # to logger at level debugging.
84
-
85
- # Dissect the (merged) site.data hash and print its contents
86
- #
87
- # - Print the key string(s) and if matches theme name, validate its
88
- # value as well.
89
- # - Individually analyse the hash[key] values and extract contents
90
- # to output.
91
- def inspect_hash(hash)
92
- hash.each do |key, value|
93
- print_key key
94
- if key == @site.theme.name
95
- validate_config_hash value
96
- end
97
-
98
- if value.is_a? Hash
99
- inspect_inner_hash value
100
- elsif value.is_a? Array
101
- print_label key
102
- extract_hashes_and_print value
103
- else
104
- print_value "'#{value}'"
105
- end
106
- end
107
- end
108
-
109
- # Analyse deeper hashes and extract contents to output
110
- def inspect_inner_hash(hash)
111
- hash.each do |key, value|
112
- if value.is_a? Array
113
- print_label key
114
- extract_hashes_and_print value
115
- print_clear_line
116
- elsif value.is_a? Hash
117
- print_subkey_and_value key, value
118
- else
119
- print_hash key, value
120
- end
121
- end
122
- end
123
-
124
- # If an array of strings, print. Otherwise assume as an
125
- # array of hashes (sequences) that needs further analysis.
126
- def extract_hashes_and_print(array)
127
- array.each do |entry|
128
- if entry.is_a? String
129
- print "-", entry
130
- else
131
- inspect_inner_hash entry
132
- end
133
- end
134
- end
135
-
136
- # analyse the theme config file and validate it as Hash
137
- def inspect_theme_config(path)
138
- config = ThemeDataReader.new(site).read_data_file(path)
139
- validate_config_hash config
140
- end
141
-
142
- def validate_config_hash(value)
143
- if value == false
144
- abort_with_msg "Cannot define or override Theme Configuration " \
145
- "with an empty file!"
146
- end
147
- unless value.is_a? Hash
148
- abort_with_msg "Theme Config or its override should be a Hash of " \
149
- "key:value pairs or mappings. But got #{value.class} instead."
150
- end
151
- end
152
-
153
- # Private methods for formatting log messages while debugging and a
154
- # method to issue conflict alert and abort site.process
155
-
156
- # Prints key as logger[topic] and value as [message]
157
- def print_hash(key, value)
158
- print "#{key}:", value
159
- end
160
-
161
- # Prints the site.data[key] in color
162
- def print_key(key)
163
- @dashes = "------------------------"
164
- print_value @dashes.to_s.cyan
165
- print "Data Key:", key.to_s.cyan
166
- print_value @dashes.to_s.cyan
167
- end
168
-
169
- # Prints label, keys and values of mappings
170
- def print_subkey_and_value(key, value)
171
- print_label key
172
- value.each do |subkey, val|
173
- print_hash subkey, val
174
- end
175
- print_dashes
176
- end
177
-
178
- # Print only logger[message], [topic] = nil
179
- def print_value(value)
180
- if value.is_a? Array
181
- extract_hashes_and_print value
182
- else
183
- print "", value
184
- end
185
- end
186
-
187
- # Print only logger[topic] appended with a colon
188
- def print_label(key)
189
- print "#{key}:"
190
- end
191
-
192
- def print_dashes
193
- print "", @dashes
194
- end
195
-
196
- def print_clear_line
197
- print ""
198
- end
199
-
200
- # Redefine Jekyll Loggers
201
- def print(arg1, arg2 = "")
202
- Jekyll.logger.debug arg1, arg2
203
- end
204
-
205
- def abort_with_msg(msg)
206
- Jekyll.logger.abort_with "JekyllData:", msg
207
- end
208
- end
209
- end