diff --git a/changelog/62_UNRELEASED_xxxx-xx-xx.md b/changelog/62_UNRELEASED_xxxx-xx-xx.md index 57650f91..be79228b 100644 --- a/changelog/62_UNRELEASED_xxxx-xx-xx.md +++ b/changelog/62_UNRELEASED_xxxx-xx-xx.md @@ -65,6 +65,7 @@ - Fixed that the number picker up/down buttons did not work when the input field was empty or contained an invalid number - Fixed that links and embeds (e.g. YouTube videos) did not work in the text editor -### API fixes +### API improvements/fixes +- Added a new API endpoint `/system/localization-strings` to get the localization strings (gettext JSON representation; in the by the user desired language) - Fixed that due soon products with `due_type` = "Expiration date" were missing in `due_products` of the `/stock/volatile` endpoint - Fixed that `PUT/DELETE /objects/{entity}/{objectId}` produced an internal server error when the given object id was invalid (now returns `400 Bad Request`) diff --git a/controllers/BaseApiController.php b/controllers/BaseApiController.php index f902e866..c0ff0963 100644 --- a/controllers/BaseApiController.php +++ b/controllers/BaseApiController.php @@ -17,8 +17,13 @@ class BaseApiController extends BaseController parent::__construct($container); } - protected function ApiResponse(\Psr\Http\Message\ResponseInterface $response, $data) + protected function ApiResponse(\Psr\Http\Message\ResponseInterface $response, $data, $cache = false) { + if ($cache) + { + $response = $response->withHeader('Cache-Control', 'max-age=2592000'); + } + $response->getBody()->write(json_encode($data)); return $response; } diff --git a/controllers/BaseController.php b/controllers/BaseController.php index e2556d50..7836fe9c 100644 --- a/controllers/BaseController.php +++ b/controllers/BaseController.php @@ -129,7 +129,6 @@ class BaseController $this->View->set('__n', function ($number, $singularForm, $pluralForm) use ($localizationService) { return $localizationService->__n($number, $singularForm, $pluralForm); }); - $this->View->set('GettextPo', $localizationService->GetPoAsJsonString()); // TODO: Better handle this generically based on the current language (header in .po file?) $dir = 'ltr'; diff --git a/controllers/SystemApiController.php b/controllers/SystemApiController.php index 5ff7a187..51019c95 100644 --- a/controllers/SystemApiController.php +++ b/controllers/SystemApiController.php @@ -85,6 +85,11 @@ class SystemApiController extends BaseApiController } } + public function GetLocalizationStrings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args) + { + return $this->ApiResponse($response, json_decode($this->getLocalizationService()->GetPoAsJsonString()), true); + } + public function __construct(\DI\Container $container) { parent::__construct($container); diff --git a/grocy.openapi.json b/grocy.openapi.json index 4cf50bc6..da36158e 100644 --- a/grocy.openapi.json +++ b/grocy.openapi.json @@ -184,6 +184,27 @@ } } }, + "/system/localization-strings": { + "get": { + "summary": "Returns all localization strings (in the by the user desired language)", + "tags": [ + "System" + ], + "responses": { + "200": { + "description": "The operation was successful", + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "A gettext JSON representation" + } + } + } + } + } + } + }, "/system/log-missing-localization": { "post": { "summary": "Logs a missing localization string", diff --git a/public/js/grocy.js b/public/js/grocy.js index 46a5b5e8..2e15bda9 100644 --- a/public/js/grocy.js +++ b/public/js/grocy.js @@ -226,7 +226,22 @@ Grocy.Api.DeleteFile = function(fileName, group, success, error) xhr.send(); }; -Grocy.Translator = new Translator(Grocy.GettextPo); +U = function(relativePath) +{ + return Grocy.BaseUrl.replace(/\/$/, '') + relativePath; +} + +Grocy.Translator = new Translator(); // Dummy, real instance is loaded async below +Grocy.Api.Get("system/localization-strings?v=" + Grocy.Version, + function(response) + { + Grocy.Translator = new Translator(response); + }, + function(xhr) + { + console.error(xhr); + } +); __t = function(text, ...placeholderValues) { if (Grocy.Mode === "dev") @@ -248,11 +263,6 @@ __n = function(number, singularForm, pluralForm) return Grocy.Translator.n__(singularForm, pluralForm, number, number) } -U = function(relativePath) -{ - return Grocy.BaseUrl.replace(/\/$/, '') + relativePath; -} - if (!Grocy.ActiveNav.isEmpty()) { var menuItem = $('#sidebarResponsive').find("[data-nav-for-page='" + Grocy.ActiveNav + "']"); diff --git a/routes.php b/routes.php index 8268958a..2fd054f1 100644 --- a/routes.php +++ b/routes.php @@ -151,6 +151,7 @@ $app->group('/api', function (RouteCollectorProxy $group) { $group->get('/system/db-changed-time', '\Grocy\Controllers\SystemApiController:GetDbChangedTime'); $group->get('/system/config', '\Grocy\Controllers\SystemApiController:GetConfig'); $group->post('/system/log-missing-localization', '\Grocy\Controllers\SystemApiController:LogMissingLocalization'); + $group->get('/system/localization-strings', '\Grocy\Controllers\SystemApiController:GetLocalizationStrings'); // Generic entity interaction $group->get('/objects/{entity}', '\Grocy\Controllers\GenericEntityApiController:GetObjects'); diff --git a/views/layout/default.blade.php b/views/layout/default.blade.php index c3c0f225..a7be1059 100644 --- a/views/layout/default.blade.php +++ b/views/layout/default.blade.php @@ -85,6 +85,7 @@