diff --git a/app/Views/Components/DropdownMenu.php b/app/Views/Components/DropdownMenu.php
index 23609c27f660811c9925aed17cb682c96bc4d3b2..7803b9fc6374007d401320bc07727582333bee2a 100644
--- a/app/Views/Components/DropdownMenu.php
+++ b/app/Views/Components/DropdownMenu.php
@@ -21,7 +21,7 @@ class DropdownMenu extends Component
 
     public function setItems(string $value): void
     {
-        $this->items = json_decode(html_entity_decode($value), true);
+        $this->items = json_decode(htmlspecialchars_decode($value), true);
     }
 
     public function render(): string
@@ -39,7 +39,7 @@ class DropdownMenu extends Component
                     ]);
                     break;
                 case 'html':
-                    $menuItems .= html_entity_decode($item['content']);
+                    $menuItems .= htmlspecialchars_decode($item['content']);
                     break;
                 case 'separator':
                     $menuItems .= '<hr class="my-2 border border-subtle">';
diff --git a/app/Views/Components/Forms/MarkdownEditor.php b/app/Views/Components/Forms/MarkdownEditor.php
index 24c3abcc0a747a765cfa0a57f0a162925bfeeba6..9fab63a06a629236e6b1c45dd9ca676d75632725 100644
--- a/app/Views/Components/Forms/MarkdownEditor.php
+++ b/app/Views/Components/Forms/MarkdownEditor.php
@@ -13,7 +13,10 @@ class MarkdownEditor extends FormComponent
         $this->attributes['class'] = 'bg-elevated border-none focus:border-none focus:outline-none focus:ring-0 w-full h-full';
         $this->attributes['rows'] = 6;
 
-        $textarea = form_textarea($this->attributes, old($this->name, html_entity_decode($this->value), false));
+        // dd(htmlspecialchars_decode($this->value));
+        $value = htmlspecialchars_decode($this->value);
+
+        $textarea = form_textarea($this->attributes, old($this->name, $value, false));
         $icons = [
             'heading' => icon('heading'),
             'bold' => icon('bold'),
diff --git a/app/Views/Components/Forms/MultiSelect.php b/app/Views/Components/Forms/MultiSelect.php
index f04d6f536c95335292978fc3ebdd037a2db1f2e3..67d0efd2faf0abf52a2cd0b16674600963c51f25 100644
--- a/app/Views/Components/Forms/MultiSelect.php
+++ b/app/Views/Components/Forms/MultiSelect.php
@@ -18,12 +18,12 @@ class MultiSelect extends FormComponent
 
     public function setOptions(string $value): void
     {
-        $this->options = json_decode(html_entity_decode($value), true);
+        $this->options = json_decode(htmlspecialchars_decode($value), true);
     }
 
     public function setSelected(string $selected): void
     {
-        $this->selected = json_decode($selected);
+        $this->selected = json_decode(htmlspecialchars_decode($selected), true);
     }
 
     public function render(): string
diff --git a/app/Views/Components/Forms/Select.php b/app/Views/Components/Forms/Select.php
index 02d6d31bfa89396aa0a8e62cae4d3fde40eb2bf1..1dce33930f8e5525373ab375cffb8acedf1d6f6b 100644
--- a/app/Views/Components/Forms/Select.php
+++ b/app/Views/Components/Forms/Select.php
@@ -15,7 +15,7 @@ class Select extends FormComponent
 
     public function setOptions(string $value): void
     {
-        $this->options = json_decode(html_entity_decode($value), true);
+        $this->options = json_decode(htmlspecialchars_decode($value), true);
     }
 
     public function render(): string
diff --git a/app/Views/Components/Forms/Textarea.php b/app/Views/Components/Forms/Textarea.php
index 9e429258edba6686a8b1424cdff241e3d698bba2..705ec0f35c4072aa882942c43bff64124ad282d2 100644
--- a/app/Views/Components/Forms/Textarea.php
+++ b/app/Views/Components/Forms/Textarea.php
@@ -9,7 +9,7 @@ class Textarea extends FormComponent
     public function setValue(?string $value): void
     {
         if ($value) {
-            $this->value = html_entity_decode($value);
+            $this->value = htmlspecialchars_decode($value);
         }
     }
 
diff --git a/app/Views/errors/html/error_404.php b/app/Views/errors/html/error_404.php
index 0feb6b7d53fbfc0023e4fc219a341dacfacc52a6..13cd335791aed89250ff77a8b1b11e96ace9127c 100644
--- a/app/Views/errors/html/error_404.php
+++ b/app/Views/errors/html/error_404.php
@@ -21,7 +21,7 @@
             Sorry! Cannot seem to find the page you were looking for.
         <?php endif; ?>
     </p>
-    <button class="inline-flex items-center justify-center px-3 py-1 text-sm font-semibold rounded-full shadow-xs text-accent-contrast focus:ring-accent md:px-4 md:py-2 md:text-base bg-accent-base hover:bg-accent-hover"><?= lang('Common.go_back') ?></button>
+    <a href="<?= previous_url() ?>" class="inline-flex items-center justify-center px-3 py-1 text-sm font-semibold rounded-full shadow-xs text-accent-contrast focus:ring-accent md:px-4 md:py-2 md:text-base bg-accent-base hover:bg-accent-hover"><?= lang('Common.go_back') ?></a>
 </body>
 
 </html>
diff --git a/modules/Admin/Controllers/ContributorController.php b/modules/Admin/Controllers/ContributorController.php
index ad79f24b50a0c3246067cfc633f33e27ddfd3465..07bfd114acaadbcca2b11a2e7cbfddea28632e1f 100644
--- a/modules/Admin/Controllers/ContributorController.php
+++ b/modules/Admin/Controllers/ContributorController.php
@@ -166,7 +166,10 @@ class ContributorController extends BaseController
             (int) $this->request->getPost('role'),
         );
 
-        return redirect()->route('contributor-list', [$this->podcast->id]);
+        return redirect()->route('contributor-edit', [$this->podcast->id, $this->user->id])->with(
+            'message',
+            lang('Contributor.messages.editSuccess')
+        );
     }
 
     public function remove(): RedirectResponse
@@ -174,7 +177,7 @@ class ContributorController extends BaseController
         if ($this->podcast->created_by === $this->user->id) {
             return redirect()
                 ->back()
-                ->with('errors', [lang('Contributor.messages.removeOwnerContributorError')]);
+                ->with('errors', [lang('Contributor.messages.removeOwnerError')]);
         }
 
         $podcastModel = new PodcastModel();
@@ -187,10 +190,10 @@ class ContributorController extends BaseController
         }
 
         return redirect()
-            ->back()
+            ->route('contributor-list', [$this->podcast->id])
             ->with(
                 'message',
-                lang('Contributor.messages.removeContributorSuccess', [
+                lang('Contributor.messages.removeSuccess', [
                     'username' => $this->user->username,
                     'podcastTitle' => $this->podcast->title,
                 ]),
diff --git a/modules/Admin/Controllers/EpisodeController.php b/modules/Admin/Controllers/EpisodeController.php
index a2a2c57e2bdc5b912525bfdf11815abbcb788b9d..2d297ff98d66ccb3b84a8d9e03e96be3935feb1b 100644
--- a/modules/Admin/Controllers/EpisodeController.php
+++ b/modules/Admin/Controllers/EpisodeController.php
@@ -205,7 +205,10 @@ class EpisodeController extends BaseController
 
         $db->transComplete();
 
-        return redirect()->route('episode-view', [$this->podcast->id, $newEpisodeId]);
+        return redirect()->route('episode-view', [$this->podcast->id, $newEpisodeId])->with(
+            'message',
+            lang('Episode.messages.createSuccess')
+        );
     }
 
     public function edit(): string
@@ -334,11 +337,18 @@ class EpisodeController extends BaseController
 
         $db->transComplete();
 
-        return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id]);
+        return redirect()->route('episode-edit', [$this->podcast->id, $this->episode->id])->with(
+            'message',
+            lang('Episode.messages.editSuccess')
+        );
     }
 
     public function transcriptDelete(): RedirectResponse
     {
+        if ($this->episode->transcript === null) {
+            return redirect()->back();
+        }
+
         $mediaModel = new MediaModel();
         if (! $mediaModel->deleteMedia($this->episode->transcript)) {
             return redirect()
@@ -352,6 +362,10 @@ class EpisodeController extends BaseController
 
     public function chaptersDelete(): RedirectResponse
     {
+        if ($this->episode->chapters === null) {
+            return redirect()->back();
+        }
+
         $mediaModel = new MediaModel();
         if (! $mediaModel->deleteMedia($this->episode->chapters)) {
             return redirect()
@@ -699,16 +713,18 @@ class EpisodeController extends BaseController
             (new PostModel())->removePost($post);
         }
 
-        // set episode published_at to null to unpublish before deletion
-        $this->episode->published_at = null;
-
         $episodeModel = new EpisodeModel();
-        if (! $episodeModel->update($this->episode->id, $this->episode)) {
-            $db->transRollback();
-            return redirect()
-                ->back()
-                ->withInput()
-                ->with('errors', $episodeModel->errors());
+        if ($this->episode->published_at !== null) {
+            // if episode is published, set episode published_at to null to unpublish before deletion
+            $this->episode->published_at = null;
+
+            if (! $episodeModel->update($this->episode->id, $this->episode)) {
+                $db->transRollback();
+                return redirect()
+                    ->back()
+                    ->withInput()
+                    ->with('errors', $episodeModel->errors());
+            }
         }
 
         $episodeModel->delete($this->episode->id);
diff --git a/modules/Admin/Controllers/PageController.php b/modules/Admin/Controllers/PageController.php
index 7458719ee10e0f50d5787205f50241478a135179..1a13abcc469bc0055743249b56478634fd1d7534 100644
--- a/modules/Admin/Controllers/PageController.php
+++ b/modules/Admin/Controllers/PageController.php
@@ -106,7 +106,7 @@ class PageController extends BaseController
                 ->with('errors', $pageModel->errors());
         }
 
-        return redirect()->route('page-list');
+        return redirect()->route('page-edit', [$this->page->id])->with('message', lang('Page.messages.editSuccess'));
     }
 
     public function delete(): RedirectResponse
diff --git a/modules/Admin/Controllers/PersonController.php b/modules/Admin/Controllers/PersonController.php
index da410de48d645930cbdd12920edf411fddbe1a79..a62914a4a406f9db7d9fc0de34541d20ba03f691 100644
--- a/modules/Admin/Controllers/PersonController.php
+++ b/modules/Admin/Controllers/PersonController.php
@@ -99,7 +99,8 @@ class PersonController extends BaseController
 
         $db->transComplete();
 
-        return redirect()->route('person-list');
+        return redirect()->route('person-list')
+            ->with('message', lang('Person.messages.createSuccess'));
     }
 
     public function edit(): string
@@ -145,13 +146,17 @@ class PersonController extends BaseController
                 ->with('errors', $personModel->errors());
         }
 
-        return redirect()->route('person-view', [$this->person->id]);
+        return redirect()->route('person-edit', [$this->person->id])->with(
+            'message',
+            lang('Person.messages.editSuccess')
+        );
     }
 
     public function delete(): RedirectResponse
     {
         (new PersonModel())->delete($this->person->id);
 
-        return redirect()->route('person-list');
+        return redirect()->route('person-list')
+            ->with('message', lang('Person.messages.deleteSuccess'));
     }
 }
diff --git a/modules/Admin/Controllers/PodcastController.php b/modules/Admin/Controllers/PodcastController.php
index 22e9a68ea978d241f5b939aba1f7d7b2fe6463e8..5f39fe124faa33b9c300f4b5b86b24bf2458bbce 100644
--- a/modules/Admin/Controllers/PodcastController.php
+++ b/modules/Admin/Controllers/PodcastController.php
@@ -255,7 +255,10 @@ class PodcastController extends BaseController
 
         $db->transComplete();
 
-        return redirect()->route('podcast-view', [$newPodcastId]);
+        return redirect()->route('podcast-view', [$newPodcastId])->with(
+            'message',
+            lang('Podcast.messages.createSuccess')
+        );
     }
 
     public function edit(): string
@@ -354,7 +357,10 @@ class PodcastController extends BaseController
 
         $db->transComplete();
 
-        return redirect()->back();
+        return redirect()->route('podcast-edit', [$this->podcast->id])->with(
+            'message',
+            lang('Podcast.messages.editSuccess')
+        );
     }
 
     public function deleteBanner(): RedirectResponse
diff --git a/modules/Admin/Controllers/SoundbiteController.php b/modules/Admin/Controllers/SoundbiteController.php
index c13b2453c6591fe4f3c1baeae5851cbb2ba94484..d9abe12726a0231018d33b35b88f7b34479bba0b 100644
--- a/modules/Admin/Controllers/SoundbiteController.php
+++ b/modules/Admin/Controllers/SoundbiteController.php
@@ -134,7 +134,10 @@ class SoundbiteController extends BaseController
                 ->with('errors', $clipModel->errors());
         }
 
-        return redirect()->route('soundbites-list', [$this->podcast->id, $this->episode->id]);
+        return redirect()->route('soundbites-list', [$this->podcast->id, $this->episode->id])->with(
+            'message',
+            lang('Soundbite.messages.createSuccess')
+        );
     }
 
     public function delete(string $soundbiteId): RedirectResponse
@@ -158,6 +161,9 @@ class SoundbiteController extends BaseController
             }
         }
 
-        return redirect()->route('soundbites-list', [$this->podcast->id, $this->episode->id]);
+        return redirect()->route('soundbites-list', [$this->podcast->id, $this->episode->id])->with(
+            'message',
+            lang('Soundbite.messages.deleteSuccess')
+        );
     }
 }
diff --git a/modules/Admin/Language/en/Contributor.php b/modules/Admin/Language/en/Contributor.php
index 087e4f6d5f5231feea878994c8d733f719817a70..7d9c99b4b8187cd45fd4cfd1d102e3de7419f9a4 100644
--- a/modules/Admin/Language/en/Contributor.php
+++ b/modules/Admin/Language/en/Contributor.php
@@ -32,8 +32,8 @@ return [
         'podcast_admin' => 'Podcast admin',
     ],
     'messages' => [
-        'removeOwnerContributorError' => "You can't remove the podcast owner!",
-        'removeContributorSuccess' =>
+        'removeOwnerError' => "You can't remove the podcast owner!",
+        'removeSuccess' =>
             'You have successfully removed {username} from {podcastTitle}',
         'alreadyAddedError' =>
             "The contributor you're trying to add has already been added!",
diff --git a/modules/Admin/Language/en/Episode.php b/modules/Admin/Language/en/Episode.php
index 7b3d32189dd584268ccdd31c328d60c0349dd807..cce9992ff7716f0d7053d877faef5ff449746fa9 100644
--- a/modules/Admin/Language/en/Episode.php
+++ b/modules/Admin/Language/en/Episode.php
@@ -43,6 +43,10 @@ return [
         'comments' => 'Comments',
         'actions' => 'Actions',
     ],
+    'messages' => [
+        'createSuccess' => 'Episode has been successfully created!',
+        'editSuccess' => 'Episode has been successfully updated!',
+    ],
     'form' => [
         'warning' =>
             'In case of fatal error, try increasing the `memory_limit`, `upload_max_filesize` and `post_max_size` values in your php configuration file then restart your web server.<br />These values must be higher than the audio file you wish to upload.',
diff --git a/modules/Admin/Language/en/Fediverse.php b/modules/Admin/Language/en/Fediverse.php
index a445724791d24a411c138e4e8e921860edcad2e4..6ef8d71dd4247bf7f69a0345e478a7921e7538ac 100644
--- a/modules/Admin/Language/en/Fediverse.php
+++ b/modules/Admin/Language/en/Fediverse.php
@@ -9,6 +9,12 @@ declare(strict_types=1);
  */
 
 return [
+    'messages' => [
+        'blockActorSuccess' => '{actor} has been blocked!',
+        'unblockActorSuccess' => 'Actor has been unblocked!',
+        'blockDomainSuccess' => '{domain} has been blocked!',
+        'unblockDomainSuccess' => '{domain} has been unblocked!',
+    ],
     'blocked_actors' => 'Blocked accounts',
     'blocked_domains' => 'Blocked domains',
     'block_lists_form' => [
diff --git a/modules/Admin/Language/en/Page.php b/modules/Admin/Language/en/Page.php
index e4a78f89d5d65474acf1f6302e4ada1ac85a56b9..c6b4b8fe87625face7e45e5e1c5030b9f619b945 100644
--- a/modules/Admin/Language/en/Page.php
+++ b/modules/Admin/Language/en/Page.php
@@ -25,5 +25,6 @@ return [
     ],
     'messages' => [
         'createSuccess' => 'The page “{pageTitle}” was created successfully!',
+        'editSuccess' => 'The page was successfully updated!',
     ],
 ];
diff --git a/modules/Admin/Language/en/Person.php b/modules/Admin/Language/en/Person.php
index b9e122d2e40766f2a80ddabf3839f3b2ec5b97b9..114597ccbb2151eb1223aed33bacf6f6993bfac0 100644
--- a/modules/Admin/Language/en/Person.php
+++ b/modules/Admin/Language/en/Person.php
@@ -16,6 +16,11 @@ return [
     'view' => 'View person',
     'edit' => 'Edit person',
     'delete' => 'Delete person',
+    'messages' => [
+        'createSuccess' => 'Person has been successfully created!',
+        'editSuccess' => 'Person has been successfully updated!',
+        'deleteSuccess' => 'Person has been removed!',
+    ],
     'form' => [
         'avatar' => 'Avatar',
         'avatar_size_hint' =>
diff --git a/modules/Admin/Language/en/Podcast.php b/modules/Admin/Language/en/Podcast.php
index c03e46f8a776266d51a83aef796108ec3f1c2e8e..54a5e210f08d45a98c0b0ff96bba546560f15995 100644
--- a/modules/Admin/Language/en/Podcast.php
+++ b/modules/Admin/Language/en/Podcast.php
@@ -22,6 +22,11 @@ return [
     'go_to_page' => 'Go to page',
     'latest_episodes' => 'Latest episodes',
     'see_all_episodes' => 'See all episodes',
+    'messages' => [
+        'createSuccess' => 'Podcast has been successfully created!',
+        'editSuccess' => 'Podcast has been successfully updated!',
+        'importSuccess' => 'Podcast has been successfully imported!',
+    ],
     'form' => [
         'identity_section_title' => 'Podcast identity',
         'identity_section_subtitle' => 'These fields allow you to get noticed.',
diff --git a/modules/Admin/Language/en/Soundbite.php b/modules/Admin/Language/en/Soundbite.php
index 8faed932febf7b67693dbc510c6fa1263a5cd43f..059cb1bc720bacba912f9fc8adcbfe32a27ce3ac 100644
--- a/modules/Admin/Language/en/Soundbite.php
+++ b/modules/Admin/Language/en/Soundbite.php
@@ -13,6 +13,10 @@ return [
         'title' => 'Soundbites',
         'soundbite' => 'Soundbite',
     ],
+    'messages' => [
+        'createSuccess' => 'Soundbite has been successfully created!',
+        'deleteSuccess' => 'Soundbite has been successfully removed!',
+    ],
     'form' => [
         'title' => 'New soundbite',
         'soundbite_title' => 'Soundbite title',
diff --git a/modules/Admin/Language/en/VideoClip.php b/modules/Admin/Language/en/VideoClip.php
index ef936401a4768d7b4e96000fe5207ba586bcad24..1f7644314ba2907b4dcb0e7708767dd81775e23f 100644
--- a/modules/Admin/Language/en/VideoClip.php
+++ b/modules/Admin/Language/en/VideoClip.php
@@ -34,6 +34,10 @@ return [
     'retry' => 'Retry clip generation',
     'delete' => 'Delete clip',
     'logs' => 'Job logs',
+    'messages' => [
+        'createSuccess' => 'Video clip has been successfully created!',
+        'deleteSuccess' => 'Video clip has been successfully removed!',
+    ],
     'form' => [
         'title' => 'New video clip',
         'params_section_title' => 'Video clip parameters',
diff --git a/modules/Admin/Language/fr/Contributor.php b/modules/Admin/Language/fr/Contributor.php
index 7e62309e4c9fb0a8e4fe73c485f063a0cbf4a302..1e73e9a11cc6d4327d44f11254d8835652307b56 100644
--- a/modules/Admin/Language/fr/Contributor.php
+++ b/modules/Admin/Language/fr/Contributor.php
@@ -32,9 +32,9 @@ return [
         'podcast_admin' => 'Administrateur de Podcasts',
     ],
     'messages' => [
-        'removeOwnerContributorError' =>
+        'removeOwnerError' =>
             'Vous ne pouvez pas retirer le propriétaire du podcast !',
-        'removeContributorSuccess' =>
+        'removeSuccess' =>
             'Vous avez retiré {username} de {podcastTitle}',
         'alreadyAddedError' =>
             'Le contributeur que vous essayez d’ajouter est déjà présent.',
diff --git a/modules/Admin/Language/fr/Episode.php b/modules/Admin/Language/fr/Episode.php
index 38cb216d1bc9ab2083b22fdd1c560cadece38da9..1ff5a800af82dad7b23c58efebc31a2b37e571fd 100644
--- a/modules/Admin/Language/fr/Episode.php
+++ b/modules/Admin/Language/fr/Episode.php
@@ -44,6 +44,10 @@ return [
         'comments' => 'Commentaires',
         'actions' => 'Actions',
     ],
+    'messages' => [
+        'createSuccess' => 'L’épisode a été créé avec succès !',
+        'editSuccess' => 'L’épisode a bien été mis à jour !',
+    ],
     'form' => [
         'warning' =>
             'En cas d’erreur fatale, essayez d’augmenter les valeurs de `memory_limit`, `upload_max_filesize` et `post_max_size` dans votre fichier de configuration php puis redémarrez votre serveur web.<br />Les valeurs doivent être plus grandes que le fichier audio que vous souhaitez téléverser.',
diff --git a/modules/Admin/Language/fr/Fediverse.php b/modules/Admin/Language/fr/Fediverse.php
index fa6b48972c7c5465fd0c89debac46fee159df9b6..1d647d3dc757dc765bff7e023d77a411af2765e3 100644
--- a/modules/Admin/Language/fr/Fediverse.php
+++ b/modules/Admin/Language/fr/Fediverse.php
@@ -9,6 +9,12 @@ declare(strict_types=1);
  */
 
 return [
+    'messages' => [
+        'blockActorSuccess' => '{actor} a été bloqué !',
+        'unblockActorSuccess' => 'L’utilisateur a été débloqué !',
+        'blockDomainSuccess' => '{domain} a été bloqué !',
+        'unblockDomainSuccess' => '{domain} a été débloqué !',
+    ],
     'block_lists' => 'Listes de blocage',
     'block_lists_form' => [
         'blocked_users' => 'Utilisateurs bloqués',
diff --git a/modules/Admin/Language/fr/Page.php b/modules/Admin/Language/fr/Page.php
index 2a0b21a5524de265775ac8234d9efe89002b19b2..6993274cb18004faac17505ccedf9c16df7690cb 100644
--- a/modules/Admin/Language/fr/Page.php
+++ b/modules/Admin/Language/fr/Page.php
@@ -24,6 +24,7 @@ return [
         'submit_edit' => 'Enregistrer',
     ],
     'messages' => [
-        'createSuccess' => 'La page {pageTitle} a été créée avec succès !',
+        'createSuccess' => 'La page “{pageTitle}” a été créée avec succès !',
+        'editSuccess' => 'La page a bien été mise à jour !',
     ],
 ];
diff --git a/modules/Admin/Language/fr/Person.php b/modules/Admin/Language/fr/Person.php
index aa77d8777a25f57dc7d032ad5db063549bdafb70..241e5dfee0e2e0199db1e16c87f6b2bd527ab94e 100644
--- a/modules/Admin/Language/fr/Person.php
+++ b/modules/Admin/Language/fr/Person.php
@@ -16,6 +16,11 @@ return [
     'view' => 'Voir l’intervenant',
     'edit' => 'Modifier l’intervenant',
     'delete' => 'Supprimer l’intervenant',
+    'messages' => [
+        'createSuccess' => 'L’intervenant a été créé avec succès !',
+        'editSuccess' => 'L’intervenant a bien été mis à jour !',
+        'deleteSuccess' => 'L’intervenant a bien été retiré !',
+    ],
     'form' => [
         'avatar' => 'Avatar',
         'avatar_size_hint' =>
diff --git a/modules/Admin/Language/fr/Podcast.php b/modules/Admin/Language/fr/Podcast.php
index 8129f592c39daea059af90823692ce61f2a767d3..211e9459e1fddf8e8755152bca79db746523b28e 100644
--- a/modules/Admin/Language/fr/Podcast.php
+++ b/modules/Admin/Language/fr/Podcast.php
@@ -22,6 +22,11 @@ return [
     'go_to_page' => 'Aller à la page',
     'latest_episodes' => 'Derniers épisodes',
     'see_all_episodes' => 'Voir tous les épisodes',
+    'messages' => [
+        'createSuccess' => 'Le podcast a été créé avec succès !',
+        'editSuccess' => 'Le podcast a bien été mis à jour !',
+        'importSuccess' => 'Le podcast a été importé avec succès !',
+    ],
     'form' => [
         'identity_section_title' => 'Informations sur le Podcast',
         'identity_section_subtitle' =>
diff --git a/modules/Admin/Language/fr/Soundbite.php b/modules/Admin/Language/fr/Soundbite.php
index 0cb3dddb95f394a28b6fdd01720f01300184db98..0445a06180c124b2e2e8d4cac64430cddfeacf64 100644
--- a/modules/Admin/Language/fr/Soundbite.php
+++ b/modules/Admin/Language/fr/Soundbite.php
@@ -13,6 +13,10 @@ return [
         'title' => 'Extraits sonores',
         'soundbite' => 'Extrait sonore',
     ],
+    'messages' => [
+        'createSuccess' => 'L’extrait sonore a été créé avec succès !',
+        'deleteSuccess' => 'L’extrait sonore a bien été supprimé !',
+    ],
     'form' => [
         'title' => 'Nouvel extrait sonore',
         'soundbite_title' => 'Titre de l’extrait',
diff --git a/modules/Admin/Language/fr/VideoClip.php b/modules/Admin/Language/fr/VideoClip.php
index c467714f834f7209c251beb0387ebc25261064e5..e2e1b79dc0959d5285ecf4ec353a294778f5a36e 100644
--- a/modules/Admin/Language/fr/VideoClip.php
+++ b/modules/Admin/Language/fr/VideoClip.php
@@ -34,6 +34,10 @@ return [
     'retry' => 'Relancer la génération de l’extrait',
     'delete' => 'Supprimer l’extrait',
     'logs' => 'Historique d’exécution',
+    'messages' => [
+        'createSuccess' => 'L’extrait vidéo a été créé avec succès !',
+        'deleteSuccess' => 'L’extrait vidéo a bien été supprimé !',
+    ],
     'form' => [
         'title' => 'Nouvel extrait vidéo',
         'params_section_title' => 'Paramètres de l’extrait vidéo',
diff --git a/modules/Fediverse/Controllers/BlockController.php b/modules/Fediverse/Controllers/BlockController.php
index 162cc56344a9a80e2ed6cc9e857a945cc5bafd35..9537edf212cb0cef3f763c6bb35fc1b0f5a93c21 100644
--- a/modules/Fediverse/Controllers/BlockController.php
+++ b/modules/Fediverse/Controllers/BlockController.php
@@ -42,14 +42,17 @@ class BlockController extends Controller
                 return redirect()
                     ->back()
                     ->withInput()
-                    ->with('error', 'Actor not found.');
+                    ->with('error', lang('Fediverse.messages.actorNotFound'));
             }
 
             model('ActorModel')
                 ->blockActor($actor->id);
         }
 
-        return redirect()->back();
+        return redirect()->back()
+            ->with('message', lang('Fediverse.messages.blockActorSuccess', [
+                'actor' => $handle,
+            ]));
     }
 
     public function attemptUnblockActor(): RedirectResponse
@@ -68,7 +71,8 @@ class BlockController extends Controller
         model('ActorModel')
             ->unblockActor((int) $this->request->getPost('actor_id'));
 
-        return redirect()->back();
+        return redirect()->back()
+            ->with('message', lang('Fediverse.messages.unblockActorSuccess'));
     }
 
     public function attemptBlockDomain(): RedirectResponse
@@ -84,10 +88,14 @@ class BlockController extends Controller
                 ->with('errors', $this->validator->getErrors());
         }
 
+        $domain = $this->request->getPost('domain');
         model('BlockedDomainModel')
-            ->blockDomain($this->request->getPost('domain'));
+            ->blockDomain($domain);
 
-        return redirect()->back();
+        return redirect()->back()
+            ->with('message', lang('Fediverse.messages.blockDomainSuccess', [
+                'domain' => $domain,
+            ]));
     }
 
     public function attemptUnblockDomain(): RedirectResponse
@@ -103,9 +111,13 @@ class BlockController extends Controller
                 ->with('errors', $this->validator->getErrors());
         }
 
+        $domain = $this->request->getPost('domain');
         model('BlockedDomainModel')
-            ->unblockDomain($this->request->getPost('domain'));
+            ->unblockDomain($domain);
 
-        return redirect()->back();
+        return redirect()->back()
+            ->with('message', lang('Fediverse.messages.unblockDomainSuccess', [
+                'domain' => $domain,
+            ]));
     }
 }
diff --git a/modules/Fediverse/Controllers/PostController.php b/modules/Fediverse/Controllers/PostController.php
index 4240e9f7bf2ea134bce58fd1ef8c2cdf75bf3ca6..c375111c8e9630a8499408e8f54c8ce3348474ef 100644
--- a/modules/Fediverse/Controllers/PostController.php
+++ b/modules/Fediverse/Controllers/PostController.php
@@ -124,12 +124,13 @@ class PostController extends Controller
             'published_at' => Time::now(),
         ]);
 
-        if (! model('PostModel')->addPost($newPost)) {
+        $postModel = model('PostModel');
+        if (! $postModel->addPost($newPost)) {
             return redirect()
                 ->back()
                 ->withInput()
                 // TODO: translate
-                ->with('error', "Couldn't create Post");
+                ->with('error', $postModel->errors());
         }
 
         // Post without preview card has been successfully created
diff --git a/themes/cp_admin/episode/_card.php b/themes/cp_admin/episode/_card.php
index 20a2e9f9f799df83dcc6f7c16c329757a853f3c3..43199d555383c033c879420afbb8662f0242b3e8 100644
--- a/themes/cp_admin/episode/_card.php
+++ b/themes/cp_admin/episode/_card.php
@@ -34,8 +34,13 @@
         ],
         [
             'type' => 'link',
-            'title' => lang('Episode.soundbites'),
-            'uri' => route_to('soundbites-edit', $episode->podcast->id, $episode->id),
+            'title' => lang('VideoClip.list.title'),
+            'uri' => route_to('video-clips-list', $episode->podcast->id, $episode->id),
+        ],
+        [
+            'type' => 'link',
+            'title' => lang('Soundbite.list.title'),
+            'uri' => route_to('soundbites-list', $episode->podcast->id, $episode->id),
         ],
         [
             'type' => 'separator',
diff --git a/themes/cp_admin/episode/list.php b/themes/cp_admin/episode/list.php
index 3ca83c14d4b91e692798ed147f119eeba5d3a328..81ab34e8c33e0863864e4480d249c2aec071ab07 100644
--- a/themes/cp_admin/episode/list.php
+++ b/themes/cp_admin/episode/list.php
@@ -99,8 +99,13 @@
                             ],
                             [
                                 'type' => 'link',
-                                'title' => lang('Episode.soundbites'),
-                                'uri' => route_to('soundbites-edit', $podcast->id, $episode->id),
+                                'title' => lang('VideoClip.list.title'),
+                                'uri' => route_to('video-clips-list', $episode->podcast->id, $episode->id),
+                            ],
+                            [
+                                'type' => 'link',
+                                'title' => lang('Soundbite.list.title'),
+                                'uri' => route_to('soundbites-list', $podcast->id, $episode->id),
                             ],
                             [
                                 'type' => 'separator',
diff --git a/themes/cp_admin/episode/persons.php b/themes/cp_admin/episode/persons.php
index 534d0af9dc5baf780ec942ddfcb8c6fb5d39b499..57f57ce3e51e963430aef08e064c27b119271f58 100644
--- a/themes/cp_admin/episode/persons.php
+++ b/themes/cp_admin/episode/persons.php
@@ -28,8 +28,8 @@
         name="persons[]"
         label="<?= lang('Person.episode_form.persons') ?>"
         hint="<?= lang('Person.episode_form.persons_hint') ?>"
-        options="<?= htmlspecialchars(json_encode($personOptions)) ?>"
-        selected="<?= htmlspecialchars(json_encode(old('persons', []))) ?>"
+        options="<?= esc(json_encode($personOptions)) ?>"
+        selected="<?= esc(json_encode(old('persons', []))) ?>"
         required="true"
     />
 
@@ -39,8 +39,8 @@
         name="roles[]"
         label="<?= lang('Person.episode_form.roles') ?>"
         hint="<?= lang('Person.episode_form.roles_hint') ?>"
-        options="<?= htmlspecialchars(json_encode($taxonomyOptions)) ?>"
-        selected="<?= htmlspecialchars(json_encode(old('roles', []))) ?>"
+        options="<?= esc(json_encode($taxonomyOptions)) ?>"
+        selected="<?= esc(json_encode(old('roles', []))) ?>"
         required="true"
     />
 
diff --git a/themes/cp_admin/person/edit.php b/themes/cp_admin/person/edit.php
index 803bd98439a132c70109b82d9e5ccc4d45457b13..2c23a2eaf5dc95f16628d645dfbdea3a6757703e 100644
--- a/themes/cp_admin/person/edit.php
+++ b/themes/cp_admin/person/edit.php
@@ -34,7 +34,8 @@
     value="<?= $person->unique_name ?>"
     label="<?= lang('Person.form.unique_name') ?>"
     hint="<?= lang('Person.form.unique_name_hint') ?>"
-    required="true" />
+    required="true"
+    data-slugify="slug" />
 
 <Forms.Field
     name="information_url"
diff --git a/themes/cp_admin/podcast/edit.php b/themes/cp_admin/podcast/edit.php
index 682febfa453cf2a3ba5650ccbab40ae4f16e8ed2..6b7aea1361c73c48c5f04899b3c6af1bf071ac95 100644
--- a/themes/cp_admin/podcast/edit.php
+++ b/themes/cp_admin/podcast/edit.php
@@ -107,13 +107,13 @@
         selected="<?= $podcast->category_id ?>"
         options="<?= esc(json_encode($categoryOptions)) ?>"
         required="true" />
-
+    
     <Forms.Field
         as="MultiSelect"
         name="other_categories[]"
         label="<?= lang('Podcast.form.other_categories') ?>"
-        selected="<?= json_encode($podcast->other_categories_ids) ?>"
         data-max-item-count="2"
+        selected="<?= esc(json_encode($podcast->other_categories_ids)) ?>"
         options="<?= esc(json_encode($categoryOptions)) ?>" />
 
     <fieldset class="mb-4">
diff --git a/themes/cp_admin/user/edit.php b/themes/cp_admin/user/edit.php
index 1331e2378d17829ff203c9e546a43344f06c824b..3fdd98bc61be749a7144eefa9d574c111f17d01c 100644
--- a/themes/cp_admin/user/edit.php
+++ b/themes/cp_admin/user/edit.php
@@ -19,6 +19,7 @@
 <?= csrf_field() ?>
 
 <Forms.Field
+    as="MultiSelect"
     id="roles"
     name="roles[]"
     label="<?= lang('User.form.roles') ?>"
@@ -26,7 +27,7 @@
     options="<?= esc(json_encode($roleOptions)) ?>"
     selected="<?= esc(json_encode($user->roles)) ?>" />
 
-<Button variant="primary" type="submit" class="self-end"><?= lang('User.form.submit_edit') ?></Button>
+<Button variant="primary" type="submit" class="self-end mt-4"><?= lang('User.form.submit_edit') ?></Button>
 
 </form>