From 70458063ccc442df2e21afd56677fc01a067c691 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Wed, 12 Jan 2022 17:43:50 +0100 Subject: [PATCH] imp: Display new feed errors in the modal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For now, responses to form submits redirect to a new page. However, I’d like the modal forms errors to be displayed directly in the modal, without redirecting to a new page. Since the modal is handled with a Turbo Frame, it should not be too complicated. Except that's impossible. I need to set the frame attribute target="_top" in order to redirect after a success, but I would need the opposite in case of an error. There are some discussions to handle this use case directly with Turbo, but until an official solution appears, I will use this hack which use Turbo Stream to update the modal content. I don’t think it’s a perfect solution, so I’m not going to generalize it in the application. The new feed form is important to handle correctly since errors are common (e.g. a feed cannot be found). Reference: https://github.com/hotwired/turbo/issues/138#issuecomment-847699281 --- lib/Minz | 2 +- src/Application.php | 2 + src/controllers/Feeds.php | 21 +++++++--- src/views/feeds/_new.phtml | 52 ++++++++++++++++++++++++ src/views/feeds/new.phtml | 56 +++----------------------- src/views/feeds/new.turbo_stream.phtml | 10 +++++ 6 files changed, 87 insertions(+), 56 deletions(-) create mode 100644 src/views/feeds/_new.phtml create mode 100644 src/views/feeds/new.turbo_stream.phtml diff --git a/lib/Minz b/lib/Minz index 7bac3e97..4b2c73c1 160000 --- a/lib/Minz +++ b/lib/Minz @@ -1 +1 @@ -Subproject commit 7bac3e97c1552cacd600874d2d172e22f24905c3 +Subproject commit 4b2c73c105162611ccba001b3fd1007f81b11940 diff --git a/src/Application.php b/src/Application.php index 750b3d13..0c6b9bb8 100644 --- a/src/Application.php +++ b/src/Application.php @@ -35,6 +35,8 @@ public function __construct() $router = Router::load(); $this->engine = new \Minz\Engine($router); \Minz\Url::setRouter($router); + + \Minz\Output\View::$extensions_to_content_types['.turbo_stream.phtml'] = 'text/vnd.turbo-stream.html'; } /** diff --git a/src/controllers/Feeds.php b/src/controllers/Feeds.php index 0c951e88..89648e80 100644 --- a/src/controllers/Feeds.php +++ b/src/controllers/Feeds.php @@ -58,7 +58,8 @@ public function index($request) /** * Show the page to add a feed. * - * @request_param string from The page to redirect to after creation + * @request_param string from + * The page to redirect to after creation (default is /feeds) * * @response 302 /login?redirect_to=:from if not connected * @response 200 @@ -66,7 +67,7 @@ public function index($request) public function new($request) { $user = auth\CurrentUser::get(); - $from = $request->param('from'); + $from = $request->param('from', \Minz\Url::for('feeds')); if (!$user) { return Response::redirect('login', ['redirect_to' => $from]); @@ -103,8 +104,18 @@ public function create($request) return Response::redirect('login', ['redirect_to' => $from]); } + if ($request->isAccepting('text/vnd.turbo-stream.html')) { + // This allows to display the errors within the modal instead of + // sending a whole new page. This is a bit hacky so I'm going + // to use this method only where absolutely needed. + // @see https://github.com/hotwired/turbo/issues/138#issuecomment-847699281 + $view_file = 'feeds/new.turbo_stream.phtml'; + } else { + $view_file = 'feeds/new.phtml'; + } + if (!\Minz\CSRF::validate($csrf)) { - return Response::badRequest('feeds/new.phtml', [ + return Response::badRequest($view_file, [ 'url' => $url, 'from' => $from, 'error' => _('A security verification failed: you should retry to submit the form.'), @@ -121,7 +132,7 @@ public function create($request) $errors = $default_link->validate(); if ($errors) { - return Response::badRequest('feeds/new.phtml', [ + return Response::badRequest($view_file, [ 'url' => $url, 'from' => $from, 'errors' => $errors, @@ -136,7 +147,7 @@ public function create($request) $feed_urls = $default_link->feedUrls(); if (count($feed_urls) === 0) { - return Response::badRequest('feeds/new.phtml', [ + return Response::badRequest($view_file, [ 'url' => $url, 'from' => $from, 'errors' => [ diff --git a/src/views/feeds/_new.phtml b/src/views/feeds/_new.phtml new file mode 100644 index 00000000..a481ba19 --- /dev/null +++ b/src/views/feeds/_new.phtml @@ -0,0 +1,52 @@ + +
+
+

+
+ +
+ +

+ +

+ + + + + +
+ + + + + +

+ + +

+ + +

+ URL bar, at the top of your browser.') ?> +

+
+ +
+ +
+
+
+
diff --git a/src/views/feeds/new.phtml b/src/views/feeds/new.phtml index 0c720dd2..e35eeca4 100644 --- a/src/views/feeds/new.phtml +++ b/src/views/feeds/new.phtml @@ -10,53 +10,9 @@ ]); ?> -
-
-

-
- -
- -

- -

- - - - - -
- - - - - -

- - -

- - -

- URL bar, at the top of your browser.') ?> -

-
- -
- -
-
-
+include('feeds/_new.phtml', [ + 'url' => $url, + 'from' => $from, + 'errors' => $errors, + 'error' => $error, +]); ?> diff --git a/src/views/feeds/new.turbo_stream.phtml b/src/views/feeds/new.turbo_stream.phtml new file mode 100644 index 00000000..587efc52 --- /dev/null +++ b/src/views/feeds/new.turbo_stream.phtml @@ -0,0 +1,10 @@ + + +