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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2c5221638d1bc7cff97071c86b554dc3ad450120
4
- data.tar.gz: c2d34d4ff057760141282c13d4690e32b3e7fe93
3
+ metadata.gz: a53015b9d831067e9881896ba4337a0afe277b31
4
+ data.tar.gz: fc905c1a196698fc249a52f306111952ec9eac32
5
5
  SHA512:
6
- metadata.gz: 4dbd890b286d8610d5d52c47a3202ad827dd80f7cc3d806c649d0eaa77e2033a1910ab7dbb588ce53505e03985a67033ff492cd2747d7fdd4146c9121b1f9ed5
7
- data.tar.gz: 2e7e3370cf5faa3dfdb00248c12b45871ed161fb2650deb7dae6322beba56e67d7569fec22bfa495a3d0f2399864066d2ba1be85e65856708b78ae0ce0ecccc4
6
+ metadata.gz: 67ffc1e1e878040b166ba902879a11f994d91beb11a9f13fbb882277bd76ce996c617c06567da2c0edee8a6b313724d483fe92a8b97feee72ff5260798e3c401
7
+ data.tar.gz: 02d73adbe830e228176cf8dd89e14b096f51a0334fdd9a8951cc0fa4a4c39d4b8346225658a9e9201634288022cd9873525551c3d8397e3d875ed60e2ba1986b
data/.gitignore CHANGED
@@ -13,3 +13,4 @@
13
13
  *.o
14
14
  *.a
15
15
  mkmf.log
16
+ .*.swp
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Join the chat at https://gitter.im/18F/jekyll_pages_api](https://badges.gitter.im/Join%20Chat.svg)](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,2 +1,7 @@
1
1
  require "bundler/gem_tasks"
2
2
 
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ rescue LoadError
7
+ end
@@ -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
- self.site.pages.map{|page| Page.new(page) }.select(&:html?)
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.content = self.data.to_json
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
- attr_reader :page
6
+ HTML_EXTS = %w(.html .md .markdown .textile).to_set
7
+ attr_reader :page, :site
7
8
 
8
- def initialize(page)
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
- %w(.html .md).include?(self.page.ext)
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.filterer.decode_html(self.page.data['title'] || '')
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.page.site.baseurl
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, self.page.url].join
42
+ [self.base_url, rel_path].join
30
43
  end
31
44
 
32
45
  def body_text
33
- self.filterer.text_only(self.page.content)
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
@@ -1,3 +1,3 @@
1
1
  module JekyllPagesApi
2
- VERSION = '0.1.2'
2
+ VERSION = '0.1.3'
3
3
  end
@@ -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
- json = read_json(JSON_PATH)
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 "removes liquid tags" do
62
- entries_data.each do |page|
63
- expect(page['body']).to_not include('{%')
64
- expect(page['body']).to_not include('{{')
65
- end
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
@@ -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
- site = instance_double(Jekyll::Site, baseurl: Jekyll::Configuration::DEFAULTS['baseurl'])
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
- site = instance_double(Jekyll::Site, baseurl: '/base')
13
- jekyll_page = instance_double(Jekyll::Page, site: site, url: '/foo/')
14
- page = JekyllPagesApi::Page.new(jekyll_page)
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
- expect(page.url).to eq('/base/foo/')
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.2
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-04-28 00:00:00.000000000 Z
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