mirror of https://github.com/kiwix/libkiwix.git
Merge pull request #1046 from kiwix/translation_of_search_results_page
Translation of search results page
This commit is contained in:
commit
09eec822c1
|
@ -72,6 +72,13 @@ class SearchRenderer
|
||||||
this->pageLength = pageLength;
|
this->pageLength = pageLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set user language
|
||||||
|
*/
|
||||||
|
void setUserLang(const std::string& lang){
|
||||||
|
this->userlang = lang;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the html page with the resutls of the search.
|
* Generate the html page with the resutls of the search.
|
||||||
*
|
*
|
||||||
|
@ -105,6 +112,7 @@ class SearchRenderer
|
||||||
unsigned int pageLength;
|
unsigned int pageLength;
|
||||||
unsigned int estimatedResultCount;
|
unsigned int estimatedResultCount;
|
||||||
unsigned int resultStart;
|
unsigned int resultStart;
|
||||||
|
std::string userlang = "en";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,42 @@
|
||||||
#include "libkiwix-resources.h"
|
#include "libkiwix-resources.h"
|
||||||
#include "tools/stringTools.h"
|
#include "tools/stringTools.h"
|
||||||
|
|
||||||
|
#include "server/i18n.h"
|
||||||
|
|
||||||
namespace kiwix
|
namespace kiwix
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
ParameterizedMessage searchResultsPageTitleMsg(const std::string& searchPattern)
|
||||||
|
{
|
||||||
|
return ParameterizedMessage("search-results-page-title",
|
||||||
|
{{"SEARCH_PATTERN", searchPattern}}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ParameterizedMessage searchResultsPageHeaderMsg(const std::string& searchPattern,
|
||||||
|
const kainjow::mustache::data& r)
|
||||||
|
{
|
||||||
|
if ( r.get("count")->string_value() == "0" ) {
|
||||||
|
return ParameterizedMessage("empty-search-results-page-header",
|
||||||
|
{{"SEARCH_PATTERN", searchPattern}}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return ParameterizedMessage("search-results-page-header",
|
||||||
|
{
|
||||||
|
{"SEARCH_PATTERN", searchPattern},
|
||||||
|
{"START", r.get("start")->string_value()},
|
||||||
|
{"END", r.get("end") ->string_value()},
|
||||||
|
{"COUNT", r.get("count")->string_value()},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // unnamed namespace
|
||||||
|
|
||||||
/* Constructor */
|
/* Constructor */
|
||||||
SearchRenderer::SearchRenderer(zim::SearchResultSet srs,
|
SearchRenderer::SearchRenderer(zim::SearchResultSet srs,
|
||||||
unsigned int start, unsigned int estimatedResultCount)
|
unsigned int start, unsigned int estimatedResultCount)
|
||||||
|
@ -170,10 +203,20 @@ std::string SearchRenderer::renderTemplate(const std::string& tmpl_str, const Na
|
||||||
result.set("absolutePath", absPathPrefix + urlEncode(path));
|
result.set("absolutePath", absPathPrefix + urlEncode(path));
|
||||||
result.set("snippet", it.getSnippet());
|
result.set("snippet", it.getSnippet());
|
||||||
if (library) {
|
if (library) {
|
||||||
result.set("bookTitle", library->getBookById(zim_id).getTitle());
|
const std::string bookTitle = library->getBookById(zim_id).getTitle();
|
||||||
|
const ParameterizedMessage bookInfoMsg("search-result-book-info",
|
||||||
|
{{"BOOK_TITLE", bookTitle}}
|
||||||
|
);
|
||||||
|
result.set("bookInfo", bookInfoMsg.getText(userlang)); // for HTML
|
||||||
|
result.set("bookTitle", bookTitle); // for XML
|
||||||
}
|
}
|
||||||
if (it.getWordCount() >= 0) {
|
if (it.getWordCount() >= 0) {
|
||||||
result.set("wordCount", kiwix::beautifyInteger(it.getWordCount()));
|
const auto wordCountStr = kiwix::beautifyInteger(it.getWordCount());
|
||||||
|
const ParameterizedMessage wordCountMsg("word-count",
|
||||||
|
{{"COUNT", wordCountStr}}
|
||||||
|
);
|
||||||
|
result.set("wordCountInfo", wordCountMsg.getText(userlang)); // for HTML
|
||||||
|
result.set("wordCount", wordCountStr); // for XML
|
||||||
}
|
}
|
||||||
|
|
||||||
items.push_back(result);
|
items.push_back(result);
|
||||||
|
@ -181,7 +224,6 @@ std::string SearchRenderer::renderTemplate(const std::string& tmpl_str, const Na
|
||||||
kainjow::mustache::data results;
|
kainjow::mustache::data results;
|
||||||
results.set("items", items);
|
results.set("items", items);
|
||||||
results.set("count", kiwix::beautifyInteger(estimatedResultCount));
|
results.set("count", kiwix::beautifyInteger(estimatedResultCount));
|
||||||
results.set("hasResults", estimatedResultCount != 0);
|
|
||||||
results.set("start", kiwix::beautifyInteger(resultStart));
|
results.set("start", kiwix::beautifyInteger(resultStart));
|
||||||
results.set("end", kiwix::beautifyInteger(std::min(resultStart+pageLength-1, estimatedResultCount)));
|
results.set("end", kiwix::beautifyInteger(std::min(resultStart+pageLength-1, estimatedResultCount)));
|
||||||
|
|
||||||
|
@ -198,12 +240,15 @@ std::string SearchRenderer::renderTemplate(const std::string& tmpl_str, const Na
|
||||||
searchBookQuery
|
searchBookQuery
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const auto pageHeaderMsg = searchResultsPageHeaderMsg(searchPattern, results);
|
||||||
kainjow::mustache::data allData;
|
const kainjow::mustache::object allData{
|
||||||
allData.set("searchProtocolPrefix", searchProtocolPrefix);
|
{"PAGE_TITLE", searchResultsPageTitleMsg(searchPattern).getText(userlang)},
|
||||||
allData.set("results", results);
|
{"PAGE_HEADER", pageHeaderMsg.getText(userlang)},
|
||||||
allData.set("pagination", pagination);
|
{"searchProtocolPrefix", searchProtocolPrefix},
|
||||||
allData.set("query", query);
|
{"results", results},
|
||||||
|
{"pagination", pagination},
|
||||||
|
{"query", query},
|
||||||
|
};
|
||||||
|
|
||||||
kainjow::mustache::mustache tmpl(tmpl_str);
|
kainjow::mustache::mustache tmpl(tmpl_str);
|
||||||
|
|
||||||
|
|
|
@ -967,6 +967,7 @@ std::unique_ptr<Response> InternalServer::handle_search_request(const RequestCon
|
||||||
renderer.setProtocolPrefix(m_root + "/content/");
|
renderer.setProtocolPrefix(m_root + "/content/");
|
||||||
renderer.setSearchProtocolPrefix(m_root + "/search");
|
renderer.setSearchProtocolPrefix(m_root + "/search");
|
||||||
renderer.setPageLength(pageLength);
|
renderer.setPageLength(pageLength);
|
||||||
|
renderer.setUserLang(request.get_user_language());
|
||||||
if (request.get_requested_format() == "xml") {
|
if (request.get_requested_format() == "xml") {
|
||||||
return ContentResponse::build(
|
return ContentResponse::build(
|
||||||
renderer.getXml(*mp_nameMapper, mp_library.get()),
|
renderer.getXml(*mp_nameMapper, mp_library.get()),
|
||||||
|
|
|
@ -25,6 +25,11 @@
|
||||||
, "500-page-text": "An internal server error occured. We are sorry about that :/"
|
, "500-page-text": "An internal server error occured. We are sorry about that :/"
|
||||||
, "fulltext-search-unavailable" : "Fulltext search unavailable"
|
, "fulltext-search-unavailable" : "Fulltext search unavailable"
|
||||||
, "no-search-results": "The fulltext search engine is not available for this content."
|
, "no-search-results": "The fulltext search engine is not available for this content."
|
||||||
|
, "search-results-page-title": "Search: {{SEARCH_PATTERN}}"
|
||||||
|
, "search-results-page-header": "Results <b>{{START}}-{{END}}</b> of <b>{{COUNT}}</b> for <b>\"{{{SEARCH_PATTERN}}}\"</b>"
|
||||||
|
, "empty-search-results-page-header": "No results were found for <b>\"{{{SEARCH_PATTERN}}}\"</b>"
|
||||||
|
, "search-result-book-info": "from {{BOOK_TITLE}}"
|
||||||
|
, "word-count": "{{COUNT}} words"
|
||||||
, "library-button-text": "Go to welcome page"
|
, "library-button-text": "Go to welcome page"
|
||||||
, "home-button-text": "Go to the main page of '{{BOOK_TITLE}}'"
|
, "home-button-text": "Go to the main page of '{{BOOK_TITLE}}'"
|
||||||
, "random-page-button-text": "Go to a randomly selected page"
|
, "random-page-button-text": "Go to a randomly selected page"
|
||||||
|
|
|
@ -29,6 +29,11 @@
|
||||||
"500-page-text": "Text of the 500 error page",
|
"500-page-text": "Text of the 500 error page",
|
||||||
"fulltext-search-unavailable": "Title of the error page returned when search is attempted in a book without fulltext search database",
|
"fulltext-search-unavailable": "Title of the error page returned when search is attempted in a book without fulltext search database",
|
||||||
"no-search-results": "Text of the error page returned when search is attempted in a book without fulltext search database",
|
"no-search-results": "Text of the error page returned when search is attempted in a book without fulltext search database",
|
||||||
|
"search-results-page-title": "Title of the search results page",
|
||||||
|
"search-results-page-header": "Header of the search results page",
|
||||||
|
"empty-search-results-page-header": "Header of the empty search results page",
|
||||||
|
"search-result-book-info": "Reference to the book where the search result belongs (this is displayed AFTER the search result)",
|
||||||
|
"word-count": "Word count information",
|
||||||
"library-button-text": "Tooltip of the button leading to the welcome page",
|
"library-button-text": "Tooltip of the button leading to the welcome page",
|
||||||
"home-button-text": "Tooltip of the button leading to the main page of a book",
|
"home-button-text": "Tooltip of the button leading to the main page of a book",
|
||||||
"random-page-button-text": "Tooltip of the button opening a randomly selected page",
|
"random-page-button-text": "Tooltip of the button opening a randomly selected page",
|
||||||
|
|
|
@ -42,4 +42,9 @@
|
||||||
, "preview-book": "[I18N] Preview [TESTING]"
|
, "preview-book": "[I18N] Preview [TESTING]"
|
||||||
, "no-query" : "[I18N TESTING] Kiwix can read your thoughts but it is against GDPR. Please provide your query explicitly."
|
, "no-query" : "[I18N TESTING] Kiwix can read your thoughts but it is against GDPR. Please provide your query explicitly."
|
||||||
, "invalid-request" : "[I18N TESTING] Invalid URL: \"{{{url}}}\""
|
, "invalid-request" : "[I18N TESTING] Invalid URL: \"{{{url}}}\""
|
||||||
|
, "search-results-page-title": "[I18N TESTING] Search: {{SEARCH_PATTERN}}"
|
||||||
|
, "search-results-page-header": "[I18N TESTING] Results <b>{{START}}-{{END}}</b> of <b>{{COUNT}}</b> for <b>\"{{{SEARCH_PATTERN}}}\"</b>"
|
||||||
|
, "empty-search-results-page-header": "[I18N TESTING] No results were found for <b>\"{{{SEARCH_PATTERN}}}\"</b>"
|
||||||
|
, "search-result-book-info": "from [I18N TESTING] {{BOOK_TITLE}}"
|
||||||
|
, "word-count": "{{COUNT}} [I18N TESTING] words"
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ const uiLanguages = [
|
||||||
{
|
{
|
||||||
"iso_code": "en",
|
"iso_code": "en",
|
||||||
"self_name": "English",
|
"self_name": "English",
|
||||||
"translation_count": 53
|
"translation_count": 58
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"iso_code": "es",
|
"iso_code": "es",
|
||||||
|
|
|
@ -10,13 +10,22 @@ let viewerState = {
|
||||||
uiLanguage: 'en',
|
uiLanguage: 'en',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function dropUserLang(query) {
|
||||||
|
const q = new URLSearchParams(query);
|
||||||
|
q.delete('userlang');
|
||||||
|
const pre = (query.startsWith('?') && q.size != 0 ? '?' : '');
|
||||||
|
return pre + q.toString();
|
||||||
|
}
|
||||||
|
|
||||||
function userUrl2IframeUrl(url) {
|
function userUrl2IframeUrl(url) {
|
||||||
if ( url == '' ) {
|
if ( url == '' ) {
|
||||||
return blankPageUrl;
|
return blankPageUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( url.startsWith('search?') ) {
|
if ( url.startsWith('search?') ) {
|
||||||
return `${root}/${url}`;
|
const q = new URLSearchParams(url.slice("search?".length));
|
||||||
|
q.set('userlang', viewerState.uiLanguage);
|
||||||
|
return `${root}/search?${q.toString()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${root}/content/${url}`;
|
return `${root}/content/${url}`;
|
||||||
|
@ -73,7 +82,7 @@ function quasiUriEncode(s, specialSymbols) {
|
||||||
function performSearch() {
|
function performSearch() {
|
||||||
const searchbox = document.getElementById('kiwixsearchbox');
|
const searchbox = document.getElementById('kiwixsearchbox');
|
||||||
const q = encodeURIComponent(searchbox.value);
|
const q = encodeURIComponent(searchbox.value);
|
||||||
gotoUrl(`/search?books.name=${currentBook}&pattern=${q}`);
|
gotoUrl(`/search?books.name=${currentBook}&pattern=${q}&userlang=${viewerState.uiLanguage}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeJSLink(jsCodeString, linkText, linkAttr="") {
|
function makeJSLink(jsCodeString, linkText, linkAttr="") {
|
||||||
|
@ -148,7 +157,7 @@ function iframeUrl2UserUrl(url, query) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( url == `${root}/search` ) {
|
if ( url == `${root}/search` ) {
|
||||||
return `search${query}`;
|
return `search${dropUserLang(query)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
url = url.slice(root.length);
|
url = url.slice(root.length);
|
||||||
|
@ -537,9 +546,8 @@ function setupViewer() {
|
||||||
const lang = getUserLanguage();
|
const lang = getUserLanguage();
|
||||||
setUserLanguage(lang, finishViewerSetupOnceTranslationsAreLoaded);
|
setUserLanguage(lang, finishViewerSetupOnceTranslationsAreLoaded);
|
||||||
viewerState.uiLanguage = lang;
|
viewerState.uiLanguage = lang;
|
||||||
const q = new URLSearchParams(window.location.search);
|
const cleanedUpQuery = dropUserLang(window.location.search);
|
||||||
q.delete('userlang');
|
const rewrittenURL = makeURL(cleanedUpQuery, location.hash);
|
||||||
const rewrittenURL = makeURL(q.toString(), location.hash);
|
|
||||||
history.replaceState(viewerState, null, rewrittenURL);
|
history.replaceState(viewerState, null, rewrittenURL);
|
||||||
|
|
||||||
kiwixToolBarWrapper.style.display = 'block';
|
kiwixToolBarWrapper.style.display = 'block';
|
||||||
|
|
|
@ -102,23 +102,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<title>Search: {{query.pattern}}</title>
|
<title>{{PAGE_TITLE}}</title>
|
||||||
</head>
|
</head>
|
||||||
<body bgcolor="white">
|
<body bgcolor="white">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
{{#results.hasResults}}
|
{{{PAGE_HEADER}}}
|
||||||
Results
|
|
||||||
<b>
|
|
||||||
{{results.start}}-{{results.end}}
|
|
||||||
</b> of <b>
|
|
||||||
{{results.count}}
|
|
||||||
</b> for <b>
|
|
||||||
"{{{query.pattern}}}"
|
|
||||||
</b>
|
|
||||||
{{/results.hasResults}}
|
|
||||||
{{^results.hasResults}}
|
|
||||||
No results were found for <b>"{{{query.pattern}}}"</b>
|
|
||||||
{{/results.hasResults}}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="results">
|
<div class="results">
|
||||||
|
@ -131,12 +119,12 @@
|
||||||
{{#snippet}}
|
{{#snippet}}
|
||||||
<cite>{{>snippet}}...</cite>
|
<cite>{{>snippet}}...</cite>
|
||||||
{{/snippet}}
|
{{/snippet}}
|
||||||
{{#bookTitle}}
|
{{#bookInfo}}
|
||||||
<div class="book-title">from {{bookTitle}}</div>
|
<div class="book-title">{{bookInfo}}</div>
|
||||||
{{/bookTitle}}
|
{{/bookInfo}}
|
||||||
{{#wordCount}}
|
{{#wordCountInfo}}
|
||||||
<div class="informations">{{wordCount}} words</div>
|
<div class="informations">{{wordCountInfo}}</div>
|
||||||
{{/wordCount}}
|
{{/wordCountInfo}}
|
||||||
</li>
|
</li>
|
||||||
{{/results.items}}
|
{{/results.items}}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -75,7 +75,7 @@ const ResourceCollection resources200Compressible{
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css" },
|
||||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css?cacheid=e014a885" },
|
{ STATIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css?cacheid=e014a885" },
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/viewer.js" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/viewer.js" },
|
||||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=e9c025f2" },
|
{ STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=5fc4badf" },
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf" },
|
||||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf?cacheid=af705837" },
|
{ STATIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf?cacheid=af705837" },
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Roboto.ttf" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Roboto.ttf" },
|
||||||
|
@ -84,7 +84,7 @@ const ResourceCollection resources200Compressible{
|
||||||
// TODO: implement cache management of i18n resources
|
// TODO: implement cache management of i18n resources
|
||||||
//{ STATIC_CONTENT, "/ROOT%23%3F/skin/i18n/test.json?cacheid=unknown" },
|
//{ STATIC_CONTENT, "/ROOT%23%3F/skin/i18n/test.json?cacheid=unknown" },
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/languages.js" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/languages.js" },
|
||||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/languages.js?cacheid=c41aae47" },
|
{ STATIC_CONTENT, "/ROOT%23%3F/skin/languages.js?cacheid=9ccd43fd" },
|
||||||
|
|
||||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/search" },
|
{ DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/search" },
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ R"EXPECTEDRESULT( href="/ROOT%23%3F/skin/kiwix.css?cacheid=2158fad9"
|
||||||
<link rel="shortcut icon" href="/ROOT%23%3F/skin/favicon/favicon.ico?cacheid=92663314">
|
<link rel="shortcut icon" href="/ROOT%23%3F/skin/favicon/favicon.ico?cacheid=92663314">
|
||||||
<meta name="msapplication-config" content="/ROOT%23%3F/skin/favicon/browserconfig.xml?cacheid=f29a7c4a">
|
<meta name="msapplication-config" content="/ROOT%23%3F/skin/favicon/browserconfig.xml?cacheid=f29a7c4a">
|
||||||
<script type="module" src="/ROOT%23%3F/skin/i18n.js?cacheid=071abc9a" defer></script>
|
<script type="module" src="/ROOT%23%3F/skin/i18n.js?cacheid=071abc9a" defer></script>
|
||||||
<script type="text/javascript" src="/ROOT%23%3F/skin/languages.js?cacheid=c41aae47" defer></script>
|
<script type="text/javascript" src="/ROOT%23%3F/skin/languages.js?cacheid=9ccd43fd" defer></script>
|
||||||
<script src="/ROOT%23%3F/skin/isotope.pkgd.min.js?cacheid=2e48d392" defer></script>
|
<script src="/ROOT%23%3F/skin/isotope.pkgd.min.js?cacheid=2e48d392" defer></script>
|
||||||
<script src="/ROOT%23%3F/skin/iso6391To3.js?cacheid=ecde2bb3"></script>
|
<script src="/ROOT%23%3F/skin/iso6391To3.js?cacheid=ecde2bb3"></script>
|
||||||
<script type="text/javascript" src="/ROOT%23%3F/skin/index.js?cacheid=ce19da2a" defer></script>
|
<script type="text/javascript" src="/ROOT%23%3F/skin/index.js?cacheid=ce19da2a" defer></script>
|
||||||
|
@ -319,8 +319,8 @@ R"EXPECTEDRESULT( <link type="text/css" href="./skin/kiwix.css?cacheid=2158fa
|
||||||
<link type="text/css" href="./skin/taskbar.css?cacheid=e014a885" rel="Stylesheet" />
|
<link type="text/css" href="./skin/taskbar.css?cacheid=e014a885" rel="Stylesheet" />
|
||||||
<link type="text/css" href="./skin/autoComplete/css/autoComplete.css?cacheid=ef30cd42" rel="Stylesheet" />
|
<link type="text/css" href="./skin/autoComplete/css/autoComplete.css?cacheid=ef30cd42" rel="Stylesheet" />
|
||||||
<script type="module" src="./skin/i18n.js?cacheid=071abc9a" defer></script>
|
<script type="module" src="./skin/i18n.js?cacheid=071abc9a" defer></script>
|
||||||
<script type="text/javascript" src="./skin/languages.js?cacheid=c41aae47" defer></script>
|
<script type="text/javascript" src="./skin/languages.js?cacheid=9ccd43fd" defer></script>
|
||||||
<script type="text/javascript" src="./skin/viewer.js?cacheid=e9c025f2" defer></script>
|
<script type="text/javascript" src="./skin/viewer.js?cacheid=5fc4badf" defer></script>
|
||||||
<script type="text/javascript" src="./skin/autoComplete/autoComplete.min.js?cacheid=1191aaaf"></script>
|
<script type="text/javascript" src="./skin/autoComplete/autoComplete.min.js?cacheid=1191aaaf"></script>
|
||||||
const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032";
|
const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032";
|
||||||
<label for="kiwix_button_show_toggle"><img src="./skin/caret.png?cacheid=22b942b4" alt=""></label>
|
<label for="kiwix_button_show_toggle"><img src="./skin/caret.png?cacheid=22b942b4" alt=""></label>
|
||||||
|
@ -1148,7 +1148,7 @@ R"EXPECTEDRESPONSE(const uiLanguages = [
|
||||||
{
|
{
|
||||||
"iso_code": "en",
|
"iso_code": "en",
|
||||||
"self_name": "English",
|
"self_name": "English",
|
||||||
"translation_count": 53
|
"translation_count": 58
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"iso_code": "es",
|
"iso_code": "es",
|
||||||
|
|
|
@ -113,7 +113,7 @@ std::string makeSearchResultsHtml(const std::string& pattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<title>Search: %PATTERN%</title>
|
<title>%USERLANGMARKER%Search: %PATTERN%</title>
|
||||||
</head>
|
</head>
|
||||||
<body bgcolor="white">
|
<body bgcolor="white">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
|
@ -173,8 +173,8 @@ struct SearchResult
|
||||||
+ " " + title + "\n"
|
+ " " + title + "\n"
|
||||||
+ " </a>\n"
|
+ " </a>\n"
|
||||||
+ " <cite>" + snippet + "</cite>\n"
|
+ " <cite>" + snippet + "</cite>\n"
|
||||||
+ " <div class=\"book-title\">from " + bookTitle + "</div>\n"
|
+ " <div class=\"book-title\">from %USERLANGMARKER%" + bookTitle + "</div>\n"
|
||||||
+ " <div class=\"informations\">" + wordCount + " words</div>\n";
|
+ " <div class=\"informations\">" + wordCount + " %USERLANGMARKER%words</div>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getXml() const
|
std::string getXml() const
|
||||||
|
@ -737,26 +737,16 @@ struct TestData
|
||||||
|
|
||||||
std::string expectedHtmlHeader() const
|
std::string expectedHtmlHeader() const
|
||||||
{
|
{
|
||||||
if ( totalResultCount == 0 ) {
|
std::string header = totalResultCount == 0
|
||||||
return "\n No results were found for <b>\"" + getPattern() + "\"</b>";
|
? R"(No results were found for <b>"PATTERN"</b>)"
|
||||||
}
|
: R"(Results <b>FIRSTRESULT-LASTRESULT</b> of <b>RESULTCOUNT</b> for <b>"PATTERN"</b>)";
|
||||||
|
|
||||||
std::string header = R"( Results
|
|
||||||
<b>
|
|
||||||
FIRSTRESULT-LASTRESULT
|
|
||||||
</b> of <b>
|
|
||||||
RESULTCOUNT
|
|
||||||
</b> for <b>
|
|
||||||
"PATTERN"
|
|
||||||
</b>
|
|
||||||
)";
|
|
||||||
|
|
||||||
const size_t lastResultIndex = std::min(totalResultCount, firstResultIndex + results.size() - 1);
|
const size_t lastResultIndex = std::min(totalResultCount, firstResultIndex + results.size() - 1);
|
||||||
header = replace(header, "FIRSTRESULT", std::to_string(firstResultIndex));
|
header = replace(header, "FIRSTRESULT", std::to_string(firstResultIndex));
|
||||||
header = replace(header, "LASTRESULT", std::to_string(lastResultIndex));
|
header = replace(header, "LASTRESULT", std::to_string(lastResultIndex));
|
||||||
header = replace(header, "RESULTCOUNT", std::to_string(totalResultCount));
|
header = replace(header, "RESULTCOUNT", std::to_string(totalResultCount));
|
||||||
header = replace(header, "PATTERN", getPattern());
|
header = replace(header, "PATTERN", getPattern());
|
||||||
return header;
|
return "%USERLANGMARKER%" + header;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string expectedHtmlResultsString() const
|
std::string expectedHtmlResultsString() const
|
||||||
|
@ -800,12 +790,18 @@ struct TestData
|
||||||
|
|
||||||
std::string expectedHtml() const
|
std::string expectedHtml() const
|
||||||
{
|
{
|
||||||
return makeSearchResultsHtml(
|
const std::string html = makeSearchResultsHtml(
|
||||||
getPattern(),
|
getPattern(),
|
||||||
expectedHtmlHeader(),
|
expectedHtmlHeader(),
|
||||||
expectedHtmlResultsString(),
|
expectedHtmlResultsString(),
|
||||||
expectedHtmlFooter()
|
expectedHtmlFooter()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const std::string userlangMarker = extractQueryValue("userlang") == "test"
|
||||||
|
? "[I18N TESTING] "
|
||||||
|
: "";
|
||||||
|
|
||||||
|
return replace(html, "%USERLANGMARKER%", userlangMarker);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string expectedXmlHeader() const
|
std::string expectedXmlHeader() const
|
||||||
|
@ -824,7 +820,8 @@ struct TestData
|
||||||
/>)";
|
/>)";
|
||||||
|
|
||||||
const auto realResultsPerPage = resultsPerPage?resultsPerPage:25;
|
const auto realResultsPerPage = resultsPerPage?resultsPerPage:25;
|
||||||
const auto url = makeUrl(query + "&format=xml", firstResultIndex, realResultsPerPage);
|
const auto cleanedUpQuery = replace(query, "&userlang=test", "");
|
||||||
|
const auto url = makeUrl(cleanedUpQuery + "&format=xml", firstResultIndex, realResultsPerPage);
|
||||||
header = replace(header, "URL", replace(url, "&", "&"));
|
header = replace(header, "URL", replace(url, "&", "&"));
|
||||||
header = replace(header, "FIRSTRESULT", std::to_string(firstResultIndex));
|
header = replace(header, "FIRSTRESULT", std::to_string(firstResultIndex));
|
||||||
header = replace(header, "ITEMCOUNT", std::to_string(realResultsPerPage));
|
header = replace(header, "ITEMCOUNT", std::to_string(realResultsPerPage));
|
||||||
|
@ -931,6 +928,17 @@ TEST(ServerSearchTest, searchResults)
|
||||||
/* pagination */ {}
|
/* pagination */ {}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
/* query */ "pattern=velomanyunkan&books.id=" RAYCHARLESZIMID
|
||||||
|
"&userlang=test",
|
||||||
|
/* start */ -1,
|
||||||
|
/* resultsPerPage */ 0,
|
||||||
|
/* totalResultCount */ 0,
|
||||||
|
/* firstResultIndex */ 1,
|
||||||
|
/* results */ {},
|
||||||
|
/* pagination */ {}
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
/* query */ "pattern=razaf&books.id=" RAYCHARLESZIMID,
|
/* query */ "pattern=razaf&books.id=" RAYCHARLESZIMID,
|
||||||
/* start */ -1,
|
/* start */ -1,
|
||||||
|
@ -1037,6 +1045,17 @@ TEST(ServerSearchTest, searchResults)
|
||||||
/* pagination */ {}
|
/* pagination */ {}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
/* query */ "pattern=jazz&books.id=" RAYCHARLESZIMID
|
||||||
|
"&userlang=test",
|
||||||
|
/* start */ -1,
|
||||||
|
/* resultsPerPage */ 100,
|
||||||
|
/* totalResultCount */ 44,
|
||||||
|
/* firstResultIndex */ 1,
|
||||||
|
/* results */ LARGE_SEARCH_RESULTS,
|
||||||
|
/* pagination */ {}
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
/* query */ "pattern=jazz&books.id=" RAYCHARLESZIMID,
|
/* query */ "pattern=jazz&books.id=" RAYCHARLESZIMID,
|
||||||
/* start */ -1,
|
/* start */ -1,
|
||||||
|
|
Loading…
Reference in New Issue