diff --git a/app/Http/Controllers/FeedsController.php b/app/Http/Controllers/FeedsController.php
index 530b0af0..945609fc 100644
--- a/app/Http/Controllers/FeedsController.php
+++ b/app/Http/Controllers/FeedsController.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Http\Controllers;
use App\Models\{Article, Note};
+use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
class FeedsController extends Controller
@@ -12,7 +13,7 @@ class FeedsController extends Controller
/**
* Returns the blog RSS feed.
*
- * @return \Illuminate\Http\Response
+ * @return Response
*/
public function blogRss(): Response
{
@@ -27,7 +28,7 @@ class FeedsController extends Controller
/**
* Returns the blog Atom feed.
*
- * @return \Illuminate\Http\Response
+ * @return Response
*/
public function blogAtom(): Response
{
@@ -41,7 +42,7 @@ class FeedsController extends Controller
/**
* Returns the notes RSS feed.
*
- * @return \Illuminate\Http\Response
+ * @return Response
*/
public function notesRss(): Response
{
@@ -56,7 +57,7 @@ class FeedsController extends Controller
/**
* Returns the notes Atom feed.
*
- * @return \Illuminate\Http\Response
+ * @return Response
*/
public function notesAtom(): Response
{
@@ -133,4 +134,80 @@ class FeedsController extends Controller
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',
+ ]);
+ }
}
diff --git a/resources/views/master.blade.php b/resources/views/master.blade.php
index 20c9d7bb..0a20b6cc 100644
--- a/resources/views/master.blade.php
+++ b/resources/views/master.blade.php
@@ -10,9 +10,11 @@
+
+
diff --git a/routes/web.php b/routes/web.php
index 39ac2d41..de53f1a0 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -108,6 +108,7 @@ Route::group(['domain' => config('url.longurl')], function () {
Route::get('/feed.rss', 'FeedsController@blogRss');
Route::get('/feed.atom', 'FeedsController@blogAtom');
Route::get('/feed.json', 'FeedsController@blogJson');
+ Route::get('/feed.jf2', 'Feedscontroller@blogJf2');
Route::get('/s/{id}', 'ArticlesController@onlyIdInURL');
Route::get('/{year?}/{month?}', 'ArticlesController@index');
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.atom', 'FeedsController@notesAtom');
Route::get('/feed.json', 'FeedsController@notesJson');
+ Route::get('/feed.jf2', 'FeedsController@notesJf2');
Route::get('/{id}', 'NotesController@show');
Route::get('/tagged/{tag}', 'NotesController@tagged');
});
diff --git a/tests/Feature/FeedsTest.php b/tests/Feature/FeedsTest.php
index 37c51a27..1c3c8bd2 100644
--- a/tests/Feature/FeedsTest.php
+++ b/tests/Feature/FeedsTest.php
@@ -39,6 +39,27 @@ class FeedsTest extends TestCase
$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.
*
@@ -72,6 +93,27 @@ class FeedsTest extends TestCase
$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`,
* and whichever one they have can’t be `null`.