Creating an Array for RSS

Is there a way to show children and grandchildren inside an RSS Feed? My theory is that I can use either filterby() and use templates, or somehow create an array before creating an RSS Feed, but I don’t know how to structure the actual RSS Template. I’ll put this here, because it shows everything I am trying to accomplish (even though I’m sure it’s completely wrong), but hopefully this makes sense to someone! :smile:

<?php
    $posts_a = $site->find('blog')->children();
    $posts_b = $site->find('portfolio')->children();
    $posts_c = $site->find('portfolio')->grandchildren();
    $posts = new Pages(array($posts_a, $posts_b, $posts_c));
    $posts = $posts->visible()->flip()->filterBy('template', '!=', 'project.page')->limit(10);
?>

<?php
    echo $posts->feed(array(
    'title'       => $page->title(),
    'description' => $page->description(),
    'link'        => 'blog',
    ));
?>

For a little more background, I am creating a portfolio that has two template types, portfolio.single and portfolio.page (which can have more projects nested). I only want portfolio.single and posts from the blog to show in the main RSS Feed.

Looks ok to me. The code to get the collection can be a bit shorter, though:

<?php
    $posts_a = page('blog')->children()->visible();
    $posts_b = page('portfolio')->index()->visible()->filterBy('template', 'project.single');
    $posts = new Pages(array($posts_a, $posts_b));
    $posts = $posts->flip()->limit(10);
?>

Maybe you should also sort the collection (by date) before flipping and limiting …

That didn’t seem to work alone, but the following seems to have done the trick. Is there anything here that looks concerning?

<?php
    $posts_a = page('blog')->children()->visible();
    $posts_b = page('portfolio')->index()->visible()->filterBy('template', 'project.single');
    $posts = new Pages(array($posts_a, $posts_b));
    $posts = $posts->sortBy('date', 'desc', 'time', 'desc')->limit(10);

echo $posts->feed(array(
      'title'       => $page->title(),
      'description' => $page->description(),
      'link'        => 'blog',
));
?>

Thanks for helping clean-up the code – I’m learning more and more everyday!

Well, yes, you need the second code block as well, I just copied the relevant part.

Is the link in the feed array correct? Maybe in your case it would make more sense to access the feed on the first level, not below blog, because you combine stuff from multiple pages? But that is of course up to you.

1 Like

For some reason the sorting by Time is being ignored. I tried the solution here (https://forum.getkirby.com/t/kirby-gets-the-date-right-but-not-the-time/1553/4), but nothing seems to have changed. Any thoughts?

adding 'timefield' => 'time', to the plugin’s feed.php file, and changing the <pubDate>… to:

<pubDate><?php echo $datefield == 'modified' ? $item->modified('D, d M Y') : $item->date('D, d M Y', $datefield) ?> <?php echo $timefield == 'modified' ? $item->modified('H:i:s O') : $item->time('H:i:s O', $timefield) ?></pubDate>

Since you sort the posts before calling the $posts->feed() method, the issue shouldn’t be in the feed plugin. The change you made only refers to the feed output.

Have you verified that your time field is actually called time? Also, please note that the times are compared as strings, they are not parsed as actual time values, which generally makes the sorting behave in a strange way. It should work though if you use 24 hour times and add zeros to one-digit values (09:01 for example).

There’s also another possible issue. I had a look at the feed plugin and the items are again sorted within the plugin (if only by date). So maybe they should not be sorted before …

Feed.php line 30:

 $items = $pages->sortBy($options['datefield'], 'desc');

… or that line omitted, or the sorting by time added.

1 Like

I checked all of the content files, and all of the times are using a 4-digit 24-hour string. Removing line 30 seems to break the feed, and adding another string for time doesn’t seem to change anything.

// sort by date
$items = $pages->sortBy($options['datefield'], 'desc');
$items = $pages->sortBy($options['timefield'], 'desc');

Strange because all of the posts on the site are ordered correctly. The feed seems to be sorting by date and then sorting by the post number for children.

Update: Because I’ve been trying to figure out the time issue, I went around to see how things are ordered currently in the content folder. The latest posts are ordered as followed:

11.3    6/14    03:00    Consolidating…
09.2    6/13    20:00    DFD's Website
11.1    6/13    04:35    Crafting…
09.1    6/13    02.05    Branding…
28      6/12    12:45    President…
11.2    6/12    00:20    Recording…
10      6/11    10:45    Simple Verdict…

However, in the RSS Feed, the same posts are ordered:

11.3    6/14    03:00    Consolidating…
09.1    6/13    02.05    Branding…
09.2    6/13    20:00    DFD's Website
11.1    6/13    04:35    Crafting…
11.2    6/12    00:20    Recording…
28      6/12    12:45    President…

and 10.0 is replaced with

27      6/11    17:40     Devote…

The left-most number corresponds to the content folder number.

Yeah, of course completely omitting that line is not such a great idea, because then$items is not defined anymore.

Could you try this:

$items = $pages->sortBy($options['datefield'], 'desc', $options['timefield'], 'desc');
1 Like

You are a saint! That did the trick!! For anyone else who reads this, here are the pieces altered:

Use a variation of this for your feed.php template:

<?php
    $posts_a = page('blog')->children()->visible();
    $posts_b = page('portfolio')->index()->visible()->filterBy('template', 'project.single');
    $posts = new Pages(array($posts_a, $posts_b));

    echo $posts->sortBy('date', 'desc')->limit(10)->feed(array(
        'title'       => $page->title(),
        'description' => $page->description(),
        'link'        => 'feed',
    ));
?>

In the plugin’s feed.php add the following after Line 30:

'timefield'   => 'time',

Change // sort by date to:

$items = $pages->sortBy($options['datefield'], 'desc', $options['timefield'], 'desc');

And it seems you do not have to alter the <pubdate>… in the plugin’s template.php file after all.