Add jf2 feeds for notes and blog posts

This commit is contained in:
Jonny Barnes 2020-06-20 16:47:39 +01:00
parent 112c6e02d5
commit 0195814219
3 changed files with 125 additions and 4 deletions

View file

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\{Article, Note}; use App\Models\{Article, Note};
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response; use Illuminate\Http\Response;
class FeedsController extends Controller class FeedsController extends Controller
@ -12,7 +13,7 @@ class FeedsController extends Controller
/** /**
* Returns the blog RSS feed. * Returns the blog RSS feed.
* *
* @return \Illuminate\Http\Response * @return Response
*/ */
public function blogRss(): Response public function blogRss(): Response
{ {
@ -27,7 +28,7 @@ class FeedsController extends Controller
/** /**
* Returns the blog Atom feed. * Returns the blog Atom feed.
* *
* @return \Illuminate\Http\Response * @return Response
*/ */
public function blogAtom(): Response public function blogAtom(): Response
{ {
@ -41,7 +42,7 @@ class FeedsController extends Controller
/** /**
* Returns the notes RSS feed. * Returns the notes RSS feed.
* *
* @return \Illuminate\Http\Response * @return Response
*/ */
public function notesRss(): Response public function notesRss(): Response
{ {
@ -56,7 +57,7 @@ class FeedsController extends Controller
/** /**
* Returns the notes Atom feed. * Returns the notes Atom feed.
* *
* @return \Illuminate\Http\Response * @return Response
*/ */
public function notesAtom(): Response public function notesAtom(): Response
{ {
@ -133,4 +134,80 @@ class FeedsController extends Controller
return $data; return $data;
} }
/**
* Returns the blog JF2 feed.
*
* @return JsonResponse
*/
public function blogJf2(): JsonResponse
{
$articles = Article::where('published', '1')->latest('updated_at')->take(20)->get();
$items = [];
foreach ($articles as $article) {
$items[] = [
'type' => 'entry',
'published' => $article->created_at,
'uid' => config('app.url') . $article->link,
'url' => config('app.url') . $article->link,
'content' => [
'text' => $article->main,
'html' => $article->html,
],
'post-type' => 'article',
];
}
return response()->json([
'type' => 'feed',
'name' => 'Blog feed for ' . config('app.name'),
'url' => url('/blog'),
'author' => [
'type' => 'card',
'name' => config('user.displayname'),
'url' => config('app.longurl'),
],
'children' => $items,
], 200, [
'Content-Type' => 'application/jf2feed+json',
]);
}
/**
* Returns the notes JF2 feed.
*
* @return JsonResponse
*/
public function notesJf2(): JsonResponse
{
$notes = Note::latest()->take(20)->get();
$items = [];
foreach ($notes as $note) {
$items[] = [
'type' => 'entry',
'published' => $note->created_at,
'uid' => $note->longurl,
'url' => $note->longurl,
'content' => [
'text' => $note->getRawOriginal('note'),
'html' => $note->note,
],
'post-type' => 'note',
];
}
return response()->json([
'type' => 'feed',
'name' => 'Notes feed for ' . config('app.name'),
'url' => url('/notes'),
'author' => [
'type' => 'card',
'name' => config('user.displayname'),
'url' => config('app.longurl'),
],
'children' => $items,
], 200, [
'Content-Type' => 'application/jf2feed+json',
]);
}
} }

View file

@ -108,6 +108,7 @@ Route::group(['domain' => config('url.longurl')], function () {
Route::get('/feed.rss', 'FeedsController@blogRss'); Route::get('/feed.rss', 'FeedsController@blogRss');
Route::get('/feed.atom', 'FeedsController@blogAtom'); Route::get('/feed.atom', 'FeedsController@blogAtom');
Route::get('/feed.json', 'FeedsController@blogJson'); Route::get('/feed.json', 'FeedsController@blogJson');
Route::get('/feed.jf2', 'Feedscontroller@blogJf2');
Route::get('/s/{id}', 'ArticlesController@onlyIdInURL'); Route::get('/s/{id}', 'ArticlesController@onlyIdInURL');
Route::get('/{year?}/{month?}', 'ArticlesController@index'); Route::get('/{year?}/{month?}', 'ArticlesController@index');
Route::get('/{year}/{month}/{slug}', 'ArticlesController@show'); Route::get('/{year}/{month}/{slug}', 'ArticlesController@show');
@ -119,6 +120,7 @@ Route::group(['domain' => config('url.longurl')], function () {
Route::get('/feed.rss', 'FeedsController@notesRss'); Route::get('/feed.rss', 'FeedsController@notesRss');
Route::get('/feed.atom', 'FeedsController@notesAtom'); Route::get('/feed.atom', 'FeedsController@notesAtom');
Route::get('/feed.json', 'FeedsController@notesJson'); Route::get('/feed.json', 'FeedsController@notesJson');
Route::get('/feed.jf2', 'FeedsController@notesJf2');
Route::get('/{id}', 'NotesController@show'); Route::get('/{id}', 'NotesController@show');
Route::get('/tagged/{tag}', 'NotesController@tagged'); Route::get('/tagged/{tag}', 'NotesController@tagged');
}); });

View file

@ -39,6 +39,27 @@ class FeedsTest extends TestCase
$response->assertHeader('Content-Type', 'application/atom+xml; charset=utf-8'); $response->assertHeader('Content-Type', 'application/atom+xml; charset=utf-8');
} }
/** @test */
public function blog_jf2_feed()
{
$response = $this->get('/blog/feed.jf2');
$response->assertHeader('Content-Type', 'application/jf2feed+json');
$response->assertJson([
'type' => 'feed',
'name' => 'Blog feed for ' . config('app.name'),
'url' => url('/blog'),
'author' => [
'type' => 'card',
'name' => config('user.displayname'),
'url' => config('app.longurl'),
],
'children' => [[
'type' => 'entry',
'post-type' => 'article',
]]
]);
}
/** /**
* Test the notes RSS feed. * Test the notes RSS feed.
* *
@ -72,6 +93,27 @@ class FeedsTest extends TestCase
$response->assertHeader('Content-Type', 'application/json'); $response->assertHeader('Content-Type', 'application/json');
} }
/** @test */
public function notes_jf2_feed()
{
$response = $this->get('/notes/feed.jf2');
$response->assertHeader('Content-Type', 'application/jf2feed+json');
$response->assertJson([
'type' => 'feed',
'name' => 'Notes feed for ' . config('app.name'),
'url' => url('/notes'),
'author' => [
'type' => 'card',
'name' => config('user.displayname'),
'url' => config('app.longurl'),
],
'children' => [[
'type' => 'entry',
'post-type' => 'note',
]]
]);
}
/** /**
* Each JSON feed item must have one of `content_text` or `content_html`, * Each JSON feed item must have one of `content_text` or `content_html`,
* and whichever one they have cant be `null`. * and whichever one they have cant be `null`.