jekyll_pages_api 0.1.2 → 0.1.3

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: 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