Автоматическая генерация RSS лент в приложении Laravel

Источник: «Automatically generate RSS feeds in a Laravel application»
Одним из удобных способов информирования пользователей о ваших материалах является создание RSS-канала. Это позволит им подписываться на него с помощью программы чтения RSS. Усилия, затраченные на реализацию этой функции, стоят того, чтобы принять во внимание, поскольку у сайта появится ещё один канал распространения контента.

Компания Spatie известна тем, что создала сотни хороших пакетов для Laravel. Одним из них является laravel-feed. Давайте посмотрим, как он работает:

Установка laravel-feed

Первым шагом является установка пакета в ваше приложение Laravel:

composer require spatie/laravel-feed

Затем необходимо опубликовать файл конфигурации:

php artisan vendor:publish --provider="Spatie\Feed\FeedServiceProvider" --tag="feed-config"

Использование laravel-feed

Давайте разберём возможности при настройке канала.

Создание каналов

В конфигурационном файле есть ключ feeds, содержащий массив, в котором каждый элемент представляет собой новую ленту, а ключом является название ленты.

Давайте создадим ленту для записей нашего блога:

app/config/feed.php:

return [
'feeds' => [
'blog-posts' => [
//...
],
'another-feed' => [
//...
]
]
];

Ключ blog-posts также является именем фида, в котором его значение содержит конфигурацию в виде массива. При необходимости можно создать и другие фиды, но в рамках данной статьи остановимся на blog-posts.

При этом, чтобы наша модель работала, нам необходимо реализовать интерфейс Spatie\Feed\Feedable. В нем есть сигнатура для публичного метода toFeedItem, который должен возвращать экземпляр Spatie\Feed\FeedItem.

Ниже приведён пример создания объекта FeedItem:

app/Models/BlogPost.php:

use Illuminate\Database\Eloquent\Model;
use Spatie\Feed\Feedable;
use Spatie\Feed\FeedItem;

class BlogPost extends Model implements Feedable
{
//...
public function toFeedItem(): FeedItem
{
return FeedItem::create()
->id($this->id)
->title($this->title)
->summary($this->summary)
->updated($this->updated_at)
->link(route('blog-posts.show', $this->slug))
->authorName($this->author->name)
->authorEmail($this->author->email);
}
}

Теперь мы должны создать класс со статическим методом, возвращающий коллекцию объектов App\Models\BlogPost:

app/Feed/BlogPostFeed.php:

namespace App\Feed;

use App\Models\BlogPost;
use Illuminate\Database\Eloquent\Collection;

class BlogPostFeed
{
public static function getFeedItems(): Collection
{
return BlogPost::all();
}
}

Вернёмся к нашему файлу конфигурации, первым ключом для конфигурации нашей ленты являются items, которые определяют, откуда получать коллекцию постов.

app/config/feed.php:

 return [
'feeds' => [
'blog-posts' => [
+ 'items' => [App\Feed\BlogPostFeed::class, 'getFeedItems']
//...
],
]
];

Затем необходимо задать URL:

app/config/feed.php:

 return [
'feeds' => [
'blog-posts' => [
'items' => [App\Feed\BlogPostFeed::class, 'getFeedItems'],
+ 'url' => '/posts', //https://domain.com/posts
//...
],
]
];

Зарегистрируйте маршруты с помощью макроса feeds, входящего в комплект поставки:

app/routes/web.php:

Route::feeds();  //https://domain.com/posts

Если вы хотите добавить префикс:

app/routes/web.php:

Route::feeds('rss'); //https://domain.com/rss/posts

Далее необходимо добавить title, description и language:

app/config/feed.php:

 return [
'feeds' => [
'blog-posts' => [
'items' => [App\Feed\BlogPostFeed::class, 'getFeedItems'],
'url' => '/posts',
+ 'title' => 'My feed',
+ 'description' => 'The description of the feed.',
+ 'language' => 'en-US',
//...
],
]
];

Вы также можете определить формат ленты и представление, которое будет её отображать. Допустимыми значениями являются RSS, atom или JSON:

app/config/feed.php:

 return [
'feeds' => [
'blog-posts' => [
'items' => [App\Feed\BlogPostFeed::class, 'getFeedItems'],
'url' => '/posts',
'title' => 'My feed',
'description' => 'The description of the feed.',
'language' => 'en-US',
+ 'format' => 'rss',
+ 'view' => 'feed::rss',
//...
],
]
];

Существует несколько дополнительных опций:

/*
* Изображение, которое будет отображаться для фида. Для Atom-каналов оно отображается как
* баннер/логотип; для RSS- и JSON-лент оно отображается в виде иконки.
* Пустое значение исключает атрибут image из ленты.
*/

'image' => '',

/*
* Тип mime, который будет использоваться в теге <link>. Устанавливается в пустую строку для
* автоматического определения правильного значения.
*/

'type' => '',

/*
* Тип содержимого для ответа фида. Устанавливается в пустую строку для автоматического
* определения правильного значения.
*/

'contentType' => '',

Итоговый результат работы конфигурационного файла должен выглядеть следующим образом:

app/config/feed.php:

return [
'feeds' => [
'blog-posts' => [
'items' => [App\Feed\BlogPostFeed::class, 'getFeedItems'],
'url' => '/posts',
'title' => 'My feed',
'description' => 'The description of the feed.',
'language' => 'en-US',
'format' => 'rss',
'view' => 'feed::rss',
'image' => '',
'type' => '',
'contentType' => '',
],
]
];

Автоматическое создание ссылок на фиды

Читатели обнаруживают ленту, ища тег в разделе head ваших HTML-документов:

<link rel="alternate" type="application/atom+xml" title="News" href="/rss/posts">

Добавьте это в <head>:

@include('feed::links')

В качестве альтернативы можно использовать имеющийся компонент blade:

<x-feed-links />

Заключение

В этой статье вы узнали, как легко добавить RSS-канал на свой сайт с помощью пакета laravel-feed от компании Spatie.

Дополнительные материалы

Предыдущая Статья

Фильтрация типов значений TypeScript

Следующая Статья

Как использовать CSS aspect-ratio