Route configuration for RSS pages in multilang

Hi, I’m using @bnomei RSS plugin and so far it’s working great to create my RSS pages.

But I need some help! The problem I have is related to routes and dual language. My default language is French, the second one English and I need a separate RSS feed for each as they don’t present the same content. My (probably very simple) problem is that I can’t nail the syntax needed to filter pages by language in routes. I tried following the docs with the 'language' => 'en' declaration but it only returns a white page. And a basic filterBy didn’t do the trick either.

My current code (without all the tests I did) is:

'routes' => [
      [
          'pattern' => 'fr/feed',
          'method' => 'GET',
          'action'  => function () {
              $options = [
                'title'       => 'Dernières publications',
                'description' => 'Nos dernières publications',
                'link'        => 'fr/feed',
                'datefield'   => 'date',
                'textfield'   => 'text',
                'snippet'     => 'feed/json'
              ];
              $feed = page(['articles', 'podcasts'])
                ->children()
                ->visible()
                  ->sortBy(function ($page) {
                  return $page->date()->toDate();
                  }, 'desc')->feed($options);
              return $feed;
          }
        ],
        [
        'pattern' => 'en/feed' ,
        'method' => 'GET',
        'action'  => function () {
            $options = [
              'title'       => 'Latest articles',
              'description' => 'Read the latest news about our company',
              'link'        => '/en/feed',
              'datefield'   => 'date',
              'textfield'   => 'text',
              'snippet'     => 'feed/json'
            ];

            $feed = page('articles')
                ->children()
                ->visible()
                ->sortBy(function ($page) {
                  return $page->date()->toDate();
                  }, 'desc')
                ->feed($options);
            
            return $feed;
        }
      ]
    ]

Any idea? Thanks.

Since 3.2, you can set a language scope: https://getkirby.com/docs/guide/routing#multi-language-setup. You can use that to filter your pages by language.

Is that what you mean returns a blank page? No error message?

Yes, that’s what I meant. For example I just did:

[
        'pattern' => 'en/feed' ,
        'method' => 'GET',
        'language' => 'en',
        'action'  => function ($language, $slug) {
            $options = [
              'title'       => 'Latest articles',
              'description' => 'Read the latest news about our company',
              'link'        => '/en/feed',
              'datefield'   => 'date',
              'textfield'   => 'text',
              'snippet'     => 'feed/json'
            ];

            $feed = page('articles')
                ->children()
                ->visible()
                ->sortBy(function ($page) {
                  return $page->date()->toDate();
                  }, 'desc')
                ->feed($options);
            
            return $feed;
        }
      ]

And it gives me a blank page, without any error message or anything.

I haven’t really tested the new multilang routes, but as far as I can see, the language code shouldn’t be part of the pattern in this case anymore. Does it make any difference if you remove it?

  'pattern' => 'feed' ,
  'language' => 'en',
   'action'  => function ($language) {

Also, you have only one variable, there is no $slug in your case because the pattern doesn’t use a placeholder.

Nice catch, the blank page is gone and the rss feed is back. But the website.com/en/feed still references french content instead of english. Ex as a json output:

"items": [
{
"id": "https://plainkit.test/fr/articles/test-opinion",
"url": "https://plainkit.test/fr/articles/test-opinion",
"title": "test opinion fr",
"content_html": "",
"date_published": "2019-08-01T00:00:00+00:00",
"date_modified": "2019-08-02T10:12:23+00:00"
}
]

Hm, too bad. I think I need a little test install to figure that out…

@Thomasorus does it work in with kirby debug enabled? if it does then my cache implmentation for the feed plugin does not support multilanguage content yet. i will push a fix asap.

otherwise you might need to forward the language to the $feedcollection, but not sure about that. it would mean the route does not know the current language.

No it does not, debug is enabled on my local work install.

please try with new 1.1.4 again. should be available at packagist (aka composer list) in a few minutes or as zip here:

try vardumping $feed from the fr route. are you sure its the french content?

edited: nevermind you did that with json above.

I can’t test it right now, I’ll give you an update in a few hours. Thanks for your help!

@texnixe question is if the page() get the language from the route, right? sadly the unittests are setup differently.

Hm, before the multilang route changes, you had to use $site->visit() to get the right language version of a page. I haven’t really looked into that too much since. I was assuming that if you use the language key in your route definition that would happen automatically :thinking:

@bnomei I just tried and no luck.

For info my route:

[
        'pattern' => 'feed' ,
        'method' => 'GET',
        'language' => 'en',
        'action'  => function ($language) {
            $options = [
              'title'       => 'Latest articles',
              'description' => 'Read the latest news about our company',
              'link'        => '/en/feed',
              'datefield'   => 'date',
              'textfield'   => 'text',
              'snippet'     => 'feed/json'
            ];

            $feed = page('articles')
                ->children()
                ->visible()
                ->sortBy(function ($page) {
                  return $page->date()->toDate();
                  }, 'desc')
                ->feed($options);
            
            return $feed;
        }
      ]

And the result:

{
  "version": "https://jsonfeed.org/version/1",
  "title": "Latest articles",
  "home_page_url": "https://plainkit.test",
  "feed_url": "https://plainkit.test/en/feed",
  "items": [
    {
      "id": "https://plainkit.test/fr/articles/test-opinion",
      "url": "https://plainkit.test/fr/articles/test-opinion",
      "title": "test opinion fr",
      "content_html": "",
      "date_published": "2019-08-01T00:00:00+00:00",
      "date_modified": "2019-08-02T10:12:23+00:00"
    },
    {
      "id": "https://plainkit.test/fr/articles/test-article",
      "url": "https://plainkit.test/fr/articles/test-article",
      "title": "test article fr",
      "content_html": "",
      "date_published": "2019-07-17T00:00:00+00:00",
      "date_modified": "2019-08-02T10:55:05+00:00"
    },
    {
      "id": "https://plainkit.test/fr/articles/test-article-2",
      "url": "https://plainkit.test/fr/articles/test-article-2",
      "title": "test article 2 fr",
      "content_html": "<p>Lol</p>",
      "date_published": "1970-01-01T00:00:00+00:00",
      "date_modified": "2019-08-02T11:12:35+00:00"
    }
  ]
}

so did i.

This seems to work:

<?php

return [
    'debug' => true,
    'languages' => true,

  
    'routes' => [
        [
            'pattern' => 'feed' ,
            'method' => 'GET',
            'language' => '*',
            'action'  => function ($language) {
                $options = [
                    'en' => [
                        'title'       => 'Latest articles',
                        'description' => 'Read the latest news about our company',
                        'link'        => '/en/feed',
                        'datefield'   => 'date',
                        //'textfield'   => 'text',
                        'snippet'     => 'feed/json'
                    ],
                    'fr' => [
                        'title'       => 'Dernier articles',
                        'description' => 'Nos dernières publications',
                        'link'        => '/fr/feed',
                        'datefield'   => 'date',
                        'textfield'   => 'text',
                        'snippet'     => 'feed/json'
                    ]
                ];
                site()->visit(page(), $language->code());
                $feed = page('notes')
                    ->children()
                    ->visible()
                    ->filter(function ($page) use($language) {
                        return $page->translation($language->code())->exists(); 
                    })
                    ->sortBy(function ($page) {
                      return $page->date()->toDate();
                      }, 'desc')
                    ->feed($options[$language->code()]);
                
                return $feed;
            }
          ]
    ]
];
1 Like

Thanks @texnixe it’s working!

1 Like