jekyll_pages_api 0.1.2 → 0.1.3
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 +4 -4
- data/.gitignore +1 -0
- data/README.md +20 -1
- data/Rakefile +5 -0
- data/lib/jekyll_pages_api/generator.rb +9 -5
- data/lib/jekyll_pages_api/page.rb +23 -8
- data/lib/jekyll_pages_api/version.rb +1 -1
- data/spec/integration_spec.rb +16 -7
- data/spec/page_spec.rb +92 -9
- data/spec/site/_posts/2015-01-26-welcome-to-jekyll.markdown +0 -1
- data/spec/site/_posts/2015-05-25-do-not-render-result.markdown +14 -0
- data/spec/support/create_page.rb +50 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a53015b9d831067e9881896ba4337a0afe277b31
|
4
|
+
data.tar.gz: fc905c1a196698fc249a52f306111952ec9eac32
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67ffc1e1e878040b166ba902879a11f994d91beb11a9f13fbb882277bd76ce996c617c06567da2c0edee8a6b313724d483fe92a8b97feee72ff5260798e3c401
|
7
|
+
data.tar.gz: 02d73adbe830e228176cf8dd89e14b096f51a0334fdd9a8951cc0fa4a4c39d4b8346225658a9e9201634288022cd9873525551c3d8397e3d875ed60e2ba1986b
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](https://gitter.im/18F/jekyll_pages_api?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
4
4
|
|
5
|
-
Jekyll Pages API is a [Jekyll Plugin](http://jekyllrb.com/docs/plugins/) gem that generates a JSON file with data for all the Pages in your Site. [Jekyll](http://jekyllrb.com), if you're not familiar, is a static website generator written in Ruby.
|
5
|
+
Jekyll Pages API is a [Jekyll Plugin](http://jekyllrb.com/docs/plugins/) gem that generates a JSON file with data for all the Pages, Posts, Documents (i.e. "collections") and StaticFiles in your Site. [Jekyll](http://jekyllrb.com), if you're not familiar, is a static website generator written in Ruby.
|
6
6
|
|
7
7
|
## Usage
|
8
8
|
|
@@ -40,6 +40,25 @@ You can then see the generated JSON file at http://localhost:4000/api/v1/pages.j
|
|
40
40
|
|
41
41
|
This endpoint will be re-generated any time your site is rebuilt.
|
42
42
|
|
43
|
+
## Developing
|
44
|
+
|
45
|
+
* Run `bundle` to install any necessary gems.
|
46
|
+
* Run `bundle exec rake -T` to get a list of build commands and descriptions.
|
47
|
+
* Run `bundle exec rake spec` to run the tests.
|
48
|
+
* Run `bundle exec rake build` to ensure the entire gem can build.
|
49
|
+
* Commit an update to bump the version number of
|
50
|
+
`lib/jekyll_pages_api/version.rb` before running `bundle exec rake release`.
|
51
|
+
|
52
|
+
While developing this gem, add this to the Gemfile of any project using the
|
53
|
+
gem to try out your changes (presuming the project's working directory is a
|
54
|
+
sibling of the gem's working directory):
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
group :jekyll_plugins do
|
58
|
+
gem 'jekyll_pages_api', :path => '../jekyll_pages_api'
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
43
62
|
## See also
|
44
63
|
|
45
64
|
Additional means of turning your site content into data:
|
data/Rakefile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require_relative 'page'
|
2
2
|
require_relative 'page_without_a_file'
|
3
3
|
|
4
|
+
require 'json'
|
5
|
+
|
4
6
|
module JekyllPagesApi
|
5
7
|
class Generator
|
6
8
|
attr_reader :site
|
@@ -10,7 +12,12 @@ module JekyllPagesApi
|
|
10
12
|
end
|
11
13
|
|
12
14
|
def pages
|
13
|
-
|
15
|
+
result = []
|
16
|
+
self.site.each_site_file do |site_file|
|
17
|
+
page = Page.new(site_file, @site)
|
18
|
+
result << page if page.html?
|
19
|
+
end
|
20
|
+
result
|
14
21
|
end
|
15
22
|
|
16
23
|
def pages_data
|
@@ -30,10 +37,7 @@ module JekyllPagesApi
|
|
30
37
|
def page
|
31
38
|
# based on https://github.com/jekyll/jekyll-sitemap/blob/v0.7.0/lib/jekyll-sitemap.rb#L51-L54
|
32
39
|
page = PageWithoutAFile.new(self.site, File.dirname(__FILE__), self.dest_dir, 'pages.json')
|
33
|
-
page.
|
34
|
-
page.data['layout'] = nil
|
35
|
-
page.render(Hash.new, self.site.site_payload)
|
36
|
-
|
40
|
+
page.output = self.data.to_json
|
37
41
|
page
|
38
42
|
end
|
39
43
|
|
@@ -3,14 +3,19 @@ require_relative 'filters'
|
|
3
3
|
module JekyllPagesApi
|
4
4
|
# wrapper for a Jekyll::Page
|
5
5
|
class Page
|
6
|
-
|
6
|
+
HTML_EXTS = %w(.html .md .markdown .textile).to_set
|
7
|
+
attr_reader :page, :site
|
7
8
|
|
8
|
-
|
9
|
+
# Jekyll::StaticFile doesn't expose a `site` accessor, so we require an
|
10
|
+
# explicit `site` argument here.
|
11
|
+
def initialize(page, site)
|
9
12
|
@page = page
|
13
|
+
@site = site
|
10
14
|
end
|
11
15
|
|
12
16
|
def html?
|
13
|
-
|
17
|
+
path = self.page.path
|
18
|
+
path.end_with?('/') || HTML_EXTS.include?(File.extname(path))
|
14
19
|
end
|
15
20
|
|
16
21
|
def filterer
|
@@ -18,23 +23,33 @@ module JekyllPagesApi
|
|
18
23
|
end
|
19
24
|
|
20
25
|
def title
|
21
|
-
self.
|
26
|
+
title = self.page.data['title'] if self.page.respond_to?(:data)
|
27
|
+
title ||= self.page.title if self.page.respond_to?(:title)
|
28
|
+
self.filterer.decode_html(title || '')
|
22
29
|
end
|
23
30
|
|
24
31
|
def base_url
|
25
|
-
self.
|
32
|
+
self.site.baseurl
|
33
|
+
end
|
34
|
+
|
35
|
+
def rel_path
|
36
|
+
path = self.page.url if self.page.respond_to?(:url)
|
37
|
+
path ||= self.page.relative_path if self.page.respond_to?(:relative_path)
|
38
|
+
path
|
26
39
|
end
|
27
40
|
|
28
41
|
def url
|
29
|
-
[self.base_url,
|
42
|
+
[self.base_url, rel_path].join
|
30
43
|
end
|
31
44
|
|
32
45
|
def body_text
|
33
|
-
self.
|
46
|
+
output = self.page.content if self.page.respond_to?(:content)
|
47
|
+
output ||= File.read(self.page.path)
|
48
|
+
self.filterer.text_only(output)
|
34
49
|
end
|
35
50
|
|
36
51
|
def tags
|
37
|
-
self.page.data['tags'] || []
|
52
|
+
(self.page.data['tags'] if self.page.respond_to?(:data)) || []
|
38
53
|
end
|
39
54
|
|
40
55
|
def to_json
|
data/spec/integration_spec.rb
CHANGED
@@ -12,9 +12,12 @@ describe "integration" do
|
|
12
12
|
JSON.parse(contents)
|
13
13
|
end
|
14
14
|
|
15
|
+
def pages_data
|
16
|
+
@json ||= read_json(JSON_PATH)
|
17
|
+
end
|
18
|
+
|
15
19
|
def entries_data
|
16
|
-
|
17
|
-
json['entries']
|
20
|
+
pages_data['entries']
|
18
21
|
end
|
19
22
|
|
20
23
|
def page_data(url)
|
@@ -45,12 +48,16 @@ describe "integration" do
|
|
45
48
|
# not sure why this discrepancy exists...
|
46
49
|
if Jekyll::VERSION.start_with?('3.')
|
47
50
|
expect(urls).to eq(%w(
|
51
|
+
/jekyll/update/2015/01/26/welcome-to-jekyll.html
|
52
|
+
/jekyll/update/2015/05/25/do-not-render-result.html
|
48
53
|
/about/
|
49
54
|
/
|
50
55
|
/unicode.html
|
51
56
|
))
|
52
57
|
else
|
53
58
|
expect(urls).to eq(%w(
|
59
|
+
/jekyll/update/2015/01/26/welcome-to-jekyll.html
|
60
|
+
/jekyll/update/2015/05/25/do-not-render-result.html
|
54
61
|
/about/
|
55
62
|
/index.html
|
56
63
|
/unicode.html
|
@@ -58,11 +65,13 @@ describe "integration" do
|
|
58
65
|
end
|
59
66
|
end
|
60
67
|
|
61
|
-
it "
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
68
|
+
it "does not render the pages corpus using Liquid" do
|
69
|
+
# The content of each page in the pages corpus should be Liquid-rendered,
|
70
|
+
# but rendering the pages.json corpus may cause pages that contain code
|
71
|
+
# examples of Liquid tags may produce invalid JSON.
|
72
|
+
page = page_data '/jekyll/update/2015/05/25/do-not-render-result.html'
|
73
|
+
expect(page['body']).to_not include('{% raw %}')
|
74
|
+
expect(page['body']).to include('{% author chrisc %}')
|
66
75
|
end
|
67
76
|
|
68
77
|
it "removes HTML tags" do
|
data/spec/page_spec.rb
CHANGED
@@ -1,19 +1,102 @@
|
|
1
|
+
require_relative 'support/create_page'
|
2
|
+
|
3
|
+
BASEURL = Jekyll::Configuration::DEFAULTS['baseurl']
|
4
|
+
|
1
5
|
describe JekyllPagesApi::Page do
|
6
|
+
include_context "create page"
|
7
|
+
|
2
8
|
describe '#url' do
|
3
9
|
it "returns the path" do
|
4
|
-
|
5
|
-
jekyll_page = instance_double(Jekyll::Page, site: site, url: '/foo/')
|
6
|
-
page = JekyllPagesApi::Page.new(jekyll_page)
|
7
|
-
|
8
|
-
expect(page.url).to eq('/foo/')
|
10
|
+
expect(create_page(BASEURL, '/foo/').url).to eq('/foo/')
|
9
11
|
end
|
10
12
|
|
11
13
|
it "prepends the baseurl" do
|
12
|
-
|
13
|
-
|
14
|
-
|
14
|
+
expect(create_page('/base', '/foo/').url).to eq('/base/foo/')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "uses the relative path for StaticFiles" do
|
18
|
+
page = create_static_file('/base', '/foo.html')
|
19
|
+
expect(page.url).to eq('/base/foo.html')
|
20
|
+
end
|
21
|
+
|
22
|
+
it "uses the relative path for Documents" do
|
23
|
+
expect(create_document('/base', '/foo.html').url).to eq('/base/foo.html')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#html?' do
|
28
|
+
it "returns true for paths ending in slash" do
|
29
|
+
expect(create_page(BASEURL, '/foo/').html?).to eq(true)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns true for paths ending in .html" do
|
33
|
+
expect(create_page(BASEURL, '/foo/index.html').html?).to eq(true)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns true for paths ending in .md" do
|
37
|
+
expect(create_page(BASEURL, '/foo/index.html').html?).to eq(true)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns false otherwise" do
|
41
|
+
expect(create_page(BASEURL, '/foo/index.json').html?).to eq(false)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#title' do
|
46
|
+
it "returns the title field from the page's front matter if present" do
|
47
|
+
page = create_page(BASEURL, '/foo/', data:{'title' => 'Foo'})
|
48
|
+
expect(page.title).to eq('Foo')
|
49
|
+
end
|
50
|
+
|
51
|
+
it "returns the title field from the post's front matter if present" do
|
52
|
+
page = create_post(BASEURL, '/foo/', data:{'title' => 'Foo'})
|
53
|
+
expect(page.title).to eq('Foo')
|
54
|
+
end
|
55
|
+
|
56
|
+
it "returns the title method from post method if not in front matter" do
|
57
|
+
page = create_post(BASEURL, '/foo/', title: 'Foo')
|
58
|
+
expect(page.title).to eq('Foo')
|
59
|
+
end
|
60
|
+
|
61
|
+
it "returns the empty string for StaticFiles" do
|
62
|
+
expect(create_static_file(BASEURL, '/foo/').title).to eq('')
|
63
|
+
end
|
64
|
+
|
65
|
+
it "returns the title field from the document's front matter if present" do
|
66
|
+
page = create_document(BASEURL, '/foo/', data:{'title' => 'Foo'})
|
67
|
+
expect(page.title).to eq('Foo')
|
68
|
+
end
|
69
|
+
|
70
|
+
it "returns the empty string for Documents if not in front matter" do
|
71
|
+
expect(create_document(BASEURL, '/foo/').title).to eq('')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#tags" do
|
76
|
+
it "returns tags if present in the front matter" do
|
77
|
+
page = create_page(BASEURL, '/foo/',
|
78
|
+
data:{'tags' => ['foo', 'bar', 'baz']})
|
79
|
+
expect(page.tags).to eq(['foo', 'bar', 'baz'])
|
80
|
+
end
|
81
|
+
|
82
|
+
it "returns the empty list if not present in the front matter" do
|
83
|
+
expect(create_page(BASEURL, '/foo/').tags).to eq([])
|
84
|
+
end
|
85
|
+
|
86
|
+
it "returns the empty list if the page does not contain front matter" do
|
87
|
+
expect(create_static_file(BASEURL, '/foo/').tags).to eq([])
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "#body_text" do
|
92
|
+
it "returns the content if present" do
|
93
|
+
page = create_page(BASEURL, '/foo/', content: "foo bar baz")
|
94
|
+
expect(page.body_text).to eq("foo bar baz")
|
95
|
+
end
|
15
96
|
|
16
|
-
|
97
|
+
it "returns the file content of StaticFiles" do
|
98
|
+
page = create_static_file(BASEURL, '/foo.html', content: "foo bar baz")
|
99
|
+
expect(page.body_text).to eq("foo bar baz")
|
17
100
|
end
|
18
101
|
end
|
19
102
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
---
|
2
2
|
layout: post
|
3
3
|
title: "Welcome to Jekyll!"
|
4
|
-
date: 2015-01-26 02:53:40
|
5
4
|
categories: jekyll update
|
6
5
|
---
|
7
6
|
You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
---
|
2
|
+
layout: post
|
3
|
+
title: "Do Not Render the Result"
|
4
|
+
categories: jekyll update
|
5
|
+
---
|
6
|
+
Sometimes posts will contain examples of Liquid code, like this from the [18F blog post about Jekyll and webhooks](https://18f.gsa.gov/2014/11/17/taking-control-of-our-website-with-jekyll-and-webhooks/):
|
7
|
+
|
8
|
+
```html
|
9
|
+
<p class="authors">
|
10
|
+
by {% raw %}{% author chrisc %}{% endraw %}, {%raw %}{% author mhz %}{% endraw %}, and {% raw %}{% author nick %}{% endraw %}
|
11
|
+
</p>
|
12
|
+
```
|
13
|
+
|
14
|
+
If we render the `pages.json` corpus, the Liquid tags will generate text that is not properly JSON-escaped, rendering the corpus as invalid JSON.
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
|
3
|
+
RSpec.shared_context "create page" do
|
4
|
+
before { @tmp_dir = nil }
|
5
|
+
after { FileUtils.remove_entry(@tmp_dir) if @tmp_dir }
|
6
|
+
|
7
|
+
def create_page(baseurl, page_url, data: nil, content: nil)
|
8
|
+
site = instance_double(Jekyll::Site, baseurl: baseurl)
|
9
|
+
jekyll_page = instance_double(Jekyll::Page, site: site, url: page_url,
|
10
|
+
path: page_url)
|
11
|
+
allow(jekyll_page).to receive(:data).and_return(data) unless data.nil?
|
12
|
+
unless content.nil?
|
13
|
+
allow(jekyll_page).to receive(:content).and_return(content)
|
14
|
+
end
|
15
|
+
JekyllPagesApi::Page.new(jekyll_page, site)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_static_file(baseurl, relative_path, content: nil)
|
19
|
+
site = instance_double(Jekyll::Site, baseurl: baseurl)
|
20
|
+
if content.nil?
|
21
|
+
jekyll_static_file = instance_double(Jekyll::StaticFile,
|
22
|
+
relative_path: relative_path)
|
23
|
+
else content.nil?
|
24
|
+
@tmp_root = Dir.mktmpdir
|
25
|
+
@static_file_path = File.join(@tmp_root, relative_path)
|
26
|
+
FileUtils.mkdir_p(File.dirname(@static_file_path))
|
27
|
+
File.open(@static_file_path, 'w') {|f| f << content}
|
28
|
+
|
29
|
+
jekyll_static_file = Jekyll::StaticFile.new(site, @tmp_root,
|
30
|
+
File.dirname(relative_path), File.basename(relative_path))
|
31
|
+
end
|
32
|
+
JekyllPagesApi::Page.new(jekyll_static_file, site)
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_post(baseurl, page_url, data: nil, title: nil)
|
36
|
+
site = instance_double(Jekyll::Site, baseurl: baseurl)
|
37
|
+
jekyll_post = instance_double(Jekyll::Post, site: site, url: page_url,
|
38
|
+
path: page_url)
|
39
|
+
allow(jekyll_post).to receive(:data).and_return(data) unless data.nil?
|
40
|
+
allow(jekyll_post).to receive(:title).and_return(title) unless title.nil?
|
41
|
+
JekyllPagesApi::Page.new(jekyll_post, site)
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_document(baseurl, relative_path, data: nil)
|
45
|
+
site = instance_double(Jekyll::Site, baseurl: baseurl)
|
46
|
+
jekyll_doc = instance_double(Jekyll::Document, relative_path: relative_path)
|
47
|
+
allow(jekyll_doc).to receive(:data).and_return(data) unless data.nil?
|
48
|
+
JekyllPagesApi::Page.new(jekyll_doc, site)
|
49
|
+
end
|
50
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll_pages_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aidan Feldman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: htmlentities
|
@@ -124,6 +124,7 @@ files:
|
|
124
124
|
- spec/site/_layouts/page.html
|
125
125
|
- spec/site/_layouts/post.html
|
126
126
|
- spec/site/_posts/2015-01-26-welcome-to-jekyll.markdown
|
127
|
+
- spec/site/_posts/2015-05-25-do-not-render-result.markdown
|
127
128
|
- spec/site/_sass/_base.scss
|
128
129
|
- spec/site/_sass/_layout.scss
|
129
130
|
- spec/site/_sass/_syntax-highlighting.scss
|
@@ -133,6 +134,7 @@ files:
|
|
133
134
|
- spec/site/index.html
|
134
135
|
- spec/site/unicode.html
|
135
136
|
- spec/spec_helper.rb
|
137
|
+
- spec/support/create_page.rb
|
136
138
|
- spec/support/shell.rb
|
137
139
|
homepage: https://github.com/18F/jekyll_pages_api
|
138
140
|
licenses:
|
@@ -173,6 +175,7 @@ test_files:
|
|
173
175
|
- spec/site/_layouts/page.html
|
174
176
|
- spec/site/_layouts/post.html
|
175
177
|
- spec/site/_posts/2015-01-26-welcome-to-jekyll.markdown
|
178
|
+
- spec/site/_posts/2015-05-25-do-not-render-result.markdown
|
176
179
|
- spec/site/_sass/_base.scss
|
177
180
|
- spec/site/_sass/_layout.scss
|
178
181
|
- spec/site/_sass/_syntax-highlighting.scss
|
@@ -182,4 +185,5 @@ test_files:
|
|
182
185
|
- spec/site/index.html
|
183
186
|
- spec/site/unicode.html
|
184
187
|
- spec/spec_helper.rb
|
188
|
+
- spec/support/create_page.rb
|
185
189
|
- spec/support/shell.rb
|