jekyll-feed 0.10.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/History.markdown +57 -0
- data/README.md +105 -1
- data/lib/jekyll-feed/feed.xml +37 -10
- data/lib/jekyll-feed/generator.rb +107 -24
- data/lib/jekyll-feed/meta-tag.rb +3 -7
- data/lib/jekyll-feed/version.rb +1 -1
- metadata +32 -70
- data/.gitignore +0 -20
- data/.rspec +0 -2
- data/.rubocop.yml +0 -28
- data/.travis.yml +0 -25
- data/Gemfile +0 -8
- data/Rakefile +0 -8
- data/jekyll-feed.gemspec +0 -29
- 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/fixtures/_config.yml +0 -9
- data/spec/fixtures/_data/authors.yml +0 -5
- data/spec/fixtures/_drafts/2015-01-12-a-draft.md +0 -4
- data/spec/fixtures/_layouts/some_default.html +0 -11
- data/spec/fixtures/_posts/2013-12-12-dec-the-second.md +0 -6
- data/spec/fixtures/_posts/2014-03-02-march-the-second.md +0 -5
- data/spec/fixtures/_posts/2014-03-04-march-the-fourth.md +0 -8
- data/spec/fixtures/_posts/2015-01-18-jekyll-last-modified-at.md +0 -5
- data/spec/fixtures/_posts/2015-02-12-strip-newlines.md +0 -6
- data/spec/fixtures/_posts/2015-05-12-liquid.md +0 -7
- data/spec/fixtures/_posts/2015-05-12-pre.html +0 -8
- data/spec/fixtures/_posts/2015-05-18-author-detail.md +0 -9
- data/spec/fixtures/_posts/2015-08-08-stuck-in-the-middle.html +0 -2
- data/spec/fixtures/_posts/2016-04-25-author-reference.md +0 -6
- data/spec/fixtures/feed.xslt.xml +0 -0
- data/spec/jekyll-feed_spec.rb +0 -313
- data/spec/spec_helper.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c244c9b3dc51c5a96051fe247af215ac0a136bb57fc6fe4f491ffa4acad122e6
|
4
|
+
data.tar.gz: a461c52155aa01616e59161c1c44a3eb1e0cfc3ebf58ef5bae70c9e5167272a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5274b2f62e9fd6184bad9859bcd1ab4d10a0a2bc691393a3ccdae26de936b4a2fc8072db62b0f4cbab39c9efc8b284fb7b023bfac4f575af41efe8de16f609df
|
7
|
+
data.tar.gz: 5d0396d7edaa675efcf772cc57c9b7138e523b73a6a452274cca863483740a97d0036e871301dcea951eea1e0b04ce2551b2bc9b9bb4b92fc2d262100d7da45a
|
data/History.markdown
CHANGED
@@ -1,3 +1,60 @@
|
|
1
|
+
## 0.14.0 / 2020-06-24
|
2
|
+
|
3
|
+
### Minor Enhancements
|
4
|
+
|
5
|
+
* add support for categories (#153) (#233)
|
6
|
+
* add support for tags (#264)
|
7
|
+
* Make posts limit configurable (#314)
|
8
|
+
* XML escape the title field of feed_meta (#306)
|
9
|
+
|
10
|
+
### Bug Fixes
|
11
|
+
|
12
|
+
* Fix feed link when post title contains HTML (#305)
|
13
|
+
|
14
|
+
### Development Fixes
|
15
|
+
|
16
|
+
* Use Dir to list source files (#309)
|
17
|
+
* Require Ruby >=2.4.0 (#307)
|
18
|
+
|
19
|
+
## 0.13.0 / 2019-11-13
|
20
|
+
|
21
|
+
### Minor Enhancements
|
22
|
+
|
23
|
+
* Excerpt only flag (#287)
|
24
|
+
* Add media:content tag (#290)
|
25
|
+
|
26
|
+
### Development Fixes
|
27
|
+
|
28
|
+
* test: use categories in post (#249)
|
29
|
+
|
30
|
+
## 0.12.1 / 2019-03-23
|
31
|
+
|
32
|
+
### Bug Fixes
|
33
|
+
|
34
|
+
* Re-introduce Ruby 2.3 support and test Jekyll 3.7+ (#272)
|
35
|
+
|
36
|
+
## 0.12.0 / 2019-03-21
|
37
|
+
|
38
|
+
* Allow Jekyll v4 (still alpha)
|
39
|
+
|
40
|
+
### Development Fixes
|
41
|
+
|
42
|
+
* style: fix offenses in specs (#248)
|
43
|
+
* dev: update CI and style settings (#258)
|
44
|
+
* Enable testing for Windows platform (#265)
|
45
|
+
|
46
|
+
## 0.11.0 / 2018-09-09
|
47
|
+
|
48
|
+
### Development Fixes
|
49
|
+
|
50
|
+
* Require Ruby 2.3 (#222)
|
51
|
+
* Refactor to remove redundant calls and variables (#240)
|
52
|
+
|
53
|
+
### Minor Enhancements
|
54
|
+
|
55
|
+
* Categories and collections (#228)
|
56
|
+
* Remove check for older version of Jekyll (#234)
|
57
|
+
|
1
58
|
## 0.10.0 / 2018-06-04
|
2
59
|
|
3
60
|
### Bug Fixes
|
data/README.md
CHANGED
@@ -31,7 +31,7 @@ The plugin will automatically use any of the following configuration variables,
|
|
31
31
|
|
32
32
|
* `title` or `name` - The title of the site, e.g., "My awesome site"
|
33
33
|
* `description` - A longer description of what your site is about, e.g., "Where I blog about Jekyll and other awesome things"
|
34
|
-
* `url` - The URL to your site, e.g., `
|
34
|
+
* `url` - The URL to your site, e.g., `https://example.com`. If none is provided, the plugin will try to use `site.github.url`.
|
35
35
|
* `author` - Global author information (see below)
|
36
36
|
|
37
37
|
### Already have a feed path?
|
@@ -140,6 +140,110 @@ Want to style what your feed looks like in the browser? Simply add an XSLT at `/
|
|
140
140
|
|
141
141
|
Great question. In short, Atom is a better format. Think of it like RSS 3.0. For more information, see [this discussion on why we chose Atom over RSS 2.0](https://github.com/jekyll/jekyll-rss-feed/issues/2).
|
142
142
|
|
143
|
+
## Categories
|
144
|
+
|
145
|
+
Jekyll Feed can generate feeds for each category. Simply define which categories you'd like feeds for in your config:
|
146
|
+
|
147
|
+
```yml
|
148
|
+
feed:
|
149
|
+
categories:
|
150
|
+
- news
|
151
|
+
- updates
|
152
|
+
```
|
153
|
+
|
154
|
+
## Posts limit
|
155
|
+
|
156
|
+
By default the plugin limits the number of posts in the feed to 10. Simply define a new limit in your config:
|
157
|
+
|
158
|
+
```yml
|
159
|
+
feed:
|
160
|
+
posts_limit: 20
|
161
|
+
```
|
162
|
+
|
163
|
+
## Collections
|
164
|
+
|
165
|
+
Jekyll Feed can generate feeds for collections other than the Posts collection. This works best for chronological collections (e.g., collections with dates in the filenames). Simply define which collections you'd like feeds for in your config:
|
166
|
+
|
167
|
+
```yml
|
168
|
+
feed:
|
169
|
+
collections:
|
170
|
+
- changes
|
171
|
+
```
|
172
|
+
|
173
|
+
By default, collection feeds will be outputted to `/feed/<COLLECTION>.xml`. If you'd like to customize the output path, specify a collection's custom path as follows:
|
174
|
+
|
175
|
+
```yml
|
176
|
+
feed:
|
177
|
+
collections:
|
178
|
+
changes:
|
179
|
+
path: "/changes.xml"
|
180
|
+
```
|
181
|
+
|
182
|
+
Finally, collections can also have category feeds which are outputted as `/feed/<COLLECTION>/<CATEGORY>.xml`. Specify categories like so:
|
183
|
+
|
184
|
+
```yml
|
185
|
+
feed:
|
186
|
+
collections:
|
187
|
+
changes:
|
188
|
+
path: "/changes.xml"
|
189
|
+
categories:
|
190
|
+
- news
|
191
|
+
- updates
|
192
|
+
```
|
193
|
+
|
194
|
+
## Excerpt Only flag
|
195
|
+
|
196
|
+
Optional flag `excerpt_only` allows you to exclude post content from the Atom feed. Default value is `false` for backward compatibility.
|
197
|
+
|
198
|
+
When in `config.yml` is `true` than all posts in feed will be without `<content>` tags.
|
199
|
+
|
200
|
+
```yml
|
201
|
+
feed:
|
202
|
+
excerpt_only: true
|
203
|
+
```
|
204
|
+
|
205
|
+
The same flag can be used directly in post file. It will be disable `<content>` tag for selected post.
|
206
|
+
Settings in post file has higher priority than in config file.
|
207
|
+
|
208
|
+
## Tags
|
209
|
+
|
210
|
+
To automatically generate feeds for each tag you apply to your posts you can add a tags setting to your config:
|
211
|
+
|
212
|
+
```yml
|
213
|
+
feed:
|
214
|
+
tags: true
|
215
|
+
```
|
216
|
+
|
217
|
+
If there are tags you don't want included in this auto generation you can exclude them
|
218
|
+
|
219
|
+
```yml
|
220
|
+
feed:
|
221
|
+
tags:
|
222
|
+
except:
|
223
|
+
- tag-to-exclude
|
224
|
+
- another-tag
|
225
|
+
```
|
226
|
+
|
227
|
+
If you wish to change the location of these auto generated feeds (`/feed/by_tag/<TAG>.xml` by default) you can provide an alternative folder for them to live in.
|
228
|
+
|
229
|
+
```yml
|
230
|
+
feed:
|
231
|
+
tags:
|
232
|
+
path: "alternative/path/for/tags/feeds/"
|
233
|
+
```
|
234
|
+
|
235
|
+
If you only want to generate feeds for a few tags you can also set this.
|
236
|
+
|
237
|
+
```yml
|
238
|
+
feed:
|
239
|
+
tags:
|
240
|
+
only:
|
241
|
+
- tag-to-include
|
242
|
+
- another-tag
|
243
|
+
```
|
244
|
+
|
245
|
+
Note that if you include a tag that is excluded a feed will not be generated for it.
|
246
|
+
|
143
247
|
## Contributing
|
144
248
|
|
145
249
|
1. Fork it (https://github.com/jekyll/jekyll-feed/fork)
|
data/lib/jekyll-feed/feed.xml
CHANGED
@@ -7,12 +7,20 @@
|
|
7
7
|
<link href="{{ page.url | absolute_url }}" rel="self" type="application/atom+xml" />
|
8
8
|
<link href="{{ '/' | absolute_url }}" rel="alternate" type="text/html" {% if site.lang %}hreflang="{{ site.lang }}" {% endif %}/>
|
9
9
|
<updated>{{ site.time | date_to_xmlschema }}</updated>
|
10
|
-
<id>{{
|
10
|
+
<id>{{ page.url | absolute_url | xml_escape }}</id>
|
11
11
|
|
12
|
-
{%
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
{% assign title = site.title | default: site.name %}
|
13
|
+
{% if page.collection != "posts" %}
|
14
|
+
{% assign collection = page.collection | capitalize %}
|
15
|
+
{% assign title = title | append: " | " | append: collection %}
|
16
|
+
{% endif %}
|
17
|
+
{% if page.category %}
|
18
|
+
{% assign category = page.category | capitalize %}
|
19
|
+
{% assign title = title | append: " | " | append: category %}
|
20
|
+
{% endif %}
|
21
|
+
|
22
|
+
{% if title %}
|
23
|
+
<title type="html">{{ title | smartify | xml_escape }}</title>
|
16
24
|
{% endif %}
|
17
25
|
|
18
26
|
{% if site.description %}
|
@@ -31,15 +39,29 @@
|
|
31
39
|
</author>
|
32
40
|
{% endif %}
|
33
41
|
|
34
|
-
{%
|
35
|
-
|
42
|
+
{% if page.tags %}
|
43
|
+
{% assign entries = site.tags[page.tags] %}
|
44
|
+
{% else %}
|
45
|
+
{% assign entries = site[page.collection] %}
|
46
|
+
{% endif %}
|
47
|
+
{% assign posts = entries | where_exp: "post", "post.draft != true" | sort: "date" | reverse %}
|
48
|
+
{% if page.category %}
|
49
|
+
{% assign posts = posts | where: "category",page.category %}
|
50
|
+
{% endif %}
|
51
|
+
{% assign posts_limit = site.feed.posts_limit | default: 10 %}
|
52
|
+
{% for post in posts limit: posts_limit %}
|
36
53
|
<entry{% if post.lang %}{{" "}}xml:lang="{{ post.lang }}"{% endif %}>
|
37
|
-
|
38
|
-
|
54
|
+
{% assign post_title = post.title | smartify | strip_html | normalize_whitespace | xml_escape %}
|
55
|
+
|
56
|
+
<title type="html">{{ post_title }}</title>
|
57
|
+
<link href="{{ post.url | absolute_url }}" rel="alternate" type="text/html" title="{{ post_title }}" />
|
39
58
|
<published>{{ post.date | date_to_xmlschema }}</published>
|
40
59
|
<updated>{{ post.last_modified_at | default: post.date | date_to_xmlschema }}</updated>
|
41
60
|
<id>{{ post.id | absolute_url | xml_escape }}</id>
|
42
|
-
|
61
|
+
{% assign excerpt_only = post.feed.excerpt_only | default: site.feed.excerpt_only %}
|
62
|
+
{% unless excerpt_only %}
|
63
|
+
<content type="html" xml:base="{{ post.url | absolute_url | xml_escape }}">{{ post.content | strip | xml_escape }}</content>
|
64
|
+
{% endunless %}
|
43
65
|
|
44
66
|
{% assign post_author = post.author | default: post.authors[0] | default: site.author %}
|
45
67
|
{% assign post_author = site.data.authors[post_author] | default: post_author %}
|
@@ -59,6 +81,10 @@
|
|
59
81
|
|
60
82
|
{% if post.category %}
|
61
83
|
<category term="{{ post.category | xml_escape }}" />
|
84
|
+
{% elsif post.categories %}
|
85
|
+
{% for category in post.categories %}
|
86
|
+
<category term="{{ category | xml_escape }}" />
|
87
|
+
{% endfor %}
|
62
88
|
{% endif %}
|
63
89
|
|
64
90
|
{% for tag in post.tags %}
|
@@ -75,6 +101,7 @@
|
|
75
101
|
{% assign post_image = post_image | absolute_url %}
|
76
102
|
{% endunless %}
|
77
103
|
<media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="{{ post_image | xml_escape }}" />
|
104
|
+
<media:content medium="image" url="{{ post_image | xml_escape }}" xmlns:media="http://search.yahoo.com/mrss/" />
|
78
105
|
{% endif %}
|
79
106
|
</entry>
|
80
107
|
{% endfor %}
|
@@ -8,8 +8,16 @@ module JekyllFeed
|
|
8
8
|
# Main plugin action, called by Jekyll-core
|
9
9
|
def generate(site)
|
10
10
|
@site = site
|
11
|
-
|
12
|
-
|
11
|
+
collections.each do |name, meta|
|
12
|
+
Jekyll.logger.info "Jekyll Feed:", "Generating feed for #{name}"
|
13
|
+
(meta["categories"] + [nil]).each do |category|
|
14
|
+
path = feed_path(:collection => name, :category => category)
|
15
|
+
next if file_exists?(path)
|
16
|
+
|
17
|
+
@site.pages << make_page(path, :collection => name, :category => category)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
generate_feed_by_tag if config["tags"] && !@site.tags.empty?
|
13
21
|
end
|
14
22
|
|
15
23
|
private
|
@@ -18,40 +26,115 @@ module JekyllFeed
|
|
18
26
|
# 1. A '>', which closes an XML tag or
|
19
27
|
# 2. A '}', which closes a Liquid tag
|
20
28
|
# We will strip all of this whitespace to minify the template
|
21
|
-
MINIFY_REGEX = %r!(?<=>|})\s
|
22
|
-
|
23
|
-
#
|
24
|
-
def
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
+
MINIFY_REGEX = %r!(?<=>|})\s+!.freeze
|
30
|
+
|
31
|
+
# Returns the plugin's config or an empty hash if not set
|
32
|
+
def config
|
33
|
+
@config ||= @site.config["feed"] || {}
|
34
|
+
end
|
35
|
+
|
36
|
+
# Determines the destination path of a given feed
|
37
|
+
#
|
38
|
+
# collection - the name of a collection, e.g., "posts"
|
39
|
+
# category - a category within that collection, e.g., "news"
|
40
|
+
#
|
41
|
+
# Will return "/feed.xml", or the config-specified default feed for posts
|
42
|
+
# Will return `/feed/category.xml` for post categories
|
43
|
+
# WIll return `/feed/collection.xml` for other collections
|
44
|
+
# Will return `/feed/collection/category.xml` for other collection categories
|
45
|
+
def feed_path(collection: "posts", category: nil)
|
46
|
+
prefix = collection == "posts" ? "/feed" : "/feed/#{collection}"
|
47
|
+
return "#{prefix}/#{category}.xml" if category
|
48
|
+
|
49
|
+
collections.dig(collection, "path") || "#{prefix}.xml"
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns a hash representing all collections to be processed and their metadata
|
53
|
+
# in the form of { collection_name => { categories = [...], path = "..." } }
|
54
|
+
def collections
|
55
|
+
return @collections if defined?(@collections)
|
56
|
+
|
57
|
+
@collections = if config["collections"].is_a?(Array)
|
58
|
+
config["collections"].map { |c| [c, {}] }.to_h
|
59
|
+
elsif config["collections"].is_a?(Hash)
|
60
|
+
config["collections"]
|
61
|
+
else
|
62
|
+
{}
|
63
|
+
end
|
64
|
+
|
65
|
+
@collections = normalize_posts_meta(@collections)
|
66
|
+
@collections.each_value do |meta|
|
67
|
+
meta["categories"] = (meta["categories"] || []).to_set
|
68
|
+
end
|
69
|
+
|
70
|
+
@collections
|
71
|
+
end
|
72
|
+
|
73
|
+
def generate_feed_by_tag
|
74
|
+
tags_config = config["tags"]
|
75
|
+
tags_config = {} unless tags_config.is_a?(Hash)
|
76
|
+
|
77
|
+
except = tags_config["except"] || []
|
78
|
+
only = tags_config["only"] || @site.tags.keys
|
79
|
+
tags_pool = only - except
|
80
|
+
tags_path = tags_config["path"] || "/feed/by_tag/"
|
81
|
+
|
82
|
+
generate_tag_feed(tags_pool, tags_path)
|
83
|
+
end
|
84
|
+
|
85
|
+
def generate_tag_feed(tags_pool, tags_path)
|
86
|
+
tags_pool.each do |tag|
|
87
|
+
# allow only tags with basic alphanumeric characters and underscore to keep
|
88
|
+
# feed path simple.
|
89
|
+
next if %r![^a-zA-Z0-9_]!.match?(tag)
|
90
|
+
|
91
|
+
Jekyll.logger.info "Jekyll Feed:", "Generating feed for posts tagged #{tag}"
|
92
|
+
path = "#{tags_path}#{tag}.xml"
|
93
|
+
next if file_exists?(path)
|
94
|
+
|
95
|
+
@site.pages << make_page(path, :tags => tag)
|
29
96
|
end
|
30
97
|
end
|
31
98
|
|
32
99
|
# Path to feed.xml template file
|
33
100
|
def feed_source_path
|
34
|
-
File.expand_path "feed.xml", __dir__
|
101
|
+
@feed_source_path ||= File.expand_path "feed.xml", __dir__
|
102
|
+
end
|
103
|
+
|
104
|
+
def feed_template
|
105
|
+
@feed_template ||= File.read(feed_source_path).gsub(MINIFY_REGEX, "")
|
35
106
|
end
|
36
107
|
|
37
108
|
# Checks if a file already exists in the site source
|
38
109
|
def file_exists?(file_path)
|
39
|
-
|
40
|
-
File.exist? @site.in_source_dir(file_path)
|
41
|
-
else
|
42
|
-
File.exist? Jekyll.sanitized_path(@site.source, file_path)
|
43
|
-
end
|
110
|
+
File.exist? @site.in_source_dir(file_path)
|
44
111
|
end
|
45
112
|
|
46
113
|
# Generates contents for a file
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
114
|
+
|
115
|
+
def make_page(file_path, collection: "posts", category: nil, tags: nil)
|
116
|
+
PageWithoutAFile.new(@site, __dir__, "", file_path).tap do |file|
|
117
|
+
file.content = feed_template
|
118
|
+
file.data.merge!(
|
119
|
+
"layout" => nil,
|
120
|
+
"sitemap" => false,
|
121
|
+
"xsl" => file_exists?("feed.xslt.xml"),
|
122
|
+
"collection" => collection,
|
123
|
+
"category" => category,
|
124
|
+
"tags" => tags
|
125
|
+
)
|
126
|
+
file.output
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Special case the "posts" collection, which, for ease of use and backwards
|
131
|
+
# compatability, can be configured via top-level keys or directly as a collection
|
132
|
+
def normalize_posts_meta(hash)
|
133
|
+
hash["posts"] ||= {}
|
134
|
+
hash["posts"]["path"] ||= config["path"]
|
135
|
+
hash["posts"]["categories"] ||= config["categories"]
|
136
|
+
config["path"] ||= hash["posts"]["path"]
|
137
|
+
hash
|
55
138
|
end
|
56
139
|
end
|
57
140
|
end
|
data/lib/jekyll-feed/meta-tag.rb
CHANGED
@@ -7,14 +7,14 @@ module JekyllFeed
|
|
7
7
|
|
8
8
|
def render(context)
|
9
9
|
@context = context
|
10
|
-
attrs = attributes.map { |k, v| %(#{k}
|
10
|
+
attrs = attributes.map { |k, v| %(#{k}=#{v.encode(:xml => :attr)}) }.join(" ")
|
11
11
|
"<link #{attrs} />"
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def config
|
17
|
-
@context.registers[:site].config
|
17
|
+
@config ||= @context.registers[:site].config
|
18
18
|
end
|
19
19
|
|
20
20
|
def attributes
|
@@ -27,11 +27,7 @@ module JekyllFeed
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def path
|
30
|
-
|
31
|
-
config["feed"]["path"]
|
32
|
-
else
|
33
|
-
"feed.xml"
|
34
|
-
end
|
30
|
+
config.dig("feed", "path") || "feed.xml"
|
35
31
|
end
|
36
32
|
|
37
33
|
def title
|