Реализация RSS и Atom подписки на контент
RSS и Atom-фиды позволяют читателям подписываться на обновления через агрегаторы (Feedly, Inoreader, Reeder). Фиды также используются агрегаторами новостей и SEO-инструментами для индексации свежего контента.
Laravel: RSS фид
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Cache;
class FeedController extends Controller
{
public function rss(): Response
{
$feed = Cache::remember('rss_feed', 900, fn() => $this->buildRss()); // 15 минут
return response($feed, 200)->header('Content-Type', 'application/rss+xml; charset=utf-8');
}
private function buildRss(): string
{
$articles = Article::published()
->latest('published_at')
->limit(50)
->get();
$lastBuild = $articles->first()?->published_at ?? now();
return view('feeds.rss', compact('articles', 'lastBuild'))->render();
}
public function atom(): Response
{
$feed = Cache::remember('atom_feed', 900, fn() => $this->buildAtom());
return response($feed, 200)->header('Content-Type', 'application/atom+xml; charset=utf-8');
}
}
<!-- resources/views/feeds/rss.blade.php -->
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
<channel>
<title>{{ config('app.name') }}</title>
<link>{{ url('/') }}</link>
<description>{{ config('app.description') }}</description>
<language>ru</language>
<lastBuildDate>{{ $lastBuild->toRssString() }}</lastBuildDate>
<atom:link href="{{ route('feed.rss') }}" rel="self" type="application/rss+xml"/>
<image>
<url>{{ url('/logo.png') }}</url>
<title>{{ config('app.name') }}</title>
<link>{{ url('/') }}</link>
</image>
@foreach($articles as $article)
<item>
<title><![CDATA[{{ $article->title }}]]></title>
<link>{{ route('articles.show', $article->slug) }}</link>
<guid isPermaLink="true">{{ route('articles.show', $article->slug) }}</guid>
<pubDate>{{ $article->published_at->toRssString() }}</pubDate>
<author>{{ $article->author->email }} ({{ $article->author->name }})</author>
<description><![CDATA[{{ $article->excerpt }}]]></description>
@if($article->cover_image)
<media:content url="{{ $article->cover_url }}" medium="image"/>
@endif
@foreach($article->tags as $tag)
<category>{{ $tag->name }}</category>
@endforeach
</item>
@endforeach
</channel>
</rss>
Маршруты и autodiscovery
// routes/web.php
Route::get('/feed', [FeedController::class, 'rss'])->name('feed.rss');
Route::get('/feed/atom', [FeedController::class, 'atom'])->name('feed.atom');
Route::get('/feed/{category}', [FeedController::class, 'category'])->name('feed.category');
<!-- В <head> для автообнаружения браузером и агрегаторами -->
<link rel="alternate" type="application/rss+xml" title="{{ config('app.name') }} RSS" href="{{ route('feed.rss') }}">
<link rel="alternate" type="application/atom+xml" title="{{ config('app.name') }} Atom" href="{{ route('feed.atom') }}">
Срок реализации
RSS + Atom фид с кэшированием и autodiscovery для Laravel: 0.5–1 день. С фидами по категориям/тегам и категоризацией: 1–2 дня.







