Content from an RSS feed
Fetch your Medium blog into your own site. In this example we will create pages from an RSS feed.
For this example, we use Medium's RSS feeds to integrate articles as virtual pages into our own site.
To start, we create a parent page, e.g. rssfeed
in the /content
folder and inside it an rssfeed.txt
text file.
Let's give our parent page a title and maybe a short intro.
Title: My virtual feed
----
Intro: This page lists articles from an RSS feed.
Creating the virtual subpages
To fetch the virtual children, we create a new Rssfeed
page model which will read the RSS feed and create a virtual child page for each entry on the fly. The Remote
class is our friend and helps us with handling this remote request.
<?php
use Kirby\Uuid\Uuid;
class RssfeedPage extends Page {
public function children()
{
if ($this->children instanceof Pages) {
return $this->children;
}
$results = [];
$pages = [];
// use the URL of the feed you want to fetch
$request = Remote::get('https://open.nytimes.com/feed');
// if the request was sucessfully, parse feed as $results
if ($request->code() === 200) {
$results = Xml::parse($request->content());
}
// if we have any results, create the child page props for each result
if (count($results) > 0) {
foreach ($results['channel']['item'] as $item) {
$pages[] = [
'slug' => Str::slug($item['title']),
'template' => 'feeditem',
'model' => 'feeditem',
'content' => [
'title' => $item['title'],
'date' => $item['pubDate'] ?? '',
'description' => $item['description'] ?? '',
'link' => $item['link'] ?? '',
'text' => $item['contentencoded'] ?? '',
'categories' => isset($item['category']) ? implode(',', $item['category']) : '',
'author' => $item['dccreator'] ?? '',
'uuid' => Uuid::generate(),
]
];
}
}
// create a Pages collection for the child pages
return $this->children = Pages::factory($pages, $this);
}
}
Unless you have disabled UUIDs in your config, you have to pass a uuid
field in the content array to prevent Kirby from generating the page in the file system when the $page->uuid()
method is called.
If you generate the UUIDs automatically like in the example above, they will change at every load. However, if you want to reference your virtual pages anywhere with their UUID, make sure to use a unique string that does not change.
The template
With this new page model in place, we can now render all feed articles in our rssfeed.php
template as if they were regular Kirby children pages.
<?php snippet('header') ?>
<main>
<header>
<h1><?= $page->title() ?></h1>
</header>
<div class="feed">
<?php foreach ($page->children()->sortBy('date', 'desc') as $item): ?>
<article>
<header class="article-header">
<a href="<?= $item->url() ?>">
<h2><?= $item->title() ?></h2>
<time><?= $item->date()->toDate('d F Y') ?></time>
</a>
</header>
</article>
<?php endforeach ?>
</div>
</main>
<?php snippet('footer') ?>
Subpages
Each article will automatically get its own subpage. Routing will work out of the box and you can create an feeditem.php
template (as we defined above when setting the child page props) to render each individual article.
<?php snippet('header') ?>
<main>
<article class="feedarticle">
<header class="article-header">
<h1><?= $page->title() ?></h1>
<time><?= $page->date()->toDate('d F Y') ?></time>
<?php if ($page->categories()->isNotEmpty()) : ?>
<p class="tags"><?= $page->categories() ?></p>
<?php endif ?>
</header>
<div class="article-body">
<?php if ($page->author()->isNotEmpty()): ?>
<p>by <?= $page->author() ?></p>
<?php endif ?>
<?= $page->text()->excerpt(500) ?>
<a href="<?= $page->link() ?>">Continue reading on Medium</a>
</div>
</article>
</main>
<?php snippet('footer') ?>