Kirby3 Feed - RSS/JSON/Sitemap

I am creating posts for my plugins to make it easier to find them using the forum search and not just the docs search.

Generate a RSS/JSON/Sitemap-Feed from a Pages-Collection.

site/config/config.php

return [
    'routes' => [
        [
            'pattern' => 'feed',
            'method' => 'GET',
            'action'  => function () {
                $options = [
                    'title'       => 'Latest articles',
                    'description' => 'Read the latest news about our company',
                    'link'        => 'blog'
                ];
                $feed = page('blog')->children()->listed()->flip()->limit(10)->feed($options);
                return $feed;
            }
        ],
        [
            'pattern' => 'sitemap.xml',
            'method' => 'GET',
            'action'  => function () {
                $options = [
                    'images'       => false,
                    'videos'       => false,
                ];
                $feed = site()->index()->listed()->limit(50000)->sitemap($options);
                return $feed;
            }
        ],
    ],
];

Thanks for your plugin!
How can I have two feeds: one for de and one for en on a bilingual website?

you can define different routes with an explicit language scope.

the page('blog') will have loaded content from that language then.

in your header where you define the link to the rss you need to make sure it is link the that route. but i guess using site()->url() . '/feed' should work.

I tried it with

<a href="<?php echo $kirby->language()->code() . '/rss'; ?>"

and this route but still everything is being shown:

      [
        'pattern' => 'en/rss',
        'method' => 'GET',
        'action'  => function () {
            $options = [
                'title'       => 'Pelekes Blog',
                'description' => 'Die letzten Artikel von Pelekes Blog',
                'link'        => 'blog'
            ];
            $feed = page('blog')->children()->listed()->filter(function ($child) {
              return $child->translation(kirby()->language()->code('en'))->exists();
              })->flip()->feed($options);
            return $feed;
        }
      ],

Any idea what is missing?

  [
        'pattern' => 'rss', // <----------
        'language' => 'en', // <----------
        'method' => 'GET',
        'action'  => function ($language) {
            $options = [
                'title'       => 'Pelekes Blog',
                'description' => 'Die letzten Artikel von Pelekes Blog',
                'link'        => 'blog'
            ];
            $feed = page('blog')->children()->listed()->filter(function ($child) {
              return $child->translation(kirby()->language()->code('en'))->exists();
              })->flip()->feed($options);
            return $feed;
        }
      ],

Thanks, that works for the filtering but then it shows only the German content in the feed and not the English version of it. What is missing to show the English content instead?

What I am wondering about is that it shows the german content, while you filter only for english…

Anyway - I am using the same plugin but with these settings:

'language' => '*',

and in the filter:

return $child->translation(kirby()->language()->code())->exists();

And the blog pages are shown in german or english depending on the language choosen by the visitor.

2 Likes

Thanks for the hint, that did the trick :slight_smile:
Now I only have to find out a way to show a translated description for that or just use a short name that doesn’t need to be translated…

You could set the title and description in the blog page for each language, then fetch these in the correct language in your route, e.g.

'description' => page('blog')->content('en')->get('rssdescription'),

For me, this is working without the ->content('en') part:

'title'       => page('blog')->title(),
'description' => page('blog')->description(),

It works with the title but not with the description (in my case called “text”), which just stays empty while I can access it in a template via <?= $page->text() ?>:

      [
        'pattern' => 'rss',
        'language' => '*',
        'method' => 'GET',
        'action'  => function () {
            $options = [
                'title'       => page('blog')->title(),
                'description' => page('blog')->text(),
                'link'        => 'blog'
            ];
            $feed = page('blog')->children()->listed()->filter(function ($child) {
              return $child->translation(kirby()->language()->code())->exists();
              })->flip()->feed($options);
            return $feed;
        }
      ],
title: Blog
icon: layers

tabs:
  blog:
    label: Inhalt
    icon: text
    columns:
      left:
        width: 1/4
        sections:
          meta:
            type: fields
            fields:
              text: 
                type: text
                label: Beschreibung

The original snippet is very strict and checks if the value is a string, so use

page('blog')->text()->value(),
1 Like

That worked, thank you!

Hi
I’m using your plugin to make a sitemap but most of my images are stored inside the site folder, and images are not indexed. On my homepage template, every images are coming from this folder. How to resolve this ?

the plugin uses the imagesfield option to find the images.

'imagesfield' => 'images',

you could create a custom page method to let the sitemap know where your image assets are located.

why are you storing the images in site and not the content folder?