Skip to content

Commit 548abde

Browse files
fetzijoedixon
authored andcommitted
Add RSS Feed for forum
add spatie/laravel-feed for RSS feed generation fixes #339
1 parent 50d480b commit 548abde

File tree

8 files changed

+95
-6
lines changed

8 files changed

+95
-6
lines changed

app/Models/Thread.php

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
namespace App\Models;
44

55
use App\Exceptions\CouldNotMarkReplyAsSolution;
6-
use App\Helpers\HasAuthor;
76
use App\Helpers\HasSlug;
87
use App\Helpers\HasTags;
9-
use App\Helpers\HasTimestamps;
8+
use Spatie\Feed\Feedable;
9+
use Spatie\Feed\FeedItem;
10+
use App\Helpers\HasAuthor;
1011
use App\Helpers\ModelHelpers;
11-
use App\Helpers\ProvidesSubscriptions;
12+
use App\Helpers\HasTimestamps;
13+
use Illuminate\Support\Carbon;
1214
use App\Helpers\ReceivesReplies;
15+
use App\Helpers\ProvidesSubscriptions;
1316
use DB;
1417
use Exception;
1518
use Illuminate\Contracts\Pagination\Paginator;
@@ -19,12 +22,14 @@
1922
use Illuminate\Database\Eloquent\Relations\BelongsTo;
2023
use Illuminate\Support\Str;
2124

22-
final class Thread extends Model implements ReplyAble, SubscriptionAble
25+
final class Thread extends Model implements ReplyAble, SubscriptionAble, Feedable
2326
{
2427
use HasAuthor, HasSlug, HasTimestamps, ModelHelpers, ProvidesSubscriptions, ReceivesReplies, HasTags;
2528

2629
const TABLE = 'threads';
2730

31+
const FEED_PAGE_SIZE = 20;
32+
2833
/**
2934
* {@inheritdoc}
3035
*/
@@ -109,6 +114,19 @@ public function delete()
109114
parent::delete();
110115
}
111116

117+
public function toFeedItem()
118+
{
119+
$updatedAt = Carbon::parse($this->latest_creation);
120+
121+
return FeedItem::create()
122+
->id($this->id)
123+
->title($this->subject)
124+
->summary($this->body)
125+
->updated($updatedAt)
126+
->link(route('thread', $this->slug))
127+
->author($this->author()->name);
128+
}
129+
112130
/**
113131
* @return \App\Models\Thread[]
114132
*/
@@ -173,4 +191,15 @@ public static function resolutionTime()
173191
return false;
174192
}
175193
}
194+
195+
/**
196+
* retrieve 20 feed items with use of page parameter.
197+
*/
198+
public static function getFeedItems()
199+
{
200+
$page = intval(request('page', 1));
201+
$query = static::feedQuery();
202+
203+
return $query->skip(($page - 1) * static::FEED_PAGE_SIZE)->take(static::FEED_PAGE_SIZE)->get();
204+
}
176205
}

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"ramsey/uuid": "^3.7",
2222
"roave/security-advisories": "dev-master",
2323
"spatie/laravel-backup": "^6.4",
24+
"spatie/laravel-feed": "^2.0",
2425
"spatie/laravel-robots-middleware": "^1.0"
2526
},
2627
"require-dev": {
@@ -82,4 +83,4 @@
8283
},
8384
"minimum-stability": "dev",
8485
"prefer-stable": true
85-
}
86+
}

composer.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/feed.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
return [
4+
'feeds' => [
5+
'forum' => [
6+
/*
7+
* Here you can specify which class and method will return
8+
* the items that should appear in the feed. For example:
9+
* 'App\Model@getAllFeedItems'
10+
*
11+
* You can also pass an argument to that method:
12+
* ['App\Model@getAllFeedItems', 'argument']
13+
*/
14+
'items' => ['App\Models\Thread@getFeedItems'],
15+
16+
/*
17+
* The feed will be available on this url.
18+
*/
19+
'url' => '/forum/rss',
20+
21+
'title' => 'laravel.io Forum RSS Feed',
22+
],
23+
],
24+
];

resources/views/layouts/base.blade.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
window.Laravel = {!! json_encode(['csrfToken' => csrf_token()]) !!};
1818
</script>
1919

20+
@include('feed::links')
2021
@include('layouts._favicons')
2122
@include('layouts._cookie_consent')
2223
@include('layouts._google_analytics')
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?=
2+
/* Using an echo tag here so the `<? ... ?>` won't get parsed as short tags */
3+
'<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL
4+
?>
5+
<feed xmlns="http://www.w3.org/2005/Atom">
6+
@foreach($meta as $key => $metaItem)
7+
@if($key === 'link')
8+
<{{ $key }} href="{{ url($metaItem) }}"></{{ $key }}>
9+
@elseif($key === 'title')
10+
<{{ $key }}><![CDATA[{{ $metaItem }}]]></{{ $key }}>
11+
@else
12+
<{{ $key }}>{{ $metaItem }}</{{ $key }}>
13+
@endif
14+
@endforeach
15+
@foreach($items as $item)
16+
<entry>
17+
<title><![CDATA[{{ $item->title }}]]></title>
18+
<link rel="alternate" href="{{ url($item->link) }}" />
19+
<id>{{ url($item->id) }}</id>
20+
<author>
21+
<name> <![CDATA[{{ $item->author }}]]></name>
22+
</author>
23+
<summary type="html">
24+
<![CDATA[{!! $item->summary !!}]]>
25+
</summary>
26+
<updated>{{ $item->updated->toAtomString() }}</updated>
27+
</entry>
28+
@endforeach
29+
</feed>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@foreach($feeds as $name => $title)
2+
<link rel="alternate" type="application/rss+xml" href="{{ route("feeds.{$name}") }}" title="{{ $title }}">
3+
@endforeach

routes/web.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
Route::feeds();
4+
35
// Home
46
Route::get('/', 'HomeController@show')->name('home');
57
Route::get('rules', 'HomeController@rules')->name('rules');

0 commit comments

Comments
 (0)