Started translation of the new 404 error page

- Enabled translation on the new 404 error page
- Translated its title & heading

This commit also fixes the failure of the ServerTest.UserLanguageControl
unit-test.

The only remaining failing test case is ServerTest.Http404HtmlError
(only for url=/ROOT%23%3F/content/zimfile/invalid-article?userlang=test).
This commit is contained in:
Veloman Yunkan 2025-04-07 16:42:31 +04:00
parent 1ce909ae68
commit f47490e1bc
6 changed files with 48 additions and 14 deletions

View File

@ -243,6 +243,11 @@ public:
};
}
static Data fromMsgId(const std::string& nonParameterizedMsgId)
{
return from(nonParameterizedMessage(nonParameterizedMsgId));
}
std::string asJSON() const;
void dumpJSON(std::ostream& os) const;
@ -375,11 +380,13 @@ NewHTTP404Response::NewHTTP404Response(const RequestContext& request,
MHD_HTTP_NOT_FOUND,
"text/html; charset=utf-8",
RESOURCE::templates::sexy404_html,
/*includeKiwixResponseData=*/false)
/*includeKiwixResponseData=*/true)
{
*this->m_data = Data(Data::Object{
{"root", root },
{"url_path", urlPath}
{"url_path", urlPath},
{"PAGE_TITLE", Data::fromMsgId("new-404-page-title")},
{"PAGE_HEADING", Data::fromMsgId("new-404-page-heading")},
});
}
@ -398,8 +405,8 @@ HTTPErrorResponse::HTTPErrorResponse(const RequestContext& request,
Data::List emptyList;
*this->m_data = Data(Data::Object{
{"CSS_URL", Data::onlyAsNonEmptyValue(cssUrl) },
{"PAGE_TITLE", Data::from(nonParameterizedMessage(pageTitleMsgId))},
{"PAGE_HEADING", Data::from(nonParameterizedMessage(headingMsgId))},
{"PAGE_TITLE", Data::fromMsgId(pageTitleMsgId)},
{"PAGE_HEADING", Data::fromMsgId(headingMsgId)},
{"details", emptyList}
});
}

View File

@ -20,6 +20,8 @@
, "400-page-heading" : "Invalid request"
, "404-page-title" : "Content not found"
, "404-page-heading" : "Not Found"
, "new-404-page-title" : "Page not found"
, "new-404-page-heading" : "Oops. Page not found."
, "500-page-title" : "Internal Server Error"
, "500-page-heading" : "Internal Server Error"
, "500-page-text": "An internal server error occured. We are sorry about that :/"

View File

@ -24,6 +24,8 @@
"400-page-heading": "Heading of the 400 error page",
"404-page-title": "Title of the 404 error page",
"404-page-heading": "Heading of the 404 error page",
"new-404-page-title": "Title of the 404 error page",
"new-404-page-heading": "Heading of the 404 error page",
"500-page-title": "Title of the 500 error page",
"500-page-heading": "Heading of the 500 error page",
"500-page-text": "Text of the 500 error page",

View File

@ -13,6 +13,8 @@
, "400-page-heading": "[I18N TESTING] -400 karma for an invalid request"
, "404-page-title": "[I18N TESTING] Not Found - Try Again"
, "404-page-heading": "[I18N TESTING] Content not found, but at least the server is alive"
, "new-404-page-title" : "Page [I18N] not [TESTING] found"
, "new-404-page-heading" : "[I18N TESTING] Oops. Larry Page could not be reached. He may be on paternity leave."
, "library-button-text": "[I18N TESTING] Navigate to the welcome page"
, "home-button-text": "[I18N TESTING] Jump to the main page of '{{BOOK_TITLE}}'"
, "random-page-button-text": "[I18N TESTING] I am tired of determinism"

View File

@ -3,8 +3,12 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Page not found</title>
<title>{{PAGE_TITLE}}</title>
<link type="text/css" href="{{root}}/skin/error.css?KIWIXCACHEID" rel="Stylesheet" />
{{#KIWIX_RESPONSE_DATA}} <script>
window.KIWIX_RESPONSE_TEMPLATE = "{{KIWIX_RESPONSE_TEMPLATE}}";
window.KIWIX_RESPONSE_DATA = {{{KIWIX_RESPONSE_DATA}}};
</script>{{/KIWIX_RESPONSE_DATA}}
</head>
<body>
<header>
@ -14,7 +18,7 @@
title="Not found!">
</header>
<section class="intro">
<h1>Oops. Page not found.</h1>
<h1>{{PAGE_HEADING}}</h1>
<p>The requested path was not found:</p>
<p><code>{{url_path}}</code></p>
</section>

View File

@ -346,6 +346,7 @@ R"EXPECTEDRESULT( <link type="text/css" href="./skin/kiwix.css?cacheid=3948b8
{
/* url */ "/ROOT%23%3F/content/invalid-book/whatever",
R"EXPECTEDRESULT( <link type="text/css" href="/ROOT%23%3F/skin/error.css?cacheid=c49d1586" rel="Stylesheet" />
window.KIWIX_RESPONSE_TEMPLATE = "&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n &lt;head&gt;\n &lt;meta charset=&quot;utf-8&quot;&gt;\n &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no&quot; /&gt;\n &lt;title&gt;{{PAGE_TITLE}}&lt;/title&gt;\n &lt;link type=&quot;text/css&quot; href=&quot;{{root}}/skin/error.css?cacheid=c49d1586&quot; rel=&quot;Stylesheet&quot; /&gt;\n{{#KIWIX_RESPONSE_DATA}} &lt;script&gt;\n window.KIWIX_RESPONSE_TEMPLATE = &quot;{{KIWIX_RESPONSE_TEMPLATE}}&quot;;\n window.KIWIX_RESPONSE_DATA = {{{KIWIX_RESPONSE_DATA}}};\n &lt;/script&gt;{{/KIWIX_RESPONSE_DATA}}\n &lt;/head&gt;\n &lt;body&gt;\n &lt;header&gt;\n &lt;img src=&quot;{{root}}/skin/404.svg?cacheid=b6d648af&quot;\n alt=&quot;Not found!&quot;\n aria-label=&quot;Not found!&quot;\n title=&quot;Not found!&quot;&gt;\n &lt;/header&gt;\n &lt;section class=&quot;intro&quot;&gt;\n &lt;h1&gt;{{PAGE_HEADING}}&lt;/h1&gt;\n &lt;p&gt;The requested path was not found:&lt;/p&gt;\n &lt;p&gt;&lt;code&gt;{{url_path}}&lt;/code&gt;&lt;/p&gt;\n &lt;/section&gt;\n &lt;section class=&quot;advice&quot;&gt;\n &lt;p&gt;The content you&apos;re looking for may still be available, but it might be located at a different place within the ZIM file.&lt;/p&gt;\n &lt;p class=&quot;list-intro&quot;&gt;Please:&lt;/p&gt;\n &lt;ul&gt;\n &lt;li&gt;Try using the search function to find the content you want&lt;/li&gt;\n &lt;li&gt;Look for keywords or titles related to the information you&apos;re seeking&lt;/li&gt;\n &lt;/ul&gt;\n &lt;p&gt;This approach should help you locate the desired content, even if the original link isn&apos;t working properly.&lt;/p&gt;\n &lt;/section&gt;\n &lt;/body&gt;\n&lt;/html&gt;\n";
<img src="/ROOT%23%3F/skin/404.svg?cacheid=b6d648af"
)EXPECTEDRESULT"
},
@ -922,9 +923,17 @@ std::string htmlEscape(std::string s)
return s;
}
std::string escapeJsString(std::string s)
{
s = replace(s, "</script>", "</scr\\ipt>");
s = replace(s, "\"", "\\\"");
return s;
}
std::string expectedSexy404ErrorHtml(const std::string& url)
{
const auto htmlSafeUrl = htmlEscape(url);
const auto jsSafeUrl = escapeJsString(url);
return R"RAWSTRINGLITERAL(<!DOCTYPE html>
<html>
@ -933,6 +942,14 @@ std::string expectedSexy404ErrorHtml(const std::string& url)
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Page not found</title>
<link type="text/css" href="/ROOT%23%3F/skin/error.css?cacheid=c49d1586" rel="Stylesheet" />
<script>
window.KIWIX_RESPONSE_TEMPLATE = "&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n &lt;head&gt;\n &lt;meta charset=&quot;utf-8&quot;&gt;\n &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no&quot; /&gt;\n &lt;title&gt;{{PAGE_TITLE}}&lt;/title&gt;\n &lt;link type=&quot;text/css&quot; href=&quot;{{root}}/skin/error.css?cacheid=c49d1586&quot; rel=&quot;Stylesheet&quot; /&gt;\n{{#KIWIX_RESPONSE_DATA}} &lt;script&gt;\n window.KIWIX_RESPONSE_TEMPLATE = &quot;{{KIWIX_RESPONSE_TEMPLATE}}&quot;;\n window.KIWIX_RESPONSE_DATA = {{{KIWIX_RESPONSE_DATA}}};\n &lt;/script&gt;{{/KIWIX_RESPONSE_DATA}}\n &lt;/head&gt;\n &lt;body&gt;\n &lt;header&gt;\n &lt;img src=&quot;{{root}}/skin/404.svg?cacheid=b6d648af&quot;\n alt=&quot;Not found!&quot;\n aria-label=&quot;Not found!&quot;\n title=&quot;Not found!&quot;&gt;\n &lt;/header&gt;\n &lt;section class=&quot;intro&quot;&gt;\n &lt;h1&gt;{{PAGE_HEADING}}&lt;/h1&gt;\n &lt;p&gt;The requested path was not found:&lt;/p&gt;\n &lt;p&gt;&lt;code&gt;{{url_path}}&lt;/code&gt;&lt;/p&gt;\n &lt;/section&gt;\n &lt;section class=&quot;advice&quot;&gt;\n &lt;p&gt;The content you&apos;re looking for may still be available, but it might be located at a different place within the ZIM file.&lt;/p&gt;\n &lt;p class=&quot;list-intro&quot;&gt;Please:&lt;/p&gt;\n &lt;ul&gt;\n &lt;li&gt;Try using the search function to find the content you want&lt;/li&gt;\n &lt;li&gt;Look for keywords or titles related to the information you&apos;re seeking&lt;/li&gt;\n &lt;/ul&gt;\n &lt;p&gt;This approach should help you locate the desired content, even if the original link isn&apos;t working properly.&lt;/p&gt;\n &lt;/section&gt;\n &lt;/body&gt;\n&lt;/html&gt;\n";
window.KIWIX_RESPONSE_DATA = { "PAGE_HEADING" : { "msgid" : "new-404-page-heading", "params" : { } }, "PAGE_TITLE" : { "msgid" : "new-404-page-title", "params" : { } }, "root" : "/ROOT%23%3F", "url_path" : ")RAWSTRINGLITERAL"
+ // inject the URL
jsSafeUrl // inject the URL
+ // inject the URL
R"RAWSTRINGLITERAL(" };
</script>
</head>
<body>
<header>
@ -1458,37 +1475,37 @@ TEST_F(ServerTest, UserLanguageControl)
"Default user language is English",
/*url*/ "/ROOT%23%3F/content/zimfile/invalid-article",
/*Accept-Language:*/ "",
/* expected <h1> */ "Not Found"
/* expected <h1> */ "Oops. Page not found."
},
{
"userlang URL query parameter is respected",
/*url*/ "/ROOT%23%3F/content/zimfile/invalid-article?userlang=en",
/*Accept-Language:*/ "",
/* expected <h1> */ "Not Found"
/* expected <h1> */ "Oops. Page not found."
},
{
"userlang URL query parameter is respected",
/*url*/ "/ROOT%23%3F/content/zimfile/invalid-article?userlang=test",
/*Accept-Language:*/ "",
/* expected <h1> */ "[I18N TESTING] Content not found, but at least the server is alive"
/* expected <h1> */ "[I18N TESTING] Oops. Larry Page could not be reached. He may be on paternity leave."
},
{
"'Accept-Language: *' is handled",
/*url*/ "/ROOT%23%3F/content/zimfile/invalid-article",
/*Accept-Language:*/ "*",
/* expected <h1> */ "Not Found"
/* expected <h1> */ "Oops. Page not found."
},
{
"Accept-Language: header is respected",
/*url*/ "/ROOT%23%3F/content/zimfile/invalid-article",
/*Accept-Language:*/ "test",
/* expected <h1> */ "[I18N TESTING] Content not found, but at least the server is alive"
/* expected <h1> */ "[I18N TESTING] Oops. Larry Page could not be reached. He may be on paternity leave."
},
{
"userlang query parameter takes precedence over Accept-Language",
/*url*/ "/ROOT%23%3F/content/zimfile/invalid-article?userlang=en",
/*Accept-Language:*/ "test",
/* expected <h1> */ "Not Found"
/* expected <h1> */ "Oops. Page not found."
},
{
"Most suitable language is selected from the Accept-Language header",
@ -1496,7 +1513,7 @@ TEST_F(ServerTest, UserLanguageControl)
// with quality values) the most suitable language is selected.
/*url*/ "/ROOT%23%3F/content/zimfile/invalid-article",
/*Accept-Language:*/ "test;q=0.9, en;q=0.2",
/* expected <h1> */ "[I18N TESTING] Content not found, but at least the server is alive"
/* expected <h1> */ "[I18N TESTING] Oops. Larry Page could not be reached. He may be on paternity leave."
},
{
"Most suitable language is selected from the Accept-Language header",
@ -1504,7 +1521,7 @@ TEST_F(ServerTest, UserLanguageControl)
// with quality values) the most suitable language is selected.
/*url*/ "/ROOT%23%3F/content/zimfile/invalid-article",
/*Accept-Language:*/ "test;q=0.2, en;q=0.9",
/* expected <h1> */ "Not Found"
/* expected <h1> */ "Oops. Page not found."
},
};