jekyll-conrefifier 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 065d8f8c53f11bc9a9e5a8657fba8844228da1d1
4
- data.tar.gz: 5cd34e692c71e470491b88c5ed4629fff3ad0e6a
3
+ metadata.gz: db0d778b5e1e0ab68919ef23d08c1f1715304823
4
+ data.tar.gz: 28a2c9ccdf9de238f5ed558f1ae4d079b46699a6
5
5
  SHA512:
6
- metadata.gz: b67b2493701b2b63cd47bf639837dfe6435df9707b12062fd56ad39c9a9ec24b3c38e668520e070fc71742821e4d4429722cbe012f96080f3994d5dd1c74f221
7
- data.tar.gz: ef625b18abef60fae8b637c7c9b492dc813faba80c3b2bdf0d0413758b14a80e17b3636c3ed94b51bb0333d2670878b037f56cca5aefd968b0e49e1d838ad9c4
6
+ metadata.gz: ca4756a3697919d534c876cf379bfd7e025e261674884ebc18a37b672166684f7bb136ad9400b7c7bc598fe2dd02f5763b10b8f37df6e5aa652026adb1de8805
7
+ data.tar.gz: 7855026b72a8fff240054bc38842080b04d37bc9a9554247e02ffab0e88763051944fabc649b312c1ed83a37055dce25cc7dbe79f76c5bad12f68b2e5071ab9a
data/README.md CHANGED
@@ -114,3 +114,30 @@ data_file_variables:
114
114
  ```
115
115
 
116
116
  In this case, every data file has a `page.version` of `2.0`. However, only data files prefixed with `ent`, containing one or more word characters (`\w+`), and followed by an underscore (`_`), have a value of `2.1`.
117
+
118
+ ## Rendering filtered data files in layouts
119
+
120
+ As an addition to the above, a new tag, `data_render`, can be used to iterate over filtered data files.
121
+
122
+ You can call this filter by:
123
+
124
+ * Passing a data file name to `data_render`
125
+ * Passing any optional variables to this filter
126
+ * The YAML information will be temporarily stored within `site.data.data_render`
127
+ * You can iterate over `site.data.data_render` to walk along the data
128
+ * Multiple calls to `data_render` rewrite to `site.data.data_render`
129
+
130
+ Here's an example:
131
+
132
+ ``` liquid
133
+ {% data_render site.data.filtered_categories(:version => 2.0) %}
134
+
135
+ {% for category_hash in site.data.data_render %}
136
+ {% assign category_title = category_hash[0] %}
137
+ {% assign category_articles = category_hash[1] %}
138
+ {{ category_title }}
139
+ {{ category_articles }}
140
+ {% endfor %}
141
+ ```
142
+
143
+ Note that data files are read *once*, to improve performance. The variables passed in are evaluated for each call.
@@ -1,16 +1,3 @@
1
- class Hash
2
- def insert_before(key, kvpair)
3
- arr = to_a
4
- pos = arr.index(arr.assoc(key))
5
- if pos
6
- arr.insert(pos, kvpair)
7
- else
8
- arr << kvpair
9
- end
10
- replace Hash[arr]
11
- end
12
- end
13
-
14
1
  module Jekyll
15
2
  class Document
16
3
  alias_method :old_read, :read
@@ -32,7 +19,6 @@ module Jekyll
32
19
 
33
20
  class Site
34
21
  alias_method :old_read, :read
35
- alias_method :old_read_data_to, :read_data_to
36
22
 
37
23
  def in_source_dir(*paths)
38
24
  paths.reduce(source) do |base, path|
@@ -40,7 +26,7 @@ module Jekyll
40
26
  end
41
27
  end
42
28
 
43
- # allows us to filter data file content out on conditionals, eg. `{% if page.version == ... %}`
29
+ # allows us to filter data file contents via conditionals, eg. `{% if page.version == ... %}`
44
30
  def read_data_to(dir, data)
45
31
  return unless File.directory?(dir) && (!safe || !File.symlink?(dir))
46
32
 
@@ -48,8 +34,9 @@ module Jekyll
48
34
  Dir['*.{yaml,yml,json,csv}'] + Dir['*'].select { |fn| File.directory?(fn) }
49
35
  end
50
36
 
37
+ # all of this is copied from the Jekyll source, except...
51
38
  entries.each do |entry|
52
- path = in_source_dir(dir, entry)
39
+ path = self.in_source_dir(dir, entry)
53
40
  next if File.symlink?(path) && safe
54
41
 
55
42
  key = sanitize_filename(File.basename(entry, '.*'))
@@ -60,61 +47,107 @@ module Jekyll
60
47
  when '.csv'
61
48
  data[key] = CSV.read(path, :headers => true).map(&:to_hash)
62
49
  else
50
+ # if we hit upon if/unless conditionals, we'll need to pause and render them
63
51
  contents = File.read(path)
64
52
  if (matches = contents.scan /(\{% (?:if|unless).+? %\}.*?\{% end(?:if|unless) %\})/m)
65
- unless matches.empty?
66
- contents = apply_vars_to_datafile(contents, path, matches, config['data_file_variables'])
53
+ unless data_file_variables(path).nil?
54
+ contents = contents.gsub(/\{\{/, '[[')
55
+ contents = apply_vars_to_datafile(contents, matches, path)
67
56
  end
68
57
  end
69
58
  data[key] = SafeYAML.load(contents)
70
59
  end
71
60
  end
72
61
  end
62
+
63
+ # once we're all done, we need to iterate once more to parse out `{{ }}` blocks.
64
+ # two reasons for this: one, we need to collect every data file before attempting to
65
+ # parse these vars; two, the Liquid parse above obliterates these tags, so we
66
+ # first need to convert them into `[[ }}`, and *then* continue with the parse
67
+ data.each_pair do |datafile, value|
68
+ yaml_dump = YAML::dump value
69
+ yaml_dump = yaml_dump.gsub(/\[\[/, '{{')
70
+
71
+ data[datafile] = SafeYAML.load transform_liquid_variables(yaml_dump, datafile)
72
+ end
73
+ end
74
+
75
+ # apply the custom scoope plus the rest of the `site.data` information
76
+ def apply_vars_to_datafile(contents, matches, path)
77
+ return contents if matches.empty?
78
+
79
+ data_vars = path.nil? ? {} : data_file_variables(path)
80
+
81
+ config = { 'page' => data_vars }
82
+ config = { 'site' => { 'data' => self.data } }.merge(config)
83
+
84
+ matches.each do |match|
85
+ contents = contents.sub(match.first, Liquid::Template.parse(match.first).render(config))
86
+ end
87
+
88
+ contents
73
89
  end
74
90
 
75
- def apply_vars_to_datafile(contents, path, matches, data_file_variables)
76
- return contents if data_file_variables.nil?
91
+ # fetch the custom scope vars, as defined in _config.yml
92
+ def data_file_variables(path)
77
93
  data_vars = {}
78
- scopes = data_file_variables.select { |v| v['scope']['path'].empty? || Regexp.new(v['scope']['path']) =~ path }
94
+ scopes = config['data_file_variables'].select { |v| v['scope']['path'].empty? || Regexp.new(v['scope']['path']) =~ path }
79
95
  scopes.each do |scope|
80
96
  data_vars = data_vars.merge(scope['values'])
81
97
  end
82
- temp_config = self.config.merge({ 'page' => data_vars })
83
- matches.each do |match|
84
- contents = contents.sub(match.first, Liquid::Template.parse(match.first).render(temp_config))
85
- end
86
98
 
87
- contents
99
+ data_vars
88
100
  end
89
101
 
90
102
  # allow us to use any variable within Jekyll data files; for example:
91
103
  # - '{{ site.data.conrefs.product_name[site.audience] }} Glossary'
92
104
  # renders as "GitHub Glossary" for dotcom, but "GitHub Enterprise Glossary" for Enterprise
93
- def read
94
- keys_to_modify = {}
95
- old_read
96
- data.each_pair do |data_file, data_set|
97
- if data_set.is_a? Hash
98
- data_set.each_pair do |key, values|
99
- if key =~ /\{\{.+?\}\}/
100
- new_key = Liquid::Template.parse(key).render({ "site" => { "data" => data }.merge(config) })
101
- keys_to_modify[key] = new_key
102
- end
103
- if values.is_a? Array
104
- values.each_with_index do |value, i|
105
- if value =~ /\{\{.+?\}\}/
106
- value = Liquid::Template.parse(value).render({ "site" => { "data" => data }.merge(config) })
107
- data[data_file][key][i] = value
108
- end
109
- end
110
- end
111
- end
112
- keys_to_modify.each_pair do |old_key, new_key|
113
- data[data_file].insert_before(old_key, [new_key, data[data_file][old_key]])
114
- data[data_file].delete(old_key)
115
- end
116
- end
105
+ def transform_liquid_variables(contents, path=nil)
106
+ if (matches = contents.scan /(\{\{.+?\}\})/)
107
+ contents = apply_vars_to_datafile(contents, matches, path)
117
108
  end
109
+
110
+ contents
118
111
  end
119
112
  end
113
+
114
+ class DataRenderTag < Liquid::Tag
115
+ def initialize(tag_name, text, tokens)
116
+ super
117
+
118
+ keys = text.strip.split('.', 3)
119
+ keys.shift(2) # this is just site.data
120
+ paren_arg = keys.last.match(/\((.+?)\)/)
121
+ unless paren_arg.nil?
122
+ last_key = keys.last.sub(paren_arg[0], '')
123
+ keys.pop
124
+ keys << last_key
125
+ @hash_args = paren_arg[1].gsub(/[{}:]/,'').split(', ').map{|h| h1,h2 = h.split('=>'); {h1.strip => h2.strip}}.reduce(:merge)
126
+ end
127
+ @keys = keys
128
+ @id = keys.join('-')
129
+ end
130
+
131
+ def fetch_datafile(context, keys)
132
+ data_file = context.registers[:site].data["data_render_#{@id}"]
133
+ return data_file unless data_file.nil?
134
+
135
+ path = @id.sub('.', '/')
136
+ data_source = File.join(context.registers[:site].source, context.registers[:site].config['data_source'])
137
+ data_file = File.read("#{data_source}/#{path}.yml")
138
+ context.registers[:site].data["data_render_#{@id}"] = data_file
139
+ end
140
+
141
+ def render(context)
142
+ datafile = fetch_datafile(context, @keys)
143
+
144
+ config = { 'page' => @hash_args }
145
+ config = { 'site' => { "data" => context.registers[:site].data } }.merge(config)
146
+ versioned_yaml = SafeYAML.load(Liquid::Template.parse(datafile).render(config))
147
+ context.registers[:site].data['data_render'] = versioned_yaml
148
+ nil
149
+ end
150
+ end
151
+
152
+ Liquid::Template.register_tag('data_render', Jekyll::DataRenderTag)
120
153
  end
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module JekyllConrefifier
2
- VERSION = '0.2.1'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -10,7 +10,7 @@ describe("Conrefifier") do
10
10
  end
11
11
 
12
12
  it "writes the proper content for values after fetching info from a data file" do
13
- index_file = @dest.join("index.html")
13
+ index_file = @dest.join('index.html')
14
14
  expect(index_file).to exist
15
15
  index_contents = File.read(index_file)
16
16
  expect(index_contents).to include("GitHub Glossary")
@@ -34,7 +34,7 @@ describe("Conrefifier") do
34
34
  filtered_index_file = @dest.join("filtered_index.html")
35
35
  expect(filtered_index_file).to exist
36
36
  filtered_index_contents = File.read(filtered_index_file)
37
- expect(filtered_index_contents).to include("GitHub Glossary")
37
+ expect(filtered_index_contents).to include("GitHub Enterprise Glossary")
38
38
  expect(filtered_index_contents).to include("Fork A Repo")
39
39
  expect(filtered_index_contents).to include("Article v2.0")
40
40
  expect(filtered_index_contents).to include("Still show")
@@ -46,11 +46,22 @@ describe("Conrefifier") do
46
46
  enterprise_filtered_index = @dest.join("enterprise_filtered_index.html")
47
47
  expect(enterprise_filtered_index).to exist
48
48
  filtered_index_contents = File.read(enterprise_filtered_index)
49
- expect(filtered_index_contents).to include("GitHub Glossary")
49
+ expect(filtered_index_contents).to include("GitHub Enterprise Glossary")
50
50
  expect(filtered_index_contents).to include("Fork A Repo")
51
51
  expect(filtered_index_contents).to include("Article v2.1")
52
52
  expect(filtered_index_contents).to include("Still show")
53
53
  expect(filtered_index_contents).to_not include("Article v2.0")
54
54
  expect(filtered_index_contents).to_not include("Ignored")
55
55
  end
56
+
57
+ it 'uses the data_render tag to provide filtered data in a layout' do
58
+ filtering_layout = @dest.join("filtering_layout.html")
59
+ expect(filtering_layout).to exist
60
+ filtering_layout_contents = File.read(filtering_layout)
61
+ expect(filtering_layout_contents).to include('GitHub Enterprise Glossary')
62
+ expect(filtering_layout_contents.scan(/Bootcamp/).count).to eq(2)
63
+ expect(filtering_layout_contents.scan(/Article v2.1/).count).to eq(1)
64
+ expect(filtering_layout_contents.scan(/Article v2.0/).count).to eq(1)
65
+ expect(filtering_layout_contents.scan(/Ignored/).count).to eq(1)
66
+ end
56
67
  end
@@ -22,6 +22,11 @@ data_file_variables:
22
22
  path: ""
23
23
  values:
24
24
  version: "2.0"
25
+ -
26
+ scope:
27
+ path: "^categories"
28
+ values:
29
+ version: "dotcom"
25
30
  -
26
31
  scope:
27
32
  path: "ent\\w+_"
@@ -3,7 +3,7 @@ Bootcamp:
3
3
  - Create A Repo
4
4
  - Fork A Repo
5
5
  - Be Social
6
- - '{{ site.data.conrefs.product_name[site.audience] }} Glossary'
6
+ - '{{ site.data.conrefs.product_name[page.version] }} Glossary'
7
7
  - Good Resources for Learning Git and GitHub
8
8
 
9
9
  '{{ site.data.conrefs.product_type }}':
@@ -1,6 +1,7 @@
1
1
  product_name:
2
2
  dotcom: GitHub
3
- 2.0: GitHub Enterprise
3
+ '2.0': GitHub Enterprise
4
+ '2.1': GitHub Enterprise
4
5
  11.10.340: GitHub Enterprise
5
6
 
6
7
  product_type: 'Amazing'
@@ -3,7 +3,7 @@ Bootcamp:
3
3
  - Create A Repo
4
4
  - Fork A Repo
5
5
  - Be Social
6
- - '{{ site.data.conrefs.product_name[site.audience] }} Glossary'
6
+ - '{{ site.data.conrefs.product_name[page.version] }} Glossary'
7
7
  - Good Resources for Learning Git and GitHub
8
8
 
9
9
  Listing:
@@ -3,7 +3,7 @@ Bootcamp:
3
3
  - Create A Repo
4
4
  - Fork A Repo
5
5
  - Be Social
6
- - '{{ site.data.conrefs.product_name[site.audience] }} Glossary'
6
+ - '{{ site.data.conrefs.product_name[page.version] }} Glossary'
7
7
  - Good Resources for Learning Git and GitHub
8
8
 
9
9
  Listing:
@@ -0,0 +1,20 @@
1
+
2
+ {% data_render site.data.filtered_categories(:version => 2.0) %}
3
+
4
+ {% for category_hash in site.data.data_render %}
5
+ {% assign category_title = category_hash[0] %}
6
+ {% assign category_articles = category_hash[1] %}
7
+ {{ category_title }}
8
+ {{ category_articles }}
9
+ {% endfor %}
10
+
11
+ {{ content }}
12
+
13
+ {% data_render site.data.filtered_categories(:version => 2.1) %}
14
+
15
+ {% for category_hash in site.data.data_render %}
16
+ {% assign category_title = category_hash[0] %}
17
+ {% assign category_articles = category_hash[1] %}
18
+ {{ category_title }}
19
+ {{ category_articles }}
20
+ {% endfor %}
@@ -0,0 +1,5 @@
1
+ ---
2
+ layout: filtering_layout
3
+ ---
4
+
5
+ test
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-conrefifier
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
  - Garen J. Torikian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-02 00:00:00.000000000 Z
11
+ date: 2015-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -80,8 +80,10 @@ files:
80
80
  - spec/fixtures/_data/enterprise_filtered_categories.yml
81
81
  - spec/fixtures/_data/filtered_categories.yml
82
82
  - spec/fixtures/_layouts/article.html
83
+ - spec/fixtures/_layouts/filtering_layout.html
83
84
  - spec/fixtures/enterprise_filtered_index.html
84
85
  - spec/fixtures/filtered_index.html
86
+ - spec/fixtures/filtering_layout.html
85
87
  - spec/fixtures/index.html
86
88
  - spec/spec_helper.rb
87
89
  homepage: ''