There are a couple of things I don’t like with the feeds produced by the standard Grav Syndication Feed Plugin. Fortunately, the feeds are generated via Twig templates that can easily be customized!
Issue
I’ve setup my blog so that each page starts with a summary section that ends with ===
. Check your Grav Configuration > Site > Page Summary to confirm it is enabled. If you do not have a summary section, then best you stop reading!
Anyway, I don’t like that the plugin generates feeds that comprise:
- A fixed number of characters from the blog page (the “Feed Length” configuration in the screenshot below) - I would rather the feed contain just the summary.
- Images - I would rather not have images or links to images in the feed! Alas, there is no configuration to change this behaviour.
The Feed Plugin configuration:
Fix
As mentioned, changing the feed output is simply overriding three Twig templates in the folder user/plugins/feed/templates
:
feed.atom.twig
feed.json.twig
feed.rss.twig
To override these files, copy them to your active theme’s templates
folder folder, and then edit each file to:
- Replace
item.content
withitem.summary
. - Comment out or delete lines pertaining to the
banner
andimage
variables.
BTW, I also implemened a “Read more...” link - this is easy and I leave this as an excertise for the reader!
For feed.rss.twig
and, similarly, feed.rss.twig
, edit the [CDATA[...]]
section:
{% set collection = collection|default(page.collection) %}
{% set lastBuildDate = 0 %}
{% for page in collection %}
{%- set lastBuildDate = max(lastBuildDate, page.date) %}
{%- if collection.params.show_last_modified %}
{%- set lastBuildDate = max(feed_updated, page.modified) %}
{%- endif %}
{% endfor %}
<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
<title>{{ collection.params.title }}</title>
<link>{{ page.url(true) }}</link>
<atom:link href="{{ uri.rootUrl(true)~uri.uri() }}" rel="self" type="application/rss+xml"/>
<description>{{ collection.params.description }}</description>
<language>{{ grav.language.getLanguage|default(config.system.language.default_lang)|default('en') }}</language>
<lastBuildDate>{{ lastBuildDate|date('D, d M Y H:i:s O') }}</lastBuildDate>
{% for item in collection %}
{% set banner = item.media.images|first %}
<item>
<title>{{ item.title|e }}</title>
<link>{{ item.url(true) }}</link>
<guid>{{ item.url(true) }}</guid>
<pubDate>{{ item.date|date('D, d M Y H:i:s O') }}</pubDate>
<description>
<![CDATA[
{#
{% if banner %}
{{ banner.cropZoom(1200,800).html|absolute_url|raw }}
{% endif %}
{{ item.content|safe_truncate_html(collection.params.length)|raw }}
#}
{{ item.summary|safe_truncate_html(collection.params.length)|raw }}
]]>
</description>
{% for tag in item.taxonomy.tag %}
<category>{{ tag|e }}</category>
{% endfor %}
</item>
{% endfor %}
</channel>
</rss>
While for feed.json.twig
, edit the"content_html": item.content
line and the set image
section. I noticed the current version of the plugin does not use the banner
variable, so feel free to comment it out as well:
{# Format specification: https://www.jsonfeed.org/version/1/ #}
{% set collection = collection|default(page.collection) %}
{% set jsonfeed = {
"version" : "https://jsonfeed.org/version/1",
"title": collection.params.title,
"home_page_url": page.url(true),
"feed_url": uri.rootUrl(true)~uri.uri(),
"description": collection.params.description,
"author": {"name": site.author.name}
} %}
{% set itemList = [] %}
{% for item in collection %}
{%- set post = {
"title": item.title|e,
"date_published": item.date|date('Y-m-d\\TH:i:sP'),
"id": item.url(true),
"url": item.url(true),
"content_html": item.summary|safe_truncate_html(collection.params.length)
} %}
{#
{% set banner = item.media.images|first %}
#}
{% if item.header.metadata.description %}
{%- set post = post|merge({"summary": item.header.metadata.description|e}) %}
{% endif %}
{% if collection.params.show_last_modified %}
{%- set post = post|merge({"date_modified": item.modified|date('Y-m-d\\TH:i:sP')}) %}
{% endif %}
{% if item.taxonomy.tag %}
{%- set post = post|merge({"tags": item.taxonomy.tag}) %}
{% endif %}
{#
{% set image = item.media.images|first %}
{% if image %}
{%- set post = post|merge({"image": image.url(true)}) %}
{% endif %}
#}
{%- set itemList = itemList|merge([post]) %}
{% endfor %}
{% set jsonfeed = jsonfeed|merge({"items": itemList}) %}
{{- jsonfeed|json_encode|raw }}
It’s a good idea validate the feeds produced, for example, using the W3C Feed Validation Service and JSON Linter.
This method will work if you would like to make other changes to the feed template.