Jungle Ran

Blog/Bloglet about Drupal, Ops, and mORe

Build a valid RSS feed for Planet Drupal

Submitted by jungle on Sun, 02/09/2020 - 00:18

Since joining Planet Drupal in 2016, no seriously new blog posts for a long time. Last year, my personal site was rebuilt with Drupal 8 again. And a few months ago, I found my feed was removed from Planet Drupal. Recently, I wanted to join in it again. The first task is to make a valid RSS. This is the background.

Suggestions from How to get your feed to the Planet

If your site uses Drupal, you can create a "Drupal Planet" taxonomy term and use it to tag any content you want to appear on the Planet. Drupal automatically creates an RSS feed for each taxonomy term, and you can submit that term’s feed URL in your Drupal Planet application. Alternatively, you can use the Drupal Planet feature module, which uses Flag and Views modules to create the feed. If you are not using Drupal, you will need to make sure your site can create a feed just for your Planet content.

Using Planet content is inapplicable as it has no Drupal 8 release.

Previously, my feed had the term "Drupal Planet" exactly, and I did submit http://ranqiangjun.com/taxonomy/term/1/feed. This time I want to avoid using the term, instead, creating a content type Planet Drupal and a View Planet Drupal to provide an RSS feed,

Content type: Planet Drupal

Creating content type called Planet Drupal (machine name: planet_drupal) with a body filed. nothing fancy here.

View: Planet Drupal

Add a view Planet Drupal (machine name: planet_drupal) with a page display and a feed display

For the page display, it's free to make it whatever you want it to be, let's focus on the feed display

Feed display

  1. TITLE
  2. Title:Planet Drupal
  3. FORMAT
  4. Format:RSS Feed | Settings
  5. Show:Fields | Settings
  6. FIELDS
  7. Content: Title
  8. Content: Authored by [hidden]
  9. Content: Authored on [hidden]
  10. Content: Body [hidden]
  11. Content: Link to Content [hidden]
  12. Content: UUID [hidden]
  13. ...
  14. FEED SETTINGS
  15. Path:/planet.xml
  16. Attach to:Page

For the fields added

  • Title, remember uncheck Link to the Content
  • Authored by, Formatter: label, unchecked Link label to the referenced entity
  • Authored on, Date format: Custom, Custom date format: r, here is important. It should be a RFC 2822 formatted date. r is the proper format character.
  • Body, Formatter: Summary or Trimmed, Trimmed limit: 600 characters
  • Link to Content, Check Output the URL as text, Checked or unchecked Use absolute link (begins with "http://") are both ok.
  • UUID, we know UUID is unique, it's used as the GUID in feed. by default no formmater for UUID field type, but there is a module called uuid_extra which provides an UUID formatter, so install it, and choose Formatter: UUID.

Next mapping the fields to feed fields

  • Title field <-- Content: Title
  • Link field <-- Content: Link to Content
  • Description field <-- Content: Body
  • Creator field <-- Content: Authored by
  • Publication date field <-- Content: Authored on
  • GUID field <-- Content: UUID, and uncheck GUID is permalink

So far so good, let's check if our feed is valid. Go to W3C Feed Validation Service and submit

Bingo, it's valid, but it complains

Let's fix it.

By checking https://dri.es/taxonomy/term/1/feed, which is a valid feed. it contains only one namespace xmlns:dc="http://purl.org/dc/elements/1.1/, so let's only keep the one. And fix Missing atom:link with rel="self" needs adding one namespace and inserting a atom:link to your feed in the channel section

Solution: If you haven't already done so, declare the Atom namespace at the top of your feed, thus: Then insert a atom:link to your feed in the channel section. Below is an example to get you started. Be sure to replace the value of the href attribute with the URL of your feed.

So our solution would be alteing the namespaces inside the implementation of template_preprocess_views_view_rss, and adding a new variable called feed_url as the href of the atom:link tag being inserted. let's assume we have a theme called planet

Inside planet.theme file, add the implementation of hook_preprocess_views_view_rss

  1. /**
  2.  * Implements hook_preprocess_HOOK().
  3.  */
  4. function planet_preprocess_views_view_rss(&$variables) {
  5. /** @var \Drupal\views\ViewExecutable $view */
  6. $view = $variables['view'];
  7. if ($view->current_display === 'feed_1' && $view->id() === 'planet_chinese') {
  8. // Provide a new variable for the custom template.
  9. $display = $view->getDisplay();
  10. $variables['feed_url'] = $display->getUrl()->setAbsolute()->toString();
  11. // Alter namespaces.
  12. $style = $view->getStyle();
  13. $style->namespaces = array_filter( $style->namespaces, function ($key) {
  14. return $key === 'xmlns:dc';
  15. }, ARRAY_FILTER_USE_KEY);
  16. $style->namespaces['xmlns:atom'] = 'http://www.w3.org/2005/Atom';
  17. $variables['namespaces'] = new Attribute($style->namespaces);
  18. }
  19. }

Copy the views-view-rss.html.twig from core/modules/views/templates into the planet theme's templates folder and insert the atom:link tag inside channel.

  1. ...
  2. <channel>
  3. {% if feed_url %} <atom:link href="{{ feed_url }}" rel="self" type="application/rss+xml" /> {% endif %}
  4. ...

PS

©2020 ranqiangjun.com. All rights reserved.