bridgetown-feed 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/History.markdown +4 -0
- data/README.md +12 -9
- data/bridgetown-feed.gemspec +1 -1
- data/lib/bridgetown-feed/feed.xml +11 -10
- data/lib/bridgetown-feed/meta-tag.rb +5 -1
- data/lib/bridgetown-feed/version.rb +1 -1
- metadata +3 -46
- data/script/bootstrap +0 -3
- data/script/cibuild +0 -7
- data/script/fmt +0 -10
- data/script/release +0 -7
- data/script/test +0 -4
- data/spec/bridgetown-feed_spec.rb +0 -525
- data/spec/fixtures/bridgetown.config.yml +0 -9
- data/spec/fixtures/src/_collection/2018-01-01-collection-doc.md +0 -4
- data/spec/fixtures/src/_collection/2018-01-02-collection-category-doc.md +0 -5
- data/spec/fixtures/src/_data/authors.yml +0 -5
- data/spec/fixtures/src/_layouts/some_default.html +0 -11
- data/spec/fixtures/src/_posts/2013-12-12-dec-the-second.md +0 -7
- data/spec/fixtures/src/_posts/2014-03-02-march-the-second.md +0 -6
- data/spec/fixtures/src/_posts/2014-03-04-march-the-fourth.md +0 -9
- data/spec/fixtures/src/_posts/2015-01-12-a-draft.md +0 -5
- data/spec/fixtures/src/_posts/2015-01-18-jekyll-last-modified-at.md +0 -5
- data/spec/fixtures/src/_posts/2015-02-12-strip-newlines.md +0 -6
- data/spec/fixtures/src/_posts/2015-05-12-liquid.md +0 -7
- data/spec/fixtures/src/_posts/2015-05-12-pre.html +0 -8
- data/spec/fixtures/src/_posts/2015-05-18-author-detail.md +0 -9
- data/spec/fixtures/src/_posts/2015-08-08-stuck-in-the-middle.html +0 -6
- data/spec/fixtures/src/_posts/2016-04-25-author-reference.md +0 -6
- data/spec/fixtures/src/feed.xslt.xml +0 -0
- data/spec/spec_helper.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7fe130eac4236b925c8364669e52f46c504f055602d51170ded6d6287383228
|
4
|
+
data.tar.gz: 4701b9854efc0b3036c1fd3c21b7c552a0388dff5198a2a7ee39eb2c7552eefd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03e546ff0ae418cb229c43beb122ff306d1f1fdce9d72fc37a41cba08b37978a0a4dd5762feabc14150de9444b373a05b70973939eb31995f6162e5939c40787
|
7
|
+
data.tar.gz: e66a34cbcfac1180d27a2553e954b486d7b1dc3dbbe046698e9864a0815a148d8f3dce28b5f6238b9efdd0b7eaeb274c2da30d7acf126aecb28f937ff6cd526b
|
data/Gemfile
CHANGED
data/History.markdown
CHANGED
data/README.md
CHANGED
@@ -20,15 +20,22 @@ gem 'bridgetown-feed', group: "bridgetown_plugins"
|
|
20
20
|
|
21
21
|
The plugin will automatically generate an Atom feed at `/feed.xml`.
|
22
22
|
|
23
|
+
### Meta tags
|
24
|
+
|
25
|
+
The plugin exposes a helper tag to expose the appropriate meta tags to support automated discovery of your feed. Simply place `{% feed_meta %}` someplace in your template's `<head>` section, to output the necessary metadata.
|
26
|
+
|
23
27
|
### Optional configuration options
|
24
28
|
|
25
|
-
The plugin will automatically use any of the following
|
29
|
+
The plugin will automatically use any of the following metadata variables if they are present in your site's `_data/site_metadata.yml` file.
|
26
30
|
|
27
31
|
* `title` or `name` - The title of the site, e.g., "My awesome site"
|
28
32
|
* `description` - A longer description of what your site is about, e.g., "Where I blog about Bridgetown and other awesome things"
|
29
|
-
* `url` - The URL to your site, e.g., `https://example.com`. If none is provided, the plugin will try to use `site.github.url`.
|
30
33
|
* `author` - Global author information (see below)
|
31
34
|
|
35
|
+
In addition it looks for these `bridgetown.config.yml` settings:
|
36
|
+
|
37
|
+
* `url` - The URL to your site, e.g., `https://example.com`.
|
38
|
+
|
32
39
|
### Already have a feed path?
|
33
40
|
|
34
41
|
Do you already have an existing feed someplace other than `/feed.xml`, but are on a host like GitHub Pages that doesn't support machine-friendly redirects? If you simply swap out `bridgetown-feed` for your existing template, your existing subscribers won't continue to get updates. Instead, you can specify a non-default path via your site's config.
|
@@ -55,7 +62,7 @@ Additionally, the plugin will use the following values, if present in a post's Y
|
|
55
62
|
|
56
63
|
* `image` - URL of an image that is representative of the post (can also be passed as `image.path`)
|
57
64
|
|
58
|
-
* `author` - The author of the post, e.g., "Dr. Bridgetown". If none is given, feed readers will look to the feed author as defined in `
|
65
|
+
* `author` - The author of the post, e.g., "Dr. Bridgetown". If none is given, feed readers will look to the feed author as defined in `_data/site_metadata.yml`. Like the feed author, this can also be an object or a reference to an author in `_data/authors.yml` (see below).
|
59
66
|
|
60
67
|
### Author information
|
61
68
|
|
@@ -70,7 +77,7 @@ There are several ways to convey author-specific information. Author information
|
|
70
77
|
twitter: MarinaDiamandis
|
71
78
|
```
|
72
79
|
|
73
|
-
2. An `author` object, in the site's `
|
80
|
+
2. An `author` object, in the site's `_data/site_metadata.yml`, e.g.:
|
74
81
|
|
75
82
|
```yml
|
76
83
|
author:
|
@@ -105,16 +112,12 @@ There are several ways to convey author-specific information. Author information
|
|
105
112
|
author: marina
|
106
113
|
```
|
107
114
|
|
108
|
-
5. An author in the site's `
|
115
|
+
5. An author in the site's `_data/site_metadata.yml`, e.g.:
|
109
116
|
|
110
117
|
```yml
|
111
118
|
author: marina
|
112
119
|
```
|
113
120
|
|
114
|
-
### Meta tags
|
115
|
-
|
116
|
-
The plugin exposes a helper tag to expose the appropriate meta tags to support automated discovery of your feed. Simply place `{% feed_meta %}` someplace in your template's `<head>` section, to output the necessary metadata.
|
117
|
-
|
118
121
|
### SmartyPants
|
119
122
|
|
120
123
|
The plugin uses [Bridgetown's `smartify` filter](https://bridgetownrb.com/docs/templates/) for processing the site title and post titles. This will translate plain ASCII punctuation into "smart" typographic punctuation. This will not render or strip any Markdown you may be using in a title.
|
data/bridgetown-feed.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.homepage = "https://github.com/bridgetownrb/bridgetown-feed"
|
12
12
|
spec.license = "MIT"
|
13
13
|
|
14
|
-
spec.files = `git ls-files -z`.split("\x0")
|
14
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r!^(test|script|spec|features)/!) }
|
15
15
|
spec.test_files = spec.files.grep(%r!^spec/!)
|
16
16
|
spec.require_paths = ["lib"]
|
17
17
|
|
@@ -9,7 +9,8 @@
|
|
9
9
|
<updated>{{ site.time | date_to_xmlschema }}</updated>
|
10
10
|
<id>{{ page.url | absolute_url | xml_escape }}</id>
|
11
11
|
|
12
|
-
{
|
12
|
+
<!-- {{ site.metadata | jsonify }} -->
|
13
|
+
{% assign title = site.metadata.title | default: site.metadata.name %}
|
13
14
|
{% if page.collection != "posts" %}
|
14
15
|
{% assign collection = page.collection | capitalize %}
|
15
16
|
{% assign title = title | append: " | " | append: collection %}
|
@@ -23,18 +24,18 @@
|
|
23
24
|
<title type="html">{{ title | smartify | xml_escape }}</title>
|
24
25
|
{% endif %}
|
25
26
|
|
26
|
-
{% if site.description %}
|
27
|
-
<subtitle>{{ site.description | xml_escape }}</subtitle>
|
27
|
+
{% if site.metadata.description %}
|
28
|
+
<subtitle>{{ site.metadata.description | xml_escape }}</subtitle>
|
28
29
|
{% endif %}
|
29
30
|
|
30
|
-
{% if site.author %}
|
31
|
+
{% if site.metadata.author %}
|
31
32
|
<author>
|
32
|
-
<name>{{ site.author.name | default: site.author | xml_escape }}</name>
|
33
|
-
{% if site.author.email %}
|
34
|
-
<email>{{ site.author.email | xml_escape }}</email>
|
33
|
+
<name>{{ site.metadata.author.name | default: site.metadata.author | xml_escape }}</name>
|
34
|
+
{% if site.metadata.author.email %}
|
35
|
+
<email>{{ site.metadata.author.email | xml_escape }}</email>
|
35
36
|
{% endif %}
|
36
|
-
{% if site.author.uri %}
|
37
|
-
<uri>{{ site.author.uri | xml_escape }}</uri>
|
37
|
+
{% if site.metadata.author.uri %}
|
38
|
+
<uri>{{ site.metadata.author.uri | xml_escape }}</uri>
|
38
39
|
{% endif %}
|
39
40
|
</author>
|
40
41
|
{% endif %}
|
@@ -55,7 +56,7 @@
|
|
55
56
|
<content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">{{ post.content | strip | xml_escape }}</content>
|
56
57
|
{% endunless %}
|
57
58
|
|
58
|
-
{% assign post_author = post.author | default: post.authors[0] | default: site.author %}
|
59
|
+
{% assign post_author = post.author | default: post.authors[0] | default: site.metadata.author %}
|
59
60
|
{% assign post_author = site.data.authors[post_author] | default: post_author %}
|
60
61
|
{% assign post_author_email = post_author.email | default: nil %}
|
61
62
|
{% assign post_author_uri = post_author.uri | default: nil %}
|
@@ -17,6 +17,10 @@ module BridgetownFeed
|
|
17
17
|
@config ||= @context.registers[:site].config
|
18
18
|
end
|
19
19
|
|
20
|
+
def metadata
|
21
|
+
@metadata ||= @context.registers[:site].data["site_metadata"]
|
22
|
+
end
|
23
|
+
|
20
24
|
def attributes
|
21
25
|
{
|
22
26
|
:type => "application/atom+xml",
|
@@ -31,7 +35,7 @@ module BridgetownFeed
|
|
31
35
|
end
|
32
36
|
|
33
37
|
def title
|
34
|
-
|
38
|
+
metadata["title"] || metadata["name"]
|
35
39
|
end
|
36
40
|
end
|
37
41
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bridgetown-feed
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bridgetown Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-04-
|
11
|
+
date: 2020-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bridgetown
|
@@ -141,30 +141,6 @@ files:
|
|
141
141
|
- lib/bridgetown-feed/meta-tag.rb
|
142
142
|
- lib/bridgetown-feed/page-without-a-file.rb
|
143
143
|
- lib/bridgetown-feed/version.rb
|
144
|
-
- script/bootstrap
|
145
|
-
- script/cibuild
|
146
|
-
- script/fmt
|
147
|
-
- script/release
|
148
|
-
- script/test
|
149
|
-
- spec/bridgetown-feed_spec.rb
|
150
|
-
- spec/fixtures/bridgetown.config.yml
|
151
|
-
- spec/fixtures/src/_collection/2018-01-01-collection-doc.md
|
152
|
-
- spec/fixtures/src/_collection/2018-01-02-collection-category-doc.md
|
153
|
-
- spec/fixtures/src/_data/authors.yml
|
154
|
-
- spec/fixtures/src/_layouts/some_default.html
|
155
|
-
- spec/fixtures/src/_posts/2013-12-12-dec-the-second.md
|
156
|
-
- spec/fixtures/src/_posts/2014-03-02-march-the-second.md
|
157
|
-
- spec/fixtures/src/_posts/2014-03-04-march-the-fourth.md
|
158
|
-
- spec/fixtures/src/_posts/2015-01-12-a-draft.md
|
159
|
-
- spec/fixtures/src/_posts/2015-01-18-jekyll-last-modified-at.md
|
160
|
-
- spec/fixtures/src/_posts/2015-02-12-strip-newlines.md
|
161
|
-
- spec/fixtures/src/_posts/2015-05-12-liquid.md
|
162
|
-
- spec/fixtures/src/_posts/2015-05-12-pre.html
|
163
|
-
- spec/fixtures/src/_posts/2015-05-18-author-detail.md
|
164
|
-
- spec/fixtures/src/_posts/2015-08-08-stuck-in-the-middle.html
|
165
|
-
- spec/fixtures/src/_posts/2016-04-25-author-reference.md
|
166
|
-
- spec/fixtures/src/feed.xslt.xml
|
167
|
-
- spec/spec_helper.rb
|
168
144
|
homepage: https://github.com/bridgetownrb/bridgetown-feed
|
169
145
|
licenses:
|
170
146
|
- MIT
|
@@ -188,23 +164,4 @@ rubygems_version: 3.0.6
|
|
188
164
|
signing_key:
|
189
165
|
specification_version: 4
|
190
166
|
summary: A Bridgetown plugin to generate an Atom feed of your Bridgetown posts
|
191
|
-
test_files:
|
192
|
-
- spec/bridgetown-feed_spec.rb
|
193
|
-
- spec/fixtures/bridgetown.config.yml
|
194
|
-
- spec/fixtures/src/_collection/2018-01-01-collection-doc.md
|
195
|
-
- spec/fixtures/src/_collection/2018-01-02-collection-category-doc.md
|
196
|
-
- spec/fixtures/src/_data/authors.yml
|
197
|
-
- spec/fixtures/src/_layouts/some_default.html
|
198
|
-
- spec/fixtures/src/_posts/2013-12-12-dec-the-second.md
|
199
|
-
- spec/fixtures/src/_posts/2014-03-02-march-the-second.md
|
200
|
-
- spec/fixtures/src/_posts/2014-03-04-march-the-fourth.md
|
201
|
-
- spec/fixtures/src/_posts/2015-01-12-a-draft.md
|
202
|
-
- spec/fixtures/src/_posts/2015-01-18-jekyll-last-modified-at.md
|
203
|
-
- spec/fixtures/src/_posts/2015-02-12-strip-newlines.md
|
204
|
-
- spec/fixtures/src/_posts/2015-05-12-liquid.md
|
205
|
-
- spec/fixtures/src/_posts/2015-05-12-pre.html
|
206
|
-
- spec/fixtures/src/_posts/2015-05-18-author-detail.md
|
207
|
-
- spec/fixtures/src/_posts/2015-08-08-stuck-in-the-middle.html
|
208
|
-
- spec/fixtures/src/_posts/2016-04-25-author-reference.md
|
209
|
-
- spec/fixtures/src/feed.xslt.xml
|
210
|
-
- spec/spec_helper.rb
|
167
|
+
test_files: []
|
data/script/bootstrap
DELETED
data/script/cibuild
DELETED
data/script/fmt
DELETED
data/script/release
DELETED
data/script/test
DELETED
@@ -1,525 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
describe(BridgetownFeed) do
|
6
|
-
let(:overrides) { {} }
|
7
|
-
let(:config) do
|
8
|
-
Bridgetown.configuration(Bridgetown::Utils.deep_merge_hashes({
|
9
|
-
"full_rebuild" => true,
|
10
|
-
"root_dir" => root_dir,
|
11
|
-
"source" => source_dir,
|
12
|
-
"destination" => dest_dir,
|
13
|
-
"show_drafts" => true,
|
14
|
-
"url" => "http://example.org",
|
15
|
-
"name" => "My awesome site",
|
16
|
-
"author" => {
|
17
|
-
"name" => "Dr. Bridgetown",
|
18
|
-
},
|
19
|
-
"collections" => {
|
20
|
-
"my_collection" => { "output" => true },
|
21
|
-
"other_things" => { "output" => false },
|
22
|
-
},
|
23
|
-
}, overrides))
|
24
|
-
end
|
25
|
-
let(:site) { Bridgetown::Site.new(config) }
|
26
|
-
let(:contents) { File.read(dest_dir("feed.xml")) }
|
27
|
-
let(:context) { make_context(:site => site) }
|
28
|
-
let(:feed_meta) { Liquid::Template.parse("{% feed_meta %}").render!(context, {}) }
|
29
|
-
before(:each) do
|
30
|
-
site.process
|
31
|
-
end
|
32
|
-
|
33
|
-
it "has no layout" do
|
34
|
-
expect(contents).not_to match(%r!\ATHIS IS MY LAYOUT!)
|
35
|
-
end
|
36
|
-
|
37
|
-
it "creates a feed.xml file" do
|
38
|
-
expect(Pathname.new(dest_dir("feed.xml"))).to exist
|
39
|
-
end
|
40
|
-
|
41
|
-
it "doesn't have multiple new lines or trailing whitespace" do
|
42
|
-
expect(contents).to_not match %r!\s+\n!
|
43
|
-
expect(contents).to_not match %r!\n{2,}!
|
44
|
-
end
|
45
|
-
|
46
|
-
it "puts all the posts in the feed.xml file" do
|
47
|
-
expect(contents).to match "http://example.org/updates/bridgetown/2014/03/04/march-the-fourth.html"
|
48
|
-
expect(contents).to match "http://example.org/news/2014/03/02/march-the-second.html"
|
49
|
-
expect(contents).to match "http://example.org/news/2013/12/12/dec-the-second.html"
|
50
|
-
expect(contents).to match "http://example.org/2015/08/08/stuck-in-the-middle.html"
|
51
|
-
expect(contents).to_not match "http://example.org/2016/02/09/a-draft.html"
|
52
|
-
end
|
53
|
-
|
54
|
-
it "does not include assets or any static files that aren't .html" do
|
55
|
-
expect(contents).not_to match "http://example.org/images/hubot.png"
|
56
|
-
expect(contents).not_to match "http://example.org/feeds/atom.xml"
|
57
|
-
end
|
58
|
-
|
59
|
-
it "preserves linebreaks in preformatted text in posts" do
|
60
|
-
expect(contents).to match "Line 1\nLine 2\nLine 3"
|
61
|
-
end
|
62
|
-
|
63
|
-
it "supports post author name as an object" do
|
64
|
-
expect(contents).to match %r!<author>\s*<name>Ben</name>\s*<email>ben@example\.com</email>\s*<uri>http://ben\.balter\.com</uri>\s*</author>!
|
65
|
-
end
|
66
|
-
|
67
|
-
it "supports post author name as a string" do
|
68
|
-
expect(contents).to match %r!<author>\s*<name>Pat</name>\s*</author>!
|
69
|
-
end
|
70
|
-
|
71
|
-
it "does not output author tag no author is provided" do
|
72
|
-
expect(contents).not_to match %r!<author>\s*<name></name>\s*</author>!
|
73
|
-
end
|
74
|
-
|
75
|
-
it "does use author reference with data from _data/authors.yml" do
|
76
|
-
expect(contents).to match %r!<author>\s*<name>Garth</name>\s*<email>example@mail\.com</email>\s*<uri>http://garthdb\.com</uri>\s*</author>!
|
77
|
-
end
|
78
|
-
|
79
|
-
it "converts markdown posts to HTML" do
|
80
|
-
expect(contents).to match %r!<p>March the second\!</p>!
|
81
|
-
end
|
82
|
-
|
83
|
-
it "uses last_modified_at where available" do
|
84
|
-
expect(contents).to match %r!<updated>2015-05-12T13:27:59\+00:00</updated>!
|
85
|
-
end
|
86
|
-
|
87
|
-
it "replaces newlines in posts to spaces" do
|
88
|
-
expect(contents).to match '<title type="html">The plugin will properly strip newlines.</title>'
|
89
|
-
end
|
90
|
-
|
91
|
-
it "renders Liquid inside posts" do
|
92
|
-
expect(contents).to match "Liquid is rendered."
|
93
|
-
expect(contents).not_to match "Liquid is not rendered."
|
94
|
-
end
|
95
|
-
|
96
|
-
context "images" do
|
97
|
-
let(:image1) { 'http://example.org/image.png' }
|
98
|
-
let(:image2) { 'https://cdn.example.org/absolute.png?h=188&w=250' }
|
99
|
-
let(:image3) { 'http://example.org/object-image.png' }
|
100
|
-
|
101
|
-
it "includes the item image" do
|
102
|
-
expect(contents).to include(%(<media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="#{image1}" />))
|
103
|
-
expect(contents).to include(%(<media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="#{image2}" />))
|
104
|
-
expect(contents).to include(%(<media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="#{image3}" />))
|
105
|
-
end
|
106
|
-
|
107
|
-
it "included media content for mail templates (Mailchimp)" do
|
108
|
-
expect(contents).to include(%(<media:content medium="image" url="#{image1}" xmlns:media="http://search.yahoo.com/mrss/" />))
|
109
|
-
expect(contents).to include(%(<media:content medium="image" url="#{image2}" xmlns:media="http://search.yahoo.com/mrss/" />))
|
110
|
-
expect(contents).to include(%(<media:content medium="image" url="#{image3}" xmlns:media="http://search.yahoo.com/mrss/" />))
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
context "parsing" do
|
115
|
-
let(:feed) { RSS::Parser.parse(contents) }
|
116
|
-
|
117
|
-
it "outputs an RSS feed" do
|
118
|
-
expect(feed.feed_type).to eql("atom")
|
119
|
-
expect(feed.feed_version).to eql("1.0")
|
120
|
-
expect(feed.encoding).to eql("UTF-8")
|
121
|
-
expect(feed.lang).to be_nil
|
122
|
-
expect(feed.valid?).to eql(true)
|
123
|
-
end
|
124
|
-
|
125
|
-
it "outputs the link" do
|
126
|
-
expect(feed.link.href).to eql("http://example.org/feed.xml")
|
127
|
-
end
|
128
|
-
|
129
|
-
it "outputs the generator" do
|
130
|
-
expect(feed.generator.content).to eql("Bridgetown")
|
131
|
-
expect(feed.generator.version).to eql(Bridgetown::VERSION)
|
132
|
-
end
|
133
|
-
|
134
|
-
it "includes the items" do
|
135
|
-
expect(feed.items.count).to eql(10)
|
136
|
-
end
|
137
|
-
|
138
|
-
it "includes item contents" do
|
139
|
-
post = feed.items.last
|
140
|
-
expect(post.title.content).to eql("Dec The Second")
|
141
|
-
expect(post.link.href).to eql("http://example.org/news/2013/12/12/dec-the-second.html")
|
142
|
-
expect(post.published.content).to eql(Time.parse("2013-12-12"))
|
143
|
-
end
|
144
|
-
|
145
|
-
it "includes the item's excerpt" do
|
146
|
-
post = feed.items.last
|
147
|
-
expect(post.summary.content).to eql("Foo")
|
148
|
-
end
|
149
|
-
|
150
|
-
it "doesn't include the item's excerpt if blank" do
|
151
|
-
post = feed.items.first
|
152
|
-
expect(post.summary).to be_nil
|
153
|
-
end
|
154
|
-
|
155
|
-
context "with site.lang set" do
|
156
|
-
lang = "en_US"
|
157
|
-
let(:overrides) { { "lang" => lang } }
|
158
|
-
it "outputs a valid feed" do
|
159
|
-
expect(feed.feed_type).to eql("atom")
|
160
|
-
expect(feed.feed_version).to eql("1.0")
|
161
|
-
expect(feed.encoding).to eql("UTF-8")
|
162
|
-
expect(feed.valid?).to eql(true)
|
163
|
-
end
|
164
|
-
|
165
|
-
it "outputs the correct language" do
|
166
|
-
expect(feed.lang).to eql(lang)
|
167
|
-
end
|
168
|
-
|
169
|
-
it "sets the language of entries" do
|
170
|
-
post = feed.items.first
|
171
|
-
expect(post.lang).to eql(lang)
|
172
|
-
end
|
173
|
-
|
174
|
-
it "renders the feed meta" do
|
175
|
-
expected = %r!<link href="http://example.org/" rel="alternate" type="text/html" hreflang="#{lang}" />!
|
176
|
-
expect(contents).to match(expected)
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
context "with site.title set" do
|
181
|
-
let(:site_title) { "My Site Title" }
|
182
|
-
let(:overrides) { { "title" => site_title } }
|
183
|
-
|
184
|
-
it "uses site.title for the title" do
|
185
|
-
expect(feed.title.content).to eql(site_title)
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
context "with site.name set" do
|
190
|
-
let(:site_name) { "My Site Name" }
|
191
|
-
let(:overrides) { { "name" => site_name } }
|
192
|
-
|
193
|
-
it "uses site.name for the title" do
|
194
|
-
expect(feed.title.content).to eql(site_name)
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
context "with site.name and site.title set" do
|
199
|
-
let(:site_title) { "My Site Title" }
|
200
|
-
let(:site_name) { "My Site Name" }
|
201
|
-
let(:overrides) { { "title" => site_title, "name" => site_name } }
|
202
|
-
|
203
|
-
it "uses site.title for the title, dropping site.name" do
|
204
|
-
expect(feed.title.content).to eql(site_title)
|
205
|
-
end
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
context "smartify" do
|
210
|
-
let(:site_title) { "Pat's Site" }
|
211
|
-
let(:overrides) { { "title" => site_title } }
|
212
|
-
let(:feed) { RSS::Parser.parse(contents) }
|
213
|
-
|
214
|
-
it "processes site title with SmartyPants" do
|
215
|
-
expect(feed.title.content).to eql("Pat’s Site")
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
context "validation" do
|
220
|
-
it "validates" do
|
221
|
-
skip "Typhoeus couldn't find the 'libcurl' module on Windows" if Gem.win_platform?
|
222
|
-
# See https://validator.w3.org/docs/api.html
|
223
|
-
url = "https://validator.w3.org/feed/check.cgi?output=soap12"
|
224
|
-
response = Typhoeus.post(url, :body => { :rawdata => contents }, :accept_encoding => "gzip")
|
225
|
-
pending "Something went wrong with the W3 validator" unless response.success?
|
226
|
-
result = Nokogiri::XML(response.body)
|
227
|
-
result.remove_namespaces!
|
228
|
-
|
229
|
-
result.css("warning").each do |warning|
|
230
|
-
# Quiet a warning that results from us passing the feed as a string
|
231
|
-
next if warning.css("text").text =~ %r!Self reference doesn't match document location!
|
232
|
-
|
233
|
-
# Quiet expected warning that results from blank summary test case
|
234
|
-
next if warning.css("text").text =~ %r!(content|summary) should not be blank!
|
235
|
-
|
236
|
-
# Quiet expected warning about multiple posts with same updated time
|
237
|
-
next if warning.css("text").text =~ %r!Two entries with the same value for atom:updated!
|
238
|
-
|
239
|
-
warn "Validation warning: #{warning.css("text").text} on line #{warning.css("line").text} column #{warning.css("column").text}"
|
240
|
-
end
|
241
|
-
|
242
|
-
errors = result.css("error").map do |error|
|
243
|
-
"Validation error: #{error.css("text").text} on line #{error.css("line").text} column #{error.css("column").text}"
|
244
|
-
end
|
245
|
-
|
246
|
-
expect(result.css("validity").text).to eql("true"), errors.join("\n")
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
context "with a baseurl" do
|
251
|
-
let(:overrides) do
|
252
|
-
{ "baseurl" => "/bass" }
|
253
|
-
end
|
254
|
-
|
255
|
-
it "correctly adds the baseurl to the posts" do
|
256
|
-
expect(contents).to match "http://example.org/bass/updates/bridgetown/2014/03/04/march-the-fourth.html"
|
257
|
-
expect(contents).to match "http://example.org/bass/news/2014/03/02/march-the-second.html"
|
258
|
-
expect(contents).to match "http://example.org/bass/news/2013/12/12/dec-the-second.html"
|
259
|
-
end
|
260
|
-
|
261
|
-
it "renders the feed meta" do
|
262
|
-
expected = 'href="http://example.org/bass/feed.xml"'
|
263
|
-
expect(feed_meta).to include(expected)
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
context "feed meta" do
|
268
|
-
it "renders the feed meta" do
|
269
|
-
expected = '<link type="application/atom+xml" rel="alternate" href="http://example.org/feed.xml" title="My awesome site" />'
|
270
|
-
expect(feed_meta).to eql(expected)
|
271
|
-
end
|
272
|
-
|
273
|
-
context "with a blank site name" do
|
274
|
-
let(:config) do
|
275
|
-
Bridgetown.configuration(
|
276
|
-
"source" => source_dir,
|
277
|
-
"destination" => dest_dir,
|
278
|
-
"url" => "http://example.org"
|
279
|
-
)
|
280
|
-
end
|
281
|
-
|
282
|
-
it "does not output blank title" do
|
283
|
-
expect(feed_meta).not_to include("title=")
|
284
|
-
end
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
context "changing the feed path" do
|
289
|
-
let(:overrides) do
|
290
|
-
{
|
291
|
-
"feed" => {
|
292
|
-
"path" => "atom.xml",
|
293
|
-
},
|
294
|
-
}
|
295
|
-
end
|
296
|
-
|
297
|
-
it "should write to atom.xml" do
|
298
|
-
expect(Pathname.new(dest_dir("atom.xml"))).to exist
|
299
|
-
end
|
300
|
-
|
301
|
-
it "renders the feed meta with custom feed path" do
|
302
|
-
expected = 'href="http://example.org/atom.xml"'
|
303
|
-
expect(feed_meta).to include(expected)
|
304
|
-
end
|
305
|
-
end
|
306
|
-
|
307
|
-
context "changing the file path via collection meta" do
|
308
|
-
let(:overrides) do
|
309
|
-
{
|
310
|
-
"feed" => {
|
311
|
-
"collections" => {
|
312
|
-
"posts" => {
|
313
|
-
"path" => "atom.xml",
|
314
|
-
},
|
315
|
-
},
|
316
|
-
},
|
317
|
-
}
|
318
|
-
end
|
319
|
-
|
320
|
-
it "should write to atom.xml" do
|
321
|
-
expect(Pathname.new(dest_dir("atom.xml"))).to exist
|
322
|
-
end
|
323
|
-
|
324
|
-
it "renders the feed meta with custom feed path" do
|
325
|
-
expected = 'href="http://example.org/atom.xml"'
|
326
|
-
expect(feed_meta).to include(expected)
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
|
-
context "feed stylesheet" do
|
331
|
-
it "includes the stylesheet" do
|
332
|
-
expect(contents).to include('<?xml-stylesheet type="text/xml" href="http://example.org/feed.xslt.xml"?>')
|
333
|
-
end
|
334
|
-
end
|
335
|
-
|
336
|
-
context "with site.lang set" do
|
337
|
-
let(:overrides) { { "lang" => "en-US" } }
|
338
|
-
|
339
|
-
it "should set the language" do
|
340
|
-
expect(contents).to match 'type="text/html" hreflang="en-US" />'
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
|
-
context "with post.lang set" do
|
345
|
-
it "should set the language for that entry" do
|
346
|
-
expect(contents).to match '<entry xml:lang="en">'
|
347
|
-
expect(contents).to match '<entry>'
|
348
|
-
end
|
349
|
-
end
|
350
|
-
|
351
|
-
context "categories" do
|
352
|
-
context "with top-level post categories" do
|
353
|
-
let(:overrides) do
|
354
|
-
{
|
355
|
-
"feed" => { "categories" => ["news"] },
|
356
|
-
}
|
357
|
-
end
|
358
|
-
let(:news_feed) { File.read(dest_dir("feed/news.xml")) }
|
359
|
-
|
360
|
-
it "outputs the primary feed" do
|
361
|
-
expect(contents).to match "http://example.org/updates/bridgetown/2014/03/04/march-the-fourth.html"
|
362
|
-
expect(contents).to match "http://example.org/news/2014/03/02/march-the-second.html"
|
363
|
-
expect(contents).to match "http://example.org/news/2013/12/12/dec-the-second.html"
|
364
|
-
expect(contents).to match "http://example.org/2015/08/08/stuck-in-the-middle.html"
|
365
|
-
expect(contents).to_not match "http://example.org/2016/02/09/a-draft.html"
|
366
|
-
end
|
367
|
-
|
368
|
-
it "outputs the category feed" do
|
369
|
-
expect(news_feed).to match '<title type="html">My awesome site | News</title>'
|
370
|
-
expect(news_feed).to match "http://example.org/news/2014/03/02/march-the-second.html"
|
371
|
-
expect(news_feed).to match "http://example.org/news/2013/12/12/dec-the-second.html"
|
372
|
-
expect(news_feed).to_not match "http://example.org/updates/bridgetown/2014/03/04/march-the-fourth.html"
|
373
|
-
expect(news_feed).to_not match "http://example.org/2015/08/08/stuck-in-the-middle.html"
|
374
|
-
end
|
375
|
-
end
|
376
|
-
|
377
|
-
context "with collection-level post categories" do
|
378
|
-
let(:overrides) do
|
379
|
-
{
|
380
|
-
"feed" => {
|
381
|
-
"collections" => {
|
382
|
-
"posts" => {
|
383
|
-
"categories" => ["news"],
|
384
|
-
},
|
385
|
-
},
|
386
|
-
},
|
387
|
-
}
|
388
|
-
end
|
389
|
-
let(:news_feed) { File.read(dest_dir("feed/news.xml")) }
|
390
|
-
|
391
|
-
it "outputs the primary feed" do
|
392
|
-
expect(contents).to match "http://example.org/updates/bridgetown/2014/03/04/march-the-fourth.html"
|
393
|
-
expect(contents).to match "http://example.org/news/2014/03/02/march-the-second.html"
|
394
|
-
expect(contents).to match "http://example.org/news/2013/12/12/dec-the-second.html"
|
395
|
-
expect(contents).to match "http://example.org/2015/08/08/stuck-in-the-middle.html"
|
396
|
-
expect(contents).to_not match "http://example.org/2016/02/09/a-draft.html"
|
397
|
-
end
|
398
|
-
|
399
|
-
it "outputs the category feed" do
|
400
|
-
expect(news_feed).to match '<title type="html">My awesome site | News</title>'
|
401
|
-
expect(news_feed).to match "http://example.org/news/2014/03/02/march-the-second.html"
|
402
|
-
expect(news_feed).to match "http://example.org/news/2013/12/12/dec-the-second.html"
|
403
|
-
expect(news_feed).to_not match "http://example.org/updates/bridgetown/2014/03/04/march-the-fourth.html"
|
404
|
-
expect(news_feed).to_not match "http://example.org/2015/08/08/stuck-in-the-middle.html"
|
405
|
-
end
|
406
|
-
end
|
407
|
-
end
|
408
|
-
|
409
|
-
context "collections" do
|
410
|
-
let(:collection_feed) { File.read(dest_dir("feed/collection.xml")) }
|
411
|
-
|
412
|
-
context "when initialized as an array" do
|
413
|
-
let(:overrides) do
|
414
|
-
{
|
415
|
-
"collections" => {
|
416
|
-
"collection" => {
|
417
|
-
"output" => true,
|
418
|
-
},
|
419
|
-
},
|
420
|
-
"feed" => { "collections" => ["collection"] },
|
421
|
-
}
|
422
|
-
end
|
423
|
-
|
424
|
-
it "outputs the collection feed" do
|
425
|
-
expect(collection_feed).to match '<title type="html">My awesome site | Collection</title>'
|
426
|
-
expect(collection_feed).to match "http://example.org/collection/2018-01-01-collection-doc.html"
|
427
|
-
expect(collection_feed).to match "http://example.org/collection/2018-01-02-collection-category-doc.html"
|
428
|
-
expect(collection_feed).to_not match "http://example.org/updates/bridgetown/2014/03/04/march-the-fourth.html"
|
429
|
-
expect(collection_feed).to_not match "http://example.org/2015/08/08/stuck-in-the-middle.html"
|
430
|
-
end
|
431
|
-
end
|
432
|
-
|
433
|
-
context "with categories" do
|
434
|
-
let(:overrides) do
|
435
|
-
{
|
436
|
-
"collections" => {
|
437
|
-
"collection" => {
|
438
|
-
"output" => true,
|
439
|
-
},
|
440
|
-
},
|
441
|
-
"feed" => {
|
442
|
-
"collections" => {
|
443
|
-
"collection" => {
|
444
|
-
"categories" => ["news"],
|
445
|
-
},
|
446
|
-
},
|
447
|
-
},
|
448
|
-
}
|
449
|
-
end
|
450
|
-
let(:news_feed) { File.read(dest_dir("feed/collection/news.xml")) }
|
451
|
-
|
452
|
-
it "outputs the collection category feed" do
|
453
|
-
expect(news_feed).to match '<title type="html">My awesome site | Collection | News</title>'
|
454
|
-
expect(news_feed).to match "http://example.org/collection/2018-01-02-collection-category-doc.html"
|
455
|
-
expect(news_feed).to_not match "http://example.org/collection/2018-01-01-collection-doc.html"
|
456
|
-
expect(news_feed).to_not match "http://example.org/updates/bridgetown/2014/03/04/march-the-fourth.html"
|
457
|
-
expect(news_feed).to_not match "http://example.org/2015/08/08/stuck-in-the-middle.html"
|
458
|
-
end
|
459
|
-
end
|
460
|
-
|
461
|
-
context "with a custom path" do
|
462
|
-
let(:overrides) do
|
463
|
-
{
|
464
|
-
"collections" => {
|
465
|
-
"collection" => {
|
466
|
-
"output" => true,
|
467
|
-
},
|
468
|
-
},
|
469
|
-
"feed" => {
|
470
|
-
"collections" => {
|
471
|
-
"collection" => {
|
472
|
-
"categories" => ["news"],
|
473
|
-
"path" => "custom.xml",
|
474
|
-
},
|
475
|
-
},
|
476
|
-
},
|
477
|
-
}
|
478
|
-
end
|
479
|
-
|
480
|
-
it "should write to the custom path" do
|
481
|
-
expect(Pathname.new(dest_dir("custom.xml"))).to exist
|
482
|
-
expect(Pathname.new(dest_dir("feed/collection.xml"))).to_not exist
|
483
|
-
expect(Pathname.new(dest_dir("feed/collection/news.xml"))).to exist
|
484
|
-
end
|
485
|
-
end
|
486
|
-
end
|
487
|
-
|
488
|
-
context "excerpt_only flag" do
|
489
|
-
context "backward compatibility for no excerpt_only flag" do
|
490
|
-
it "should be in contents" do
|
491
|
-
expect(contents).to match '<content '
|
492
|
-
end
|
493
|
-
end
|
494
|
-
|
495
|
-
context "when site.excerpt_only flag is true" do
|
496
|
-
let(:overrides) do
|
497
|
-
{ "feed" => { "excerpt_only" => true } }
|
498
|
-
end
|
499
|
-
|
500
|
-
it "should not set any contents" do
|
501
|
-
expect(contents).to_not match '<content '
|
502
|
-
end
|
503
|
-
end
|
504
|
-
|
505
|
-
context "when site.excerpt_only flag is false" do
|
506
|
-
let(:overrides) do
|
507
|
-
{ "feed" => { "excerpt_only" => false } }
|
508
|
-
end
|
509
|
-
|
510
|
-
it "should be in contents" do
|
511
|
-
expect(contents).to match '<content '
|
512
|
-
end
|
513
|
-
end
|
514
|
-
|
515
|
-
context "when post.excerpt_only flag is true" do
|
516
|
-
let(:overrides) do
|
517
|
-
{ "feed" => { "excerpt_only" => false } }
|
518
|
-
end
|
519
|
-
|
520
|
-
it "should not be in contents" do
|
521
|
-
expect(contents).to_not match "This content should not be in feed.</content>"
|
522
|
-
end
|
523
|
-
end
|
524
|
-
end
|
525
|
-
end
|
File without changes
|
data/spec/spec_helper.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "bridgetown"
|
4
|
-
require "typhoeus" unless Gem.win_platform?
|
5
|
-
require "nokogiri"
|
6
|
-
require "rss"
|
7
|
-
require File.expand_path("../lib/bridgetown-feed", __dir__)
|
8
|
-
|
9
|
-
Bridgetown.logger.log_level = :error
|
10
|
-
|
11
|
-
RSpec.configure do |config|
|
12
|
-
config.run_all_when_everything_filtered = true
|
13
|
-
config.filter_run :focus
|
14
|
-
config.order = "random"
|
15
|
-
|
16
|
-
ROOT_DIR = File.expand_path("fixtures", __dir__)
|
17
|
-
SOURCE_DIR = File.join(ROOT_DIR, "src")
|
18
|
-
DEST_DIR = File.expand_path("dest", __dir__)
|
19
|
-
|
20
|
-
def root_dir(*files)
|
21
|
-
File.join(ROOT_DIR, *files)
|
22
|
-
end
|
23
|
-
|
24
|
-
def source_dir(*files)
|
25
|
-
File.join(SOURCE_DIR, *files)
|
26
|
-
end
|
27
|
-
|
28
|
-
def dest_dir(*files)
|
29
|
-
File.join(DEST_DIR, *files)
|
30
|
-
end
|
31
|
-
|
32
|
-
def make_context(registers = {})
|
33
|
-
Liquid::Context.new({}, {}, { :site => site }.merge(registers))
|
34
|
-
end
|
35
|
-
end
|