Skip to content
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Jekyll Feed plugin

A Jekyll plugin to generate an Atom (RSS-like) feed of your Jekyll posts
A Jekyll plugin to generate an Atom (RSS-like) feed and a [JSON feed](https://jsonfeed.org/version/1) of your Jekyll posts

[![Build Status](https://travis-ci.org/jekyll/jekyll-feed.svg)](https://travis-ci.org/jekyll/jekyll-feed) [![Gem Version](https://badge.fury.io/rb/jekyll-feed.svg)](https://badge.fury.io/rb/jekyll-feed)

Expand All @@ -21,7 +21,7 @@ gems:

## Usage

The plugin will automatically generate an Atom feed at `/feed.xml`.
The plugin will automatically generate an Atom feed at `/feed.xml` and a [JSON feed](https://jsonfeed.org/) at `/feed.json`.

### Optional configuration options

Expand All @@ -39,6 +39,7 @@ Do you already have an existing feed someplace other than `/feed.xml`, but are o
```yml
feed:
path: atom.xml
json_path: json_feed.json
```

To note, you shouldn't have to do this unless you already have a feed you're using, and you can't or wish not to redirect existing subscribers.
Expand Down
72 changes: 72 additions & 0 deletions lib/jekyll-feed/feed.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"version": "https://jsonfeed.org/version/1",
{% assign site_title = site.title | site.name %}
{% if site_title %}
"title": {{ site_title | smartify | json }},

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i can't find json filter there https://jekyllrb.com/docs/templates/ may be jsonify

{% endif %}
{% if site.description %}
"description": {{ site.description | json }},
{% endif %}
"home_page_url": "{{ '/' | absolute_url }}",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why just not {{ absolute_url }}?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

absolute_url is a filter not a value. It needs something as input.

"feed_url": "{{ page.url | absolute_url }}",
"icon": "{{ "/apple-touch-icon.png" | absolute_url }}",
"favicon": "{{ "/favicon.ico" | absolute_url }}",
"expired": false,
{% if site.author %}
"author": {
"name": {{ site.author.name | default: site.author | json }},
{% if site.author.uri %}
"url": {{ site.author.uri | json }}
{% endif %}
},
{% endif %}
"items": [
{% assign posts = site.posts | where_exp: "post", "post.draft != true" %}
{% for post in posts limit: 10 %}
{
"id": {{ post.id | absolute_url | json }},
"url": "{{ post.url | absolute_url }}",
"title": {{ post.title | smartify | strip_html | normalize_whitespace | json }},
{% if post.excerpt and post.excerpt != empty %}
{% assign post_summary = post.excerpt | strip_html | normalize_whitespace | json %}
"content_html": {{ post_summary }},

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think content_html should have a full content of post

"summary": {{ post_summary }},
{% endif %}
{% assign post_image = post.image.path | default: post.image %}
{% if post_image %}
{% unless post_image contains "://" %}
{% assign post_image = post_image | absolute_url | xml_escape %}
{% endunless %}
"image": "{{ post_image }}",
{% endif %}
"date_published": "{{ post.date | date_to_xmlschema }}",
"date_modified": "{{ post.last_modified_at | default: post.date | date_to_xmlschema }}",
{% assign post_author = post.author | default: post.authors[0] %}
{% if post_author %}
{% assign post_author = site.data.authors[post_author] | default: post_author %}
{% assign post_author_uri = post_author.uri | default: nil %}
{% assign post_author_name = post_author.name | default: post_author %}
"author": {
{% if post_author_name %}
"name": {{ post_author_name | json }},
{% endif %}
{% if post_author_uri %}
"url": {{ post_author_uri | json }}
{% endif %}
},
{% endif %}
{% if post.enclosure %}
"attachments": [
{
"url": "{{ post.enclosure }}",
"mime_type": "{{ post.enclosure_type }}",
"size_in_bytes": "{{ post.enclosure_length }}"
}
],
{% endif %}
"tags": {{ post.tags | jsonify }}
}
{% unless forloop.last %},{% endunless %}
{% endfor %}
]
}
41 changes: 37 additions & 4 deletions lib/jekyll-feed/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ class Generator < Jekyll::Generator
# Main plugin action, called by Jekyll-core
def generate(site)
@site = site
return if file_exists?(feed_path)
@site.pages << content_for_file(feed_path, feed_source_path)

return if file_exists?(feed_path) && file_exists?(json_feed_path)
@site.pages << xml_content_for_file(feed_path, feed_source_path)
@site.pages << json_content_for_file(json_feed_path, feed_json_source_path)
end

private
Expand All @@ -27,11 +29,25 @@ def feed_path
end
end

# Path to JSON feed from config, or feed.json for default
def json_feed_path
if @site.config["feed"] && @site.config["feed"]["json_path"]
@site.config["feed"]["json_path"]
else
"feed.json"
end
end

# Path to feed.xml template file
def feed_source_path
File.expand_path "./feed.xml", File.dirname(__FILE__)
end

# Path to feed.json template file
def feed_json_source_path
File.expand_path "./feed.json", File.dirname(__FILE__)
Copy link

@bogdanvlviv bogdanvlviv Jun 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File.expand_path("feed.xml", __dir__)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The feed_source_path function used that same format and I just changed the file path. Please note that I don't know any Ruby and I might be wrong.

end

# Checks if a file already exists in the site source
def file_exists?(file_path)
if @site.respond_to?(:in_source_dir)
Expand All @@ -42,14 +58,31 @@ def file_exists?(file_path)
end

# Generates contents for a file
def content_for_file(file_path, file_source_path)
def content_for_file(file_path, file_source_path, regex)
file = PageWithoutAFile.new(@site, File.dirname(__FILE__), "", file_path)
file.content = File.read(file_source_path).gsub(MINIFY_REGEX, "")
content = File.read(file_source_path)

if regex
content = content.gsub(regex, "")
end

file.content = content
file.data["layout"] = nil
file.data["sitemap"] = false
file
end

def xml_content_for_file(file_path, file_source_path)
file = content_for_file(file_path, file_source_path, MINIFY_REGEX)
file.data["xsl"] = file_exists?("feed.xslt.xml")
file.output
file
end

def json_content_for_file(file_path, file_source_path)
file = content_for_file(file_path, file_source_path, nil)
file.output
file
end
end
end