From 51298cd6bc100b1cc6508abb602a59c01a9e2c04 Mon Sep 17 00:00:00 2001 From: Stefan <11146296+tryallthethings@users.noreply.github.com> Date: Sun, 22 Jun 2025 00:36:32 +0200 Subject: Exposed the reading modes for extensions through Minz (#7668) * + Exposed the reading modes for extensions through Minz. Now extensions can add a custom view mode. Graceful fallback to normal view in case the extension was disabled without resetting the view_mode through the uninstall method. In that case the user will be informed via Minz_Request::setBadNotification that the view has been reset to normal. + Added translation strings for de, en and en-us for the notification * + Added missing, generated translations * Simplify indexAction, performance * Minor settings htmlspecialchars * i18n: fr * Minor wording * Doc * Fix i18n --------- Co-authored-by: Alexandre Alapetite --- app/Controllers/configureController.php | 1 + app/Controllers/indexController.php | 12 +++++- app/Models/View.php | 4 ++ app/Models/ViewMode.php | 65 +++++++++++++++++++++++++++++++++ app/i18n/cs/feedback.php | 1 + app/i18n/de/feedback.php | 1 + app/i18n/el/feedback.php | 1 + app/i18n/en-us/feedback.php | 1 + app/i18n/en/feedback.php | 1 + app/i18n/es/feedback.php | 1 + app/i18n/fa/feedback.php | 1 + app/i18n/fi/feedback.php | 1 + app/i18n/fr/feedback.php | 1 + app/i18n/he/feedback.php | 1 + app/i18n/hu/feedback.php | 1 + app/i18n/id/feedback.php | 1 + app/i18n/it/feedback.php | 1 + app/i18n/ja/feedback.php | 1 + app/i18n/ko/feedback.php | 1 + app/i18n/lv/feedback.php | 1 + app/i18n/nl/feedback.php | 1 + app/i18n/oc/feedback.php | 1 + app/i18n/pl/feedback.php | 1 + app/i18n/pt-br/feedback.php | 1 + app/i18n/pt-pt/feedback.php | 1 + app/i18n/ru/feedback.php | 1 + app/i18n/sk/feedback.php | 1 + app/i18n/tr/feedback.php | 1 + app/i18n/zh-cn/feedback.php | 1 + app/i18n/zh-tw/feedback.php | 1 + app/views/configure/reading.phtml | 16 ++++++-- 31 files changed, 119 insertions(+), 5 deletions(-) create mode 100644 app/Models/ViewMode.php (limited to 'app') diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php index 4f448c5e0..59845d710 100644 --- a/app/Controllers/configureController.php +++ b/app/Controllers/configureController.php @@ -160,6 +160,7 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController { Minz_Request::good(_t('feedback.conf.updated'), [ 'c' => 'configure', 'a' => 'reading' ]); } + $this->view->viewModes = FreshRSS_ViewMode::getAllModes(); FreshRSS_View::prependTitle(_t('conf.reading.title') . ' · '); } diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php index 661e8300b..d5d9db778 100644 --- a/app/Controllers/indexController.php +++ b/app/Controllers/indexController.php @@ -16,9 +16,17 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController { */ public function indexAction(): void { $preferred_output = FreshRSS_Context::userConf()->view_mode; + $viewMode = FreshRSS_ViewMode::getAllModes()[$preferred_output] ?? null; + + // Fallback to 'normal' if the preferred mode was not found + if ($viewMode === null) { + Minz_Request::setBadNotification(_t('feedback.extensions.invalid_view_mode', $preferred_output)); + $viewMode = FreshRSS_ViewMode::getAllModes()['normal']; + } + Minz_Request::forward([ - 'c' => 'index', - 'a' => $preferred_output, + 'c' => $viewMode->controller(), + 'a' => $viewMode->action(), ]); } diff --git a/app/Models/View.php b/app/Models/View.php index dd616b888..11ca3a105 100644 --- a/app/Models/View.php +++ b/app/Models/View.php @@ -132,4 +132,8 @@ class FreshRSS_View extends Minz_View { public string $errorMessage; /** @var array */ public array $message; + + // View modes + /** @var array */ + public array $viewModes; } diff --git a/app/Models/ViewMode.php b/app/Models/ViewMode.php new file mode 100644 index 000000000..54379b130 --- /dev/null +++ b/app/Models/ViewMode.php @@ -0,0 +1,65 @@ +id = $id; + $this->name = $name; + $this->controller = $controller; + $this->action = $action ?: $id; + } + + public function id(): string { + return $this->id; + } + + public function name(): string { + return $this->name; + } + + public function controller(): string { + return $this->controller; + } + + public function action(): string { + return $this->action; + } + + /** + * @return array Mode ID => FreshRSS_ViewMode + */ + public static function getDefaultModes(): array { + return [ + 'normal' => new self(id: 'normal', name: _t('conf.reading.view.normal'), controller: 'index', action: 'normal'), + 'reader' => new self(id: 'reader', name: _t('conf.reading.view.reader'), controller: 'index', action: 'reader'), + 'global' => new self(id: 'global', name: _t('conf.reading.view.global'), controller: 'index', action: 'global'), + ]; + } + + /** + * @return array Mode ID => FreshRSS_ViewMode + */ + public static function getAllModes(): array { + $modes = self::getDefaultModes(); + + // Allow extensions to add their own view modes + $extensionModes = Minz_ExtensionManager::callHook('view_modes', []); + if (is_array($extensionModes)) { + foreach ($extensionModes as $mode) { + if ($mode instanceof FreshRSS_ViewMode) { + $modes[$mode->id()] = $mode; + } + } + } + + return $modes; + } +} diff --git a/app/i18n/cs/feedback.php b/app/i18n/cs/feedback.php index e12db7b9b..3f0866e0c 100644 --- a/app/i18n/cs/feedback.php +++ b/app/i18n/cs/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s nelze povolit. Pro podrobnosti zkontrolujte protokoly FreshRSS.', 'ok' => '%s je nyní povoleno', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'Nemáte přístup k %s', 'not_enabled' => '%s není povoleno', 'not_found' => '%s neexistuje', diff --git a/app/i18n/de/feedback.php b/app/i18n/de/feedback.php index 5cf2302fe..201d75f80 100644 --- a/app/i18n/de/feedback.php +++ b/app/i18n/de/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s kann nicht aktiviert werden. Für Details prüfen Sie die FreshRSS-Protokolle.', 'ok' => '%s ist jetzt aktiviert', ), + 'invalid_view_mode' => 'Ungültige Standard-Ansicht %s gefunden. Setze Standard-Ansicht auf Normale Ansicht zurück.', 'no_access' => 'Sie haben keinen Zugang zu %s', 'not_enabled' => '%s ist noch nicht aktiviert', 'not_found' => '%s existiert nicht', diff --git a/app/i18n/el/feedback.php b/app/i18n/el/feedback.php index f6481c077..f1cd8ecc8 100644 --- a/app/i18n/el/feedback.php +++ b/app/i18n/el/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s cannot be enabled. Check FreshRSS logs for details.', // TODO 'ok' => '%s is now enabled', // TODO ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'You have no access on %s', // TODO 'not_enabled' => '%s is not enabled', // TODO 'not_found' => '%s does not exist', // TODO diff --git a/app/i18n/en-us/feedback.php b/app/i18n/en-us/feedback.php index f16ffd5f5..2e2dad8ea 100644 --- a/app/i18n/en-us/feedback.php +++ b/app/i18n/en-us/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s cannot be enabled. Check FreshRSS logs for details.', // IGNORE 'ok' => '%s is now enabled', // IGNORE ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // IGNORE 'no_access' => 'You have no access on %s', // IGNORE 'not_enabled' => '%s is not enabled', // IGNORE 'not_found' => '%s does not exist', // IGNORE diff --git a/app/i18n/en/feedback.php b/app/i18n/en/feedback.php index 10ec302c2..e5f0123d1 100644 --- a/app/i18n/en/feedback.php +++ b/app/i18n/en/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s cannot be enabled. Check FreshRSS logs for details.', 'ok' => '%s is now enabled', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', 'no_access' => 'You have no access on %s', 'not_enabled' => '%s is not enabled', 'not_found' => '%s does not exist', diff --git a/app/i18n/es/feedback.php b/app/i18n/es/feedback.php index 9c2df5294..84712d16b 100644 --- a/app/i18n/es/feedback.php +++ b/app/i18n/es/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s no se puede activar. Revisa el registro de FreshRSS para más información.', 'ok' => '%s ha quedado activado', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'No tienes acceso a %s', 'not_enabled' => '%s no está activado', 'not_found' => '%s no existe', diff --git a/app/i18n/fa/feedback.php b/app/i18n/fa/feedback.php index 5d2f6b6a4..57a69a8a7 100644 --- a/app/i18n/fa/feedback.php +++ b/app/i18n/fa/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => ' %s را نمی توان فعال کرد. برای جزئیات گزارش‌های FreshRSS را بررسی کنید.', 'ok' => ' %s اکنون فعال است', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => ' شما به %s دسترسی ندارید', 'not_enabled' => '%s فعال نیست', 'not_found' => '%s وجود ندارد', diff --git a/app/i18n/fi/feedback.php b/app/i18n/fi/feedback.php index 4f62b2362..d2e694ed5 100644 --- a/app/i18n/fi/feedback.php +++ b/app/i18n/fi/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => 'Laajennusta %s ei voi ottaa käyttöön. Lisätietoja on FreshRSS-lokeissa.', 'ok' => '%s on nyt otettu käyttöön', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'Sinulla ei ole laajennuksen %s käyttöoikeutta', 'not_enabled' => 'Laajennus %s ei ole käytössä', 'not_found' => 'Laajennusta %s ei ole', diff --git a/app/i18n/fr/feedback.php b/app/i18n/fr/feedback.php index d5e05b5c5..99edb39bf 100644 --- a/app/i18n/fr/feedback.php +++ b/app/i18n/fr/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s ne peut pas être activée. Consulter les logs de FreshRSS pour plus de détails.', 'ok' => '%s est désormais activée', ), + 'invalid_view_mode' => 'Mode de vue “%s” invalide ! Passage en “Vue normale”.', 'no_access' => 'Vous n’avez aucun accès sur %s', 'not_enabled' => '%s n’est pas encore activée', 'not_found' => '%s n’existe pas', diff --git a/app/i18n/he/feedback.php b/app/i18n/he/feedback.php index e017a7243..dcc2c413c 100644 --- a/app/i18n/he/feedback.php +++ b/app/i18n/he/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s cannot be enabled. Check FreshRSS logs for details.', // TODO 'ok' => '%s is now enabled', // TODO ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'You have no access on %s', // TODO 'not_enabled' => '%s is not enabled yet', 'not_found' => '%s does not exist', // TODO diff --git a/app/i18n/hu/feedback.php b/app/i18n/hu/feedback.php index 8cc404395..db0e1907a 100755 --- a/app/i18n/hu/feedback.php +++ b/app/i18n/hu/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => 'A(z) %s nem kapcsolható be. nézd meg a FreshRSS log-okat a részletekért.', 'ok' => 'A(z) %s bekapcsolása sikeres', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'Nincs hozzáférésed ehhez: %s', 'not_enabled' => 'A(z) %s nincs bekapcsolva', 'not_found' => 'A(z) %s nem létezik', diff --git a/app/i18n/id/feedback.php b/app/i18n/id/feedback.php index 224a1dc3b..6e2e8efa6 100644 --- a/app/i18n/id/feedback.php +++ b/app/i18n/id/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s cannot be enabled. Check FreshRSS logs for details.', // TODO 'ok' => '%s is now enabled', // TODO ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'You have no access on %s', // TODO 'not_enabled' => '%s is not enabled', // TODO 'not_found' => '%s does not exist', // TODO diff --git a/app/i18n/it/feedback.php b/app/i18n/it/feedback.php index bb334c6df..5b6092e7f 100644 --- a/app/i18n/it/feedback.php +++ b/app/i18n/it/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s non può essere abilitata. Verifica i logs per dettagli.', 'ok' => '%s è ora abilitata', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'Accesso negato a %s', 'not_enabled' => '%s non abilitato', 'not_found' => '%s non disponibile', diff --git a/app/i18n/ja/feedback.php b/app/i18n/ja/feedback.php index df2bc9eda..13bbd5fab 100644 --- a/app/i18n/ja/feedback.php +++ b/app/i18n/ja/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%sは有効にできません。 FreshRSS のログを確認してください 詳細が表示されます。', 'ok' => '%sは有効にされています。', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'あなたは%sにアクセスする権限がありません', 'not_enabled' => '%sは有効にされていません', 'not_found' => '%sは存在しません', diff --git a/app/i18n/ko/feedback.php b/app/i18n/ko/feedback.php index 4cd62254c..457731a97 100644 --- a/app/i18n/ko/feedback.php +++ b/app/i18n/ko/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s 확장 기능을 활성화 할 수 없습니다. 자세한 내용은 FreshRSS 로그를 참고하세요.', 'ok' => '%s 확장 기능이 활성화되었습니다', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => '%s 확장 기능에 접근 권한이 없습니다', 'not_enabled' => '%s 확장 기능이 활성화되지 않았습니다', 'not_found' => '%s 확장 기능이 존재하지 않습니다', diff --git a/app/i18n/lv/feedback.php b/app/i18n/lv/feedback.php index f359f0306..861cf1e06 100644 --- a/app/i18n/lv/feedback.php +++ b/app/i18n/lv/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s nevar būt ieslēgts. Pārbaudiet FreshRSS žurnālu priekš papildu informācijas.', 'ok' => '%s ir tagad ieslēgts', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'Jums nav piekļuves %s', 'not_enabled' => '%s nav ieslēgts', 'not_found' => '%s nēeksistē', diff --git a/app/i18n/nl/feedback.php b/app/i18n/nl/feedback.php index fa55dc9ba..39ed01e28 100644 --- a/app/i18n/nl/feedback.php +++ b/app/i18n/nl/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s kan niet worden ingeschakeld. Controleer FreshRSS log bestanden voor details.', 'ok' => '%s is nn ingeschakeld', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'U hebt geen toegang voor %s', 'not_enabled' => '%s is nog niet ingeschakeld', 'not_found' => '%s bestaat niet', diff --git a/app/i18n/oc/feedback.php b/app/i18n/oc/feedback.php index 5d7d277df..e158cc299 100644 --- a/app/i18n/oc/feedback.php +++ b/app/i18n/oc/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s pòt pas èsser activada. Consultatz los jornals d’audit de FreshRSS logs per mai de detalhs.', 'ok' => '%s es ara activada', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'Avètz pas accès sus %s', 'not_enabled' => '%s es pas encara activada', 'not_found' => '%s existís pas', diff --git a/app/i18n/pl/feedback.php b/app/i18n/pl/feedback.php index 291114fd3..70a6842f1 100644 --- a/app/i18n/pl/feedback.php +++ b/app/i18n/pl/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => 'Rozszerzenie %s nie może zostać włączone. Sprawdź dziennik w celu uzyskania szczegółowych informacji.', 'ok' => 'Rozszerzenie %s zostało włączone', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'Brak dostępu do %s', 'not_enabled' => 'Rozszerzenie %s nie jest włączone', 'not_found' => 'Rozszerzenie %s nie istnieje', diff --git a/app/i18n/pt-br/feedback.php b/app/i18n/pt-br/feedback.php index 9533189a8..562efb0b6 100644 --- a/app/i18n/pt-br/feedback.php +++ b/app/i18n/pt-br/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s não pode ser habilitado. verifique os logs do FreshRSS para detalhes.', 'ok' => '%s agora está habilitado', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'Você não tem acesso ao %s', 'not_enabled' => '%s não está habilitado', 'not_found' => '%s não existe', diff --git a/app/i18n/pt-pt/feedback.php b/app/i18n/pt-pt/feedback.php index 22f96cee5..995947f9f 100644 --- a/app/i18n/pt-pt/feedback.php +++ b/app/i18n/pt-pt/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s não pode ser activado. verifique os logs do FreshRSS para detalhes.', 'ok' => '%s agora está activado', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => ' não tem acesso ao %s', 'not_enabled' => '%s não está habilitado', 'not_found' => '%s não existe', diff --git a/app/i18n/ru/feedback.php b/app/i18n/ru/feedback.php index d7b76c63c..4e3e61c57 100644 --- a/app/i18n/ru/feedback.php +++ b/app/i18n/ru/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s не может быть включено. Проверьте логи FreshRSS для подробностей.', 'ok' => '%s теперь включено', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'У вас нет доступа к %s', 'not_enabled' => '%s не включено', 'not_found' => '%s не существует', diff --git a/app/i18n/sk/feedback.php b/app/i18n/sk/feedback.php index 0ab41684a..a1d63cca9 100644 --- a/app/i18n/sk/feedback.php +++ b/app/i18n/sk/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s sa nepodarilo povoliť. Prečítajte si záznamy FreshRSS, ak chcete poznať podrobnosti.', 'ok' => '%s je teraz povolený', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => 'Nemáte prístup k %s', 'not_enabled' => '%s nie je povolený', 'not_found' => '%s neexistuje', diff --git a/app/i18n/tr/feedback.php b/app/i18n/tr/feedback.php index d65dd530f..19ac11e3b 100644 --- a/app/i18n/tr/feedback.php +++ b/app/i18n/tr/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s etkinleştirilemedi. Ayrıntılar için FreshRSS günlüklerini kontrol edin.', 'ok' => '%s artık etkin', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => '%s üzerinde erişiminiz yok', 'not_enabled' => '%s etkin değil', 'not_found' => '%s mevcut değil', diff --git a/app/i18n/zh-cn/feedback.php b/app/i18n/zh-cn/feedback.php index 07e0130cf..2d726d22a 100644 --- a/app/i18n/zh-cn/feedback.php +++ b/app/i18n/zh-cn/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s 启用失败。检查 FreshRSS 日志 查看详情。', 'ok' => '%s 现已启用', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => '你无权访问 %s', 'not_enabled' => '%s 未启用', 'not_found' => '%s 不存在', diff --git a/app/i18n/zh-tw/feedback.php b/app/i18n/zh-tw/feedback.php index 9404c83bb..d43e6efbd 100644 --- a/app/i18n/zh-tw/feedback.php +++ b/app/i18n/zh-tw/feedback.php @@ -50,6 +50,7 @@ return array( 'ko' => '%s 啟用失敗。檢查 FreshRSS 日誌 查看詳情。', 'ok' => '%s 現已啟用', ), + 'invalid_view_mode' => 'Invalid view mode “%s”! Fall back to “Normal view”.', // TODO 'no_access' => '你無權訪問 %s', 'not_enabled' => '%s 未啟用', 'not_found' => '%s 不存在', diff --git a/app/views/configure/reading.phtml b/app/views/configure/reading.phtml index dc67874b0..c31cfda0b 100644 --- a/app/views/configure/reading.phtml +++ b/app/views/configure/reading.phtml @@ -14,9 +14,19 @@
-- cgit v1.2.3