17 |
18 | This package provides an easy way to generate a feed for your Laravel application. Supported formats are [RSS](http://www.whatisrss.com/), [Atom](https://en.wikipedia.org/wiki/Atom_(standard)), and [JSON](https://jsonfeed.org). There's almost no coding required on your part. Just follow the installation instructions, update your config file, and you're good to go.
19 |
20 | Spatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects [on our website](https://spatie.be/opensource).
21 |
22 | ## Support us
23 |
24 | [](https://spatie.be/github-ad-click/laravel-feed)
25 |
26 | We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).
27 |
28 | We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).
29 |
30 | ## Installation
31 |
32 | You can install the package via composer:
33 |
34 | ``` bash
35 | composer require spatie/laravel-feed
36 | ```
37 |
38 | Register the routes the feeds will be displayed on using the `feeds`-macro.
39 |
40 | ```php
41 | // In routes/web.php
42 | Route::feeds();
43 | ```
44 |
45 | Optionally, you can pass a string as a first argument of the macro. The string will be used as a URL prefix for all configured feeds.
46 |
47 | Next, you must publish the config file:
48 |
49 | ```bash
50 | php artisan feed:install
51 | ```
52 |
53 | Here's what that looks like:
54 |
55 | ```php
56 | return [
57 | 'feeds' => [
58 | 'main' => [
59 | /*
60 | * Here you can specify which class and method will return
61 | * the items that should appear in the feed. For example:
62 | * [App\Model::class, 'getAllFeedItems']
63 | *
64 | * You can also pass an argument to that method. Note that their key must be the name of the parameter: *
65 | * [App\Model::class, 'getAllFeedItems', 'parameterName' => 'argument']
66 | */
67 | 'items' => '',
68 |
69 | /*
70 | * The feed will be available on this url.
71 | */
72 | 'url' => '',
73 |
74 | 'title' => 'My feed',
75 | 'description' => 'The description of the feed.',
76 | 'language' => 'en-US',
77 |
78 | /*
79 | * The image to display for the feed. For Atom feeds, this is displayed as
80 | * a banner/logo; for RSS and JSON feeds, it's displayed as an icon.
81 | * An empty value omits the image attribute from the feed.
82 | */
83 | 'image' => '',
84 |
85 | /*
86 | * The format of the feed. Acceptable values are 'rss', 'atom', or 'json'.
87 | */
88 | 'format' => 'atom',
89 |
90 | /*
91 | * The view that will render the feed.
92 | */
93 | 'view' => 'feed::atom',
94 |
95 | /*
96 | * The mime type to be used in the tag. Set to an empty string to automatically
97 | * determine the correct value.
98 | */
99 | 'type' => '',
100 |
101 | /*
102 | * The content type for the feed response. Set to an empty string to automatically
103 | * determine the correct value.
104 | */
105 | 'contentType' => '',
106 | ],
107 | ],
108 | ];
109 | ```
110 |
111 | Optionally you can publish the view files:
112 |
113 | ```bash
114 | php artisan vendor:publish --provider="Spatie\Feed\FeedServiceProvider" --tag="feed-views"
115 | ```
116 |
117 | ## Usage
118 |
119 | Imagine you have a model named `NewsItem` that contains records that you want to have displayed in the feed.
120 |
121 | First you must implement the `Feedable` interface on that model. `Feedable` expects one method: `toFeedItem`, which should return a `FeedItem` instance.
122 |
123 | ```php
124 | // app/NewsItem.php
125 |
126 | use Illuminate\Database\Eloquent\Model;
127 | use Spatie\Feed\Feedable;
128 | use Spatie\Feed\FeedItem;
129 |
130 | class NewsItem extends Model implements Feedable
131 | {
132 | public function toFeedItem(): FeedItem
133 | {
134 | return FeedItem::create()
135 | ->id($this->id)
136 | ->title($this->title)
137 | ->summary($this->summary)
138 | ->updated($this->updated_at)
139 | ->link($this->link)
140 | ->authorName($this->author)
141 | ->authorEmail($this->authorEmail);
142 | }
143 | }
144 | ```
145 |
146 | If you prefer, returning an associative array with the necessary keys will do the trick too.
147 |
148 | ```php
149 | // app/NewsItem.php
150 |
151 | use Illuminate\Database\Eloquent\Model;
152 | use Spatie\Feed\Feedable;
153 | use Spatie\Feed\FeedItem;
154 |
155 | class NewsItem extends Model implements Feedable
156 | {
157 | public function toFeedItem(): FeedItem
158 | {
159 | return FeedItem::create([
160 | 'id' => $this->id,
161 | 'title' => $this->title,
162 | 'summary' => $this->summary,
163 | 'updated' => $this->updated_at,
164 | 'link' => $this->link,
165 | 'authorName' => $this->authorName,
166 | ]);
167 | }
168 | }
169 | ```
170 |
171 | Next, you'll have to create a method that will return all the items that must be displayed in
172 | the feed. You can name that method anything you like and you can do any query you want.
173 |
174 | ```php
175 | // app/NewsItem.php
176 |
177 | public static function getFeedItems()
178 | {
179 | return NewsItem::all();
180 | }
181 | ```
182 |
183 | Finally, you have to put the name of your class and the url where you want the feed to rendered
184 | in the config file:
185 |
186 | ```php
187 | // config/feed.php
188 |
189 | return [
190 |
191 | 'feeds' => [
192 | 'news' => [
193 | /*
194 | * Here you can specify which class and method will return
195 | * the items that should appear in the feed. For example:
196 | * 'App\Model@getAllFeedItems'
197 | * or
198 | * ['App\Model', 'getAllFeedItems']
199 | *
200 | * You can also pass an argument to that method. Note that their key must be the name of the parameter: *
201 | * ['App\Model@getAllFeedItems', 'parameterName' => 'argument']
202 | * or
203 | * ['App\Model', 'getAllFeedItems', 'parameterName' => 'argument']
204 | */
205 | 'items' => 'App\NewsItem@getFeedItems',
206 |
207 | /*
208 | * The feed will be available on this url.
209 | */
210 | 'url' => '/feed',
211 |
212 | 'title' => 'All newsitems on mysite.com',
213 |
214 | /*
215 | * The format of the feed. Acceptable values are 'rss', 'atom', or 'json'.
216 | */
217 | 'format' => 'atom',
218 |
219 | /*
220 | * Custom view for the items.
221 | *
222 | * Defaults to feed::feed if not present.
223 | */
224 | 'view' => 'feed::feed',
225 | ],
226 | ],
227 |
228 | ];
229 | ```
230 |
231 | The `items` key must point to a method that returns one of the following:
232 |
233 | - An array or collection of `Feedable`s
234 | - An array or collection of `FeedItem`s
235 | - An array or collection of arrays containing feed item values
236 |
237 | ### Customizing your feed views
238 |
239 | This package provides, out of the box, the `feed::feed` view that displays your feeds details.
240 |
241 | However, you could use a custom view per feed by providing a `view` key inside of your feed configuration.
242 |
243 | In the following example, we're using the previous `News` feed with a custom `feeds.news` view (located on `resources/views/feeds/news.blade.php`):
244 |
245 | ```php
246 | // config/feed.php
247 |
248 | return [
249 |
250 | 'feeds' => [
251 | 'news' => [
252 | 'items' => ['App\NewsItem', 'getFeedItems'],
253 |
254 | 'url' => '/feed',
255 |
256 | 'title' => 'All newsitems on mysite.com',
257 |
258 | /*
259 | * The format of the feed. Acceptable values are 'rss', 'atom', or 'json'.
260 | */
261 | 'format' => 'atom',
262 |
263 | /*
264 | * Custom view for the items.
265 | *
266 | * Defaults to feed::feed if not present.
267 | */
268 | 'view' => 'feeds.news',
269 | ],
270 | ],
271 |
272 | ];
273 | ```
274 |
275 | ### Automatically generate feed links
276 |
277 | To discover a feed, feed readers are looking for a tag in the head section of your html documents that looks like this:
278 |
279 | ```html
280 |
281 | ```
282 |
283 | You can add this to your `` through a partial view.
284 |
285 | ```php
286 | @include('feed::links')
287 | ```
288 |
289 | As an alternative you can use this blade component:
290 |
291 | ```html
292 |
293 | ```
294 |
295 | ## Testing
296 |
297 | ```bash
298 | composer test
299 | ```
300 |
301 | ## Changelog
302 |
303 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
304 |
305 | ## Contributing
306 |
307 | Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.
308 |
309 | ## Security Vulnerabilities
310 |
311 | Please review [our security policy](../../security/policy) on how to report security vulnerabilities.
312 |
313 | ## Credits
314 |
315 | - [Jolita Grazyte](https://github.com/JolitaGrazyte)
316 | - [Freek Van der Herten](https://github.com/freekmurze)
317 | - [Sebastian De Deyne](https://github.com/sebastiandedeyne)
318 | - [All Contributors](../../contributors)
319 |
320 | ## License
321 |
322 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
323 |
--------------------------------------------------------------------------------
/UPGRADING.md:
--------------------------------------------------------------------------------
1 | # Upgrade Guide
2 |
3 | This guide contains the steps to follow for upgrading `laravel-feed` versions.
4 |
5 | ## Upgrading from v4 to v4.3
6 |
7 | v4.3 added support for styled RSS feeds. To enable them issue this command
8 |
9 | ```bash
10 | php artisan feed:install
11 | ```
12 |
13 | This command will published the required assets.
14 |
15 | ## Upgrading from v3 to v4
16 |
17 | When upgrading from v3 to v4, there are a number of changes required; they primarily affect the configuration file, however
18 | there are also some minor changes required to the return value of the `toFeedItem()` method implemented on your models.
19 |
20 | ### Configuration file changes
21 |
22 | Make the following additions and changes to the `config/feed.php` configuration file.
23 |
24 | - add `image` to each feed as either a url to an image for the feed or an empty string:
25 |
26 | ```php
27 | 'image' => '',
28 | ```
29 |
30 | - add `format` to each feed with a valid value (`atom`, `json`, or `rss`):
31 |
32 | ```php
33 | 'format' => 'atom',
34 | ```
35 |
36 | - add `contentType` to each feed _(an empty value forces auto-detect)_:
37 |
38 | ```php
39 | 'contentType' => '',
40 | ```
41 |
42 | - update the `view` key in each feed to an existing view that is not `feed::feed`:
43 |
44 | ```php
45 | 'view' => 'feed::atom',
46 | ```
47 |
48 | - update the `type` key in each feed to an empty value unless you're sure you want to keep the existing value _(an empty value enables auto-detect)_:
49 |
50 | ```php
51 | 'type' => '',
52 | ```
53 |
54 | ### `toFeedItem()` return value changes
55 |
56 | The `author` property is no longer used. Instead, return an `authorName` property and optionally an `authorEmail` property.
57 |
58 | If you decide to take advantage of the new `jsonfeed.org` support, you may return an `image` property that associates an image with the feed item.
59 |
60 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spatie/laravel-feed",
3 | "description": "Generate rss feeds",
4 | "keywords": [
5 | "spatie",
6 | "rss",
7 | "laravel",
8 | "laravel-feed"
9 | ],
10 | "homepage": "https://github.com/spatie/laravel-feed",
11 | "license": "MIT",
12 | "authors": [
13 | {
14 | "name": "Jolita Grazyte",
15 | "email": "jolita@spatie.be",
16 | "homepage": "https://spatie.be",
17 | "role": "Developer"
18 | },
19 | {
20 | "name": "Freek Van der Herten",
21 | "email": "freek@spatie.be",
22 | "homepage": "https://spatie.be",
23 | "role": "Developer"
24 | },
25 | {
26 | "name": "Sebastian De Deyne",
27 | "email": "sebastian@spatie.be",
28 | "homepage": "https://spatie.be",
29 | "role": "Developer"
30 | },
31 | {
32 | "name": "Patrick Organ",
33 | "homepage": "https://github.com/patinthehat",
34 | "role": "Developer"
35 | }
36 | ],
37 | "require": {
38 | "php": "^8.2",
39 | "illuminate/support": "^10.0|^11.0|^12.0",
40 | "illuminate/http": "^10.0|^11.0|^12.0",
41 | "illuminate/contracts": "^10.0|^11.0|^12.0",
42 | "spatie/laravel-package-tools": "^1.15"
43 | },
44 | "require-dev": {
45 | "orchestra/testbench": "^8.0|^9.0|^10.0",
46 | "spatie/test-time": "^1.2",
47 | "pestphp/pest": "^2.0|^3.0",
48 | "spatie/pest-plugin-snapshots": "^2.0"
49 | },
50 | "autoload": {
51 | "psr-4": {
52 | "Spatie\\Feed\\": "src"
53 | }
54 | },
55 | "autoload-dev": {
56 | "psr-4": {
57 | "Spatie\\Feed\\Test\\": "tests"
58 | }
59 | },
60 | "scripts": {
61 | "test": "vendor/bin/pest",
62 | "test-coverage": "vendor/bin/pest --coverage-html coverage"
63 | },
64 | "extra": {
65 | "laravel": {
66 | "providers": [
67 | "Spatie\\Feed\\FeedServiceProvider"
68 | ]
69 | }
70 | },
71 | "minimum-stability": "dev",
72 | "prefer-stable": true,
73 | "config": {
74 | "allow-plugins": {
75 | "pestphp/pest-plugin": true
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/config/feed.php:
--------------------------------------------------------------------------------
1 | [
5 | 'main' => [
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::class, 'getAllFeedItems']
10 | *
11 | * You can also pass an argument to that method. Note that their key must be the name of the parameter:
12 | * [App\Model::class, 'getAllFeedItems', 'parameterName' => 'argument']
13 | */
14 | 'items' => '',
15 |
16 | /*
17 | * The feed will be available on this url.
18 | */
19 | 'url' => '',
20 |
21 | 'title' => 'My feed',
22 | 'description' => 'The description of the feed.',
23 | 'language' => 'en-US',
24 |
25 | /*
26 | * The image to display for the feed. For Atom feeds, this is displayed as
27 | * a banner/logo; for RSS and JSON feeds, it's displayed as an icon.
28 | * An empty value omits the image attribute from the feed.
29 | */
30 | 'image' => '',
31 |
32 | /*
33 | * The format of the feed. Acceptable values are 'rss', 'atom', or 'json'.
34 | */
35 | 'format' => 'atom',
36 |
37 | /*
38 | * The view that will render the feed.
39 | */
40 | 'view' => 'feed::atom',
41 |
42 | /*
43 | * The mime type to be used in the tag. Set to an empty string to automatically
44 | * determine the correct value.
45 | */
46 | 'type' => '',
47 |
48 | /*
49 | * The content type for the feed response. Set to an empty string to automatically
50 | * determine the correct value.
51 | */
52 | 'contentType' => '',
53 | ],
54 | ],
55 | ];
56 |
--------------------------------------------------------------------------------
/resources/dist/atom.xsl:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 | RSS Feed |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |