From 1553d52593fde8f9acd46f353c12422528d6e50d Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Tue, 9 Jan 2024 23:13:23 +0400 Subject: [PATCH] Lazy translation during error response generation Now when parameterized messages are added to an error response, they are not immediately instantiated (translated). Instead the message id and the parameters of the message are recorded. The instantiation of the messages happens right before generating the final content of the response. --- src/server/i18n.h | 3 +++ src/server/response.cpp | 45 ++++++++++++++++++++++++++++++++--------- src/server/response.h | 3 --- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/server/i18n.h b/src/server/i18n.h index 7eeb0205a..1e42cac68 100644 --- a/src/server/i18n.h +++ b/src/server/i18n.h @@ -107,6 +107,9 @@ public: // functions std::string getText(const std::string& lang) const; + const std::string& getMsgId() const { return msgId; } + const Parameters& getParams() const { return params; } + private: // data const std::string msgId; const Parameters params; diff --git a/src/server/response.cpp b/src/server/response.cpp index ce418d54c..53584349b 100644 --- a/src/server/response.cpp +++ b/src/server/response.cpp @@ -183,6 +183,18 @@ public: return s.empty() ? Data(false) : Data(s); } + static Data from(const ParameterizedMessage& pmsg) + { + Object obj; + for(const auto& kv : pmsg.getParams()) { + obj[kv.first] = kv.second; + } + return Object{ + { "msgid", pmsg.getMsgId() }, + { "params", Data(obj) } + }; + } + private: bool isString() const { return std::holds_alternative(data); } bool isList() const { return std::holds_alternative(data); } @@ -192,6 +204,16 @@ private: bool boolValue() const { return std::get(data); } const List& listValue() const { return std::get(data); } const Object& objectValue() const { return std::get(data); } + + const Data* get(const std::string& key) const + { + if ( !isObject() ) + return nullptr; + + const auto& obj = objectValue(); + const auto it = obj.find(key); + return it != obj.end() ? &it->second : nullptr; + } }; MustacheData ContentResponseBlueprint::Data::toMustache(const std::string& lang) const @@ -203,11 +225,22 @@ MustacheData ContentResponseBlueprint::Data::toMustache(const std::string& lang) } return l; } else if ( this->isObject() ) { + const Data* msgId = this->get("msgid"); + const Data* msgParams = this->get("params"); + if ( msgId && msgId->isString() && msgParams && msgParams->isObject() ) { + std::map params; + for(const auto& kv : msgParams->objectValue()) { + params[kv.first] = kv.second.stringValue(); + } + const ParameterizedMessage msg(msgId->stringValue(), ParameterizedMessage::Parameters(params)); + return msg.getText(lang); + } else { kainjow::mustache::object o; for ( const auto& kv : this->objectValue() ) { o[kv.first] = kv.second.toMustache(lang); } return o; + } } else if ( this->isString() ) { return this->stringValue(); } else { @@ -229,11 +262,6 @@ ContentResponseBlueprint::ContentResponseBlueprint(const RequestContext* request ContentResponseBlueprint::~ContentResponseBlueprint() = default; -std::string ContentResponseBlueprint::getMessage(const std::string& msgId) const -{ - return getTranslatedString(m_request.get_user_language(), msgId); -} - std::unique_ptr ContentResponseBlueprint::generateResponseObject() const { kainjow::mustache::data d = m_data->toMustache(m_request.get_user_language()); @@ -255,8 +283,8 @@ HTTPErrorResponse::HTTPErrorResponse(const RequestContext& request, Data::List emptyList; *this->m_data = Data(Data::Object{ {"CSS_URL", Data::onlyAsNonEmptyValue(cssUrl) }, - {"PAGE_TITLE", getMessage(pageTitleMsgId)}, - {"PAGE_HEADING", getMessage(headingMsgId)}, + {"PAGE_TITLE", Data::from(nonParameterizedMessage(pageTitleMsgId))}, + {"PAGE_HEADING", Data::from(nonParameterizedMessage(headingMsgId))}, {"details", emptyList} }); } @@ -278,8 +306,7 @@ UrlNotFoundResponse::UrlNotFoundResponse(const RequestContext& request) HTTPErrorResponse& HTTPErrorResponse::operator+(const ParameterizedMessage& details) { - const std::string msg = details.getText(m_request.get_user_language()); - (*m_data)["details"].push_back(Data::Object{{"p", msg}}); + (*m_data)["details"].push_back(Data::Object{{"p", Data::from(details)}}); return *this; } diff --git a/src/server/response.h b/src/server/response.h index 726a51668..e239173df 100644 --- a/src/server/response.h +++ b/src/server/response.h @@ -135,9 +135,6 @@ public: // functions protected: // types class Data; -protected: // functions - std::string getMessage(const std::string& msgId) const; - protected: //data const RequestContext& m_request; const int m_httpStatusCode;