mirror of
https://github.com/kiwix/kiwix-tools.git
synced 2025-09-24 04:20:56 -04:00
commit
ee5333bb91
@ -91,6 +91,7 @@ static bool noLibraryButtonFlag = false;
|
|||||||
static bool noSearchBarFlag = false;
|
static bool noSearchBarFlag = false;
|
||||||
static string welcomeHTML;
|
static string welcomeHTML;
|
||||||
static std::atomic_bool isVerbose(false);
|
static std::atomic_bool isVerbose(false);
|
||||||
|
static std::string rootLocation = "";
|
||||||
static std::map<std::string, std::string> extMimeTypes;
|
static std::map<std::string, std::string> extMimeTypes;
|
||||||
static std::map<std::string, kiwix::Reader*> readers;
|
static std::map<std::string, kiwix::Reader*> readers;
|
||||||
static std::map<std::string, kiwix::Searcher*> searchers;
|
static std::map<std::string, kiwix::Searcher*> searchers;
|
||||||
@ -181,6 +182,7 @@ void introduceTaskbar(string& content, const string& humanReadableBookId)
|
|||||||
humanReadableBookId,
|
humanReadableBookId,
|
||||||
"__CONTENT__"));
|
"__CONTENT__"));
|
||||||
}
|
}
|
||||||
|
content = replaceRegex(content, rootLocation, "__ROOT_LOCATION__");
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(®exLock);
|
pthread_mutex_unlock(®exLock);
|
||||||
}
|
}
|
||||||
@ -430,7 +432,7 @@ static struct MHD_Response* handle_skin(RequestContext* request_context)
|
|||||||
{
|
{
|
||||||
std::string content;
|
std::string content;
|
||||||
try {
|
try {
|
||||||
content = getResource(request_context->urlStr.substr(6));
|
content = getResource(request_context->urlStr.substr(rootLocation.size() + 6));
|
||||||
} catch (const ResourceNotFound& e) {
|
} catch (const ResourceNotFound& e) {
|
||||||
return build_404(request_context);
|
return build_404(request_context);
|
||||||
}
|
}
|
||||||
@ -466,7 +468,7 @@ static struct MHD_Response* handle_search(RequestContext* request_context)
|
|||||||
/* If article found then redirect directly to it */
|
/* If article found then redirect directly to it */
|
||||||
if (!patternCorrespondingUrl.empty()) {
|
if (!patternCorrespondingUrl.empty()) {
|
||||||
httpRedirection
|
httpRedirection
|
||||||
= "/" + request_context->humanReadableBookId + "/" + patternCorrespondingUrl;
|
= rootLocation + "/" + request_context->humanReadableBookId + "/" + patternCorrespondingUrl;
|
||||||
request_context->httpResponseCode = MHD_HTTP_FOUND;
|
request_context->httpResponseCode = MHD_HTTP_FOUND;
|
||||||
return build_response("", 0, httpRedirection, "", false, true);
|
return build_response("", 0, httpRedirection, "", false, true);
|
||||||
}
|
}
|
||||||
@ -515,7 +517,7 @@ static struct MHD_Response* handle_random(RequestContext* request_context)
|
|||||||
if (request_context->reader != NULL) {
|
if (request_context->reader != NULL) {
|
||||||
std::string randomUrl = request_context->reader->getRandomPageUrl();
|
std::string randomUrl = request_context->reader->getRandomPageUrl();
|
||||||
httpRedirection
|
httpRedirection
|
||||||
= "/" + request_context->humanReadableBookId + "/" + kiwix::urlEncode(randomUrl);
|
= rootLocation + "/" + request_context->humanReadableBookId + "/" + kiwix::urlEncode(randomUrl);
|
||||||
}
|
}
|
||||||
return build_response("", 0, httpRedirection, "", false, false);
|
return build_response("", 0, httpRedirection, "", false, false);
|
||||||
}
|
}
|
||||||
@ -578,22 +580,22 @@ static struct MHD_Response* handle_content(RequestContext* request_context)
|
|||||||
+ article.getUrl();
|
+ article.getUrl();
|
||||||
pthread_mutex_lock(®exLock);
|
pthread_mutex_lock(®exLock);
|
||||||
content = replaceRegex(content,
|
content = replaceRegex(content,
|
||||||
"$1$2" + request_context->humanReadableBookId + "/$3/",
|
"$1$2" + rootLocation + "/" + request_context->humanReadableBookId + "/$3/",
|
||||||
"(href|src)(=[\"|\']{0,1}/)([A-Z|\\-])/");
|
"(href|src)(=[\"|\']{0,1})/([A-Z|\\-])/");
|
||||||
content = replaceRegex(content,
|
content = replaceRegex(content,
|
||||||
"$1$2" + request_context->humanReadableBookId + "/$3/",
|
"$1$2" + rootLocation + "/" + request_context->humanReadableBookId + "/$3/",
|
||||||
"(@import[ ]+)([\"|\']{0,1}/)([A-Z|\\-])/");
|
"(@import[ ]+)([\"|\']{0,1})/([A-Z|\\-])/");
|
||||||
content = replaceRegex(
|
content = replaceRegex(
|
||||||
content,
|
content,
|
||||||
"<head><base href=\"/" + request_context->humanReadableBookId + baseUrl + "\" />",
|
"<head><base href=\"" + rootLocation + "/" + request_context->humanReadableBookId + baseUrl + "\" />",
|
||||||
"<head>");
|
"<head>");
|
||||||
pthread_mutex_unlock(®exLock);
|
pthread_mutex_unlock(®exLock);
|
||||||
introduceTaskbar(content, request_context->humanReadableBookId);
|
introduceTaskbar(content, request_context->humanReadableBookId);
|
||||||
} else if (mimeType.find("text/css") != string::npos) {
|
} else if (mimeType.find("text/css") != string::npos) {
|
||||||
pthread_mutex_lock(®exLock);
|
pthread_mutex_lock(®exLock);
|
||||||
content = replaceRegex(content,
|
content = replaceRegex(content,
|
||||||
"$1$2" + request_context->humanReadableBookId + "/$3/",
|
"$1$2" + rootLocation + "/" + request_context->humanReadableBookId + "/$3/",
|
||||||
"(url|URL)(\\([\"|\']{0,1}/)([A-Z|\\-])/");
|
"(url|URL)(\\([\"|\']{0,1})/([A-Z|\\-])/");
|
||||||
pthread_mutex_unlock(®exLock);
|
pthread_mutex_unlock(®exLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,7 +626,7 @@ static struct MHD_Response* handle_default(RequestContext* request_context)
|
|||||||
|
|
||||||
bool deflated = request_context->acceptEncodingDeflate && compress_content(content, mimeType);
|
bool deflated = request_context->acceptEncodingDeflate && compress_content(content, mimeType);
|
||||||
return build_response(
|
return build_response(
|
||||||
content.data(), content.size(), "", mimeType, deflated, true);
|
content.data(), content.size(), "", mimeType, deflated, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int print_out_key (void *cls, enum MHD_ValueKind kind,
|
int print_out_key (void *cls, enum MHD_ValueKind kind,
|
||||||
@ -698,20 +700,25 @@ static int accessHandlerCallback(void* cls,
|
|||||||
|
|
||||||
/* Get searcher and reader */
|
/* Get searcher and reader */
|
||||||
std::string humanReadableBookId = "";
|
std::string humanReadableBookId = "";
|
||||||
if (!(urlStr.size() > 5 && urlStr.substr(0, 6) == "/skin/")) {
|
|
||||||
if (!strcmp(url, "/search") || !strcmp(url, "/suggest")
|
if (!rootLocation.empty() && urlStr.substr(0, rootLocation.size() + 1) != rootLocation + "/"){
|
||||||
|| !strcmp(url, "/random")) {
|
humanReadableBookId = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (!(urlStr.size() > rootLocation.size() + 5 && urlStr.substr(rootLocation.size() , 6) == "/skin/")) {
|
||||||
|
if ((urlStr == rootLocation + "/" + "search") || (urlStr == rootLocation + "/" + "suggest")
|
||||||
|
|| (urlStr == rootLocation + "/" + "random")) {
|
||||||
const char* tmpGetValue = MHD_lookup_connection_value(
|
const char* tmpGetValue = MHD_lookup_connection_value(
|
||||||
connection, MHD_GET_ARGUMENT_KIND, "content");
|
connection, MHD_GET_ARGUMENT_KIND, "content");
|
||||||
humanReadableBookId = (tmpGetValue != NULL ? string(tmpGetValue) : "");
|
humanReadableBookId = (tmpGetValue != NULL ? string(tmpGetValue) : "");
|
||||||
} else {
|
} else {
|
||||||
humanReadableBookId = urlStr.substr(1,
|
humanReadableBookId = urlStr.substr(rootLocation.size() + 1,
|
||||||
urlStr.find("/", 1) != string::npos
|
urlStr.find("/", rootLocation.size() + 1) != string::npos
|
||||||
? urlStr.find("/", 1) - 1
|
? urlStr.find("/", rootLocation.size() + 1) - (rootLocation.size() + 1)
|
||||||
: urlStr.size() - 2);
|
: urlStr.size() - (rootLocation.size() + 2));
|
||||||
if (!humanReadableBookId.empty()) {
|
if (!humanReadableBookId.empty()) {
|
||||||
urlStr = urlStr.substr(urlStr.find("/", 1) != string::npos
|
urlStr = urlStr.substr(urlStr.find("/", rootLocation.size() + 1) != string::npos
|
||||||
? urlStr.find("/", 1)
|
? urlStr.find("/", rootLocation.size() + 1)
|
||||||
: humanReadableBookId.size());
|
: humanReadableBookId.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -736,22 +743,22 @@ static int accessHandlerCallback(void* cls,
|
|||||||
|
|
||||||
|
|
||||||
/* Get suggestions */
|
/* Get suggestions */
|
||||||
if (!strcmp(url, "/suggest") && reader != NULL) {
|
if ((urlStr == (rootLocation + "/" + "suggest")) && reader != NULL) {
|
||||||
response = handle_suggest(&request_context);
|
response = handle_suggest(&request_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get static skin stuff */
|
/* Get static skin stuff */
|
||||||
else if (urlStr.substr(0, 6) == "/skin/") {
|
else if (urlStr.size() > rootLocation.size() + 5 && urlStr.substr(rootLocation.size() , 6) == "/skin/") {
|
||||||
response = handle_skin(&request_context);
|
response = handle_skin(&request_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display the search restults */
|
/* Display the search restults */
|
||||||
else if (!strcmp(url, "/search")) {
|
else if (urlStr == (rootLocation + "/" + "search")) {
|
||||||
response = handle_search(&request_context);
|
response = handle_search(&request_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display a random article */
|
/* Display a random article */
|
||||||
else if (!strcmp(url, "/random")) {
|
else if (urlStr == (rootLocation + "/" + "random")) {
|
||||||
response = handle_random(&request_context);
|
response = handle_random(&request_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -799,13 +806,14 @@ int main(int argc, char** argv)
|
|||||||
{"port", required_argument, 0, 'p'},
|
{"port", required_argument, 0, 'p'},
|
||||||
{"interface", required_argument, 0, 'f'},
|
{"interface", required_argument, 0, 'f'},
|
||||||
{"threads", required_argument, 0, 't'},
|
{"threads", required_argument, 0, 't'},
|
||||||
|
{"urlRootLocation", required_argument, 0, 'r'},
|
||||||
{0, 0, 0, 0}};
|
{0, 0, 0, 0}};
|
||||||
|
|
||||||
/* Argument parsing */
|
/* Argument parsing */
|
||||||
while (true) {
|
while (true) {
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
int c
|
int c
|
||||||
= getopt_long(argc, argv, "mndvli:a:p:f:t:", long_options, &option_index);
|
= getopt_long(argc, argv, "mndvli:a:p:f:t:r:", long_options, &option_index);
|
||||||
|
|
||||||
if (c != -1) {
|
if (c != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@ -839,6 +847,20 @@ int main(int argc, char** argv)
|
|||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
nb_threads = atoi(optarg);
|
nb_threads = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
rootLocation = string(optarg);
|
||||||
|
|
||||||
|
/* prepend prefix "/" if not provided*/
|
||||||
|
if (rootLocation[0] != '/'){
|
||||||
|
rootLocation = "/" + rootLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove the trailing slash if provided*/
|
||||||
|
if (rootLocation.back() == '/'){
|
||||||
|
rootLocation.erase(rootLocation.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -859,12 +881,13 @@ int main(int argc, char** argv)
|
|||||||
cerr << "Usage: kiwix-serve [--index=INDEX_PATH] [--port=PORT] [--verbose] "
|
cerr << "Usage: kiwix-serve [--index=INDEX_PATH] [--port=PORT] [--verbose] "
|
||||||
"[--nosearchbar] [--nolibrarybutton] [--daemon] "
|
"[--nosearchbar] [--nolibrarybutton] [--daemon] "
|
||||||
"[--attachToProcess=PID] [--interface=IF_NAME] "
|
"[--attachToProcess=PID] [--interface=IF_NAME] "
|
||||||
|
"[--urlRootLocation=/URL_ROOT] "
|
||||||
"[--threads=NB_THREAD(" << nb_threads << ")] ZIM_PATH+"
|
"[--threads=NB_THREAD(" << nb_threads << ")] ZIM_PATH+"
|
||||||
<< endl;
|
<< endl;
|
||||||
cerr << " kiwix-serve --library [--port=PORT] [--verbose] [--daemon] "
|
cerr << " kiwix-serve --library [--port=PORT] [--verbose] [--daemon] "
|
||||||
"[--nosearchbar] [--nolibrarybutton] [--attachToProcess=PID] "
|
"[--nosearchbar] [--nolibrarybutton] [--attachToProcess=PID] "
|
||||||
"[--interface=IF_NAME] [--threads=NB_THREAD(" << nb_threads << ")] "
|
"[--interface=IF_NAME] [--urlRootLocation=/URL_ROOT] "
|
||||||
"LIBRARY_PATH"
|
"[--threads=NB_THREAD(" << nb_threads << ")] LIBRARY_PATH "
|
||||||
<< endl;
|
<< endl;
|
||||||
cerr << "\n If you set more than one ZIM_PATH, you cannot set a "
|
cerr << "\n If you set more than one ZIM_PATH, you cannot set a "
|
||||||
"INDEX_PATH."
|
"INDEX_PATH."
|
||||||
@ -930,8 +953,8 @@ int main(int argc, char** argv)
|
|||||||
vector<string>::iterator itr;
|
vector<string>::iterator itr;
|
||||||
kiwix::Book currentBook;
|
kiwix::Book currentBook;
|
||||||
globalSearcher = new kiwix::Searcher();
|
globalSearcher = new kiwix::Searcher();
|
||||||
globalSearcher->setProtocolPrefix("/");
|
globalSearcher->setProtocolPrefix(rootLocation + "/");
|
||||||
globalSearcher->setSearchProtocolPrefix("/search?");
|
globalSearcher->setSearchProtocolPrefix(rootLocation + "/" + "search?");
|
||||||
for (itr = booksIds.begin(); itr != booksIds.end(); ++itr) {
|
for (itr = booksIds.begin(); itr != booksIds.end(); ++itr) {
|
||||||
bool zimFileOk = false;
|
bool zimFileOk = false;
|
||||||
libraryManager.getBookById(*itr, currentBook);
|
libraryManager.getBookById(*itr, currentBook);
|
||||||
@ -955,16 +978,16 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
if ( reader->hasFulltextIndex()) {
|
if ( reader->hasFulltextIndex()) {
|
||||||
kiwix::Searcher* searcher = new kiwix::Searcher();
|
kiwix::Searcher* searcher = new kiwix::Searcher();
|
||||||
searcher->setProtocolPrefix("/");
|
searcher->setProtocolPrefix(rootLocation + "/");
|
||||||
searcher->setSearchProtocolPrefix("/search?");
|
searcher->setSearchProtocolPrefix(rootLocation + "/" + "search?");
|
||||||
searcher->add_reader(reader, humanReadableId);
|
searcher->add_reader(reader, humanReadableId);
|
||||||
globalSearcher->add_reader(reader, humanReadableId);
|
globalSearcher->add_reader(reader, humanReadableId);
|
||||||
searchers[humanReadableId] = searcher;
|
searchers[humanReadableId] = searcher;
|
||||||
} else if ( !indexPath.empty() ) {
|
} else if ( !indexPath.empty() ) {
|
||||||
try {
|
try {
|
||||||
kiwix::Searcher* searcher = new kiwix::Searcher(indexPath, reader, humanReadableId);
|
kiwix::Searcher* searcher = new kiwix::Searcher(indexPath, reader, humanReadableId);
|
||||||
searcher->setProtocolPrefix("/");
|
searcher->setProtocolPrefix(rootLocation + "/");
|
||||||
searcher->setSearchProtocolPrefix("/search?");
|
searcher->setSearchProtocolPrefix(rootLocation + "/" + "search?");
|
||||||
searchers[humanReadableId] = searcher;
|
searchers[humanReadableId] = searcher;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
cerr << "Unable to open the search index '" << indexPath << "'."
|
cerr << "Unable to open the search index '" << indexPath << "'."
|
||||||
@ -989,7 +1012,7 @@ int main(int argc, char** argv)
|
|||||||
&& readers.find(currentBook.getHumanReadableIdFromPath())
|
&& readers.find(currentBook.getHumanReadableIdFromPath())
|
||||||
!= readers.end()) {
|
!= readers.end()) {
|
||||||
welcomeBooksHtml += ""
|
welcomeBooksHtml += ""
|
||||||
"<a href='/" + currentBook.getHumanReadableIdFromPath() + "/'>"
|
"<a href='" + rootLocation + "/" + currentBook.getHumanReadableIdFromPath() + "/'>"
|
||||||
"<div class='book'>"
|
"<div class='book'>"
|
||||||
"<div class='book__background' style='background-image: url(data:" + currentBook.faviconMimeType+ ";base64," + currentBook.favicon + ");'>"
|
"<div class='book__background' style='background-image: url(data:" + currentBook.faviconMimeType+ ";base64," + currentBook.favicon + ");'>"
|
||||||
"<div class='book__title' title='" + currentBook.title + "'>" + currentBook.title + "</div>"
|
"<div class='book__title' title='" + currentBook.title + "'>" + currentBook.title + "</div>"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<span id="kiwixtoolbar" class="ui-widget-header">
|
<span id="kiwixtoolbar" class="ui-widget-header">
|
||||||
<div class="kiwix_centered">
|
<div class="kiwix_centered">
|
||||||
<div class="kiwix_searchform">
|
<div class="kiwix_searchform">
|
||||||
<form class="kiwixsearch" method="GET" action="/search" id="kiwixsearchform">
|
<form class="kiwixsearch" method="GET" action="__ROOT_LOCATION__/search" id="kiwixsearchform">
|
||||||
<input autocomplete="off" class="ui-autocomplete-input" id="kiwixsearchbox" name="pattern" type="text">
|
<input autocomplete="off" class="ui-autocomplete-input" id="kiwixsearchbox" name="pattern" type="text">
|
||||||
<input type="submit" value="Search">
|
<input type="submit" value="Search">
|
||||||
</form>
|
</form>
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<title>Welcome to Kiwix Server</title>
|
<title>Welcome to Kiwix Server</title>
|
||||||
<script type="text/javascript" src="/skin/jquery-ui/external/jquery/jquery.js"></script>
|
<script type="text/javascript" src="__ROOT_LOCATION__/skin/jquery-ui/external/jquery/jquery.js"></script>
|
||||||
<script type="text/javascript" src="/skin/jquery-ui/jquery-ui.min.js"></script>
|
<script type="text/javascript" src="__ROOT_LOCATION__/skin/jquery-ui/jquery-ui.min.js"></script>
|
||||||
<link type="text/css" href="/skin/jquery-ui/jquery-ui.min.css" rel="Stylesheet" />
|
<link type="text/css" href="__ROOT_LOCATION__/skin/jquery-ui/jquery-ui.min.css" rel="Stylesheet" />
|
||||||
<link type="text/css" href="/skin/jquery-ui/jquery-ui.theme.min.css" rel="Stylesheet" />
|
<link type="text/css" href="__ROOT_LOCATION__/skin/jquery-ui/jquery-ui.theme.min.css" rel="Stylesheet" />
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
background:
|
background:
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
<link type="text/css" href="/skin/jquery-ui/jquery-ui.min.css" rel="Stylesheet" />
|
<link type="text/css" href="__ROOT_LOCATION__/skin/jquery-ui/jquery-ui.min.css" rel="Stylesheet" />
|
||||||
<link type="text/css" href="/skin/jquery-ui/jquery-ui.theme.min.css" rel="Stylesheet" />
|
<link type="text/css" href="__ROOT_LOCATION__/skin/jquery-ui/jquery-ui.theme.min.css" rel="Stylesheet" />
|
||||||
<link type="text/css" href="/skin/taskbar.css" rel="Stylesheet" />
|
<link type="text/css" href="__ROOT_LOCATION__/skin/taskbar.css" rel="Stylesheet" />
|
||||||
<script type="text/javascript" src="/skin/jquery-ui/external/jquery/jquery.js"></script>
|
<script type="text/javascript" src="__ROOT_LOCATION__/skin/jquery-ui/external/jquery/jquery.js"></script>
|
||||||
<script type="text/javascript" src="/skin/jquery-ui/jquery-ui.min.js"></script>
|
<script type="text/javascript" src="__ROOT_LOCATION__/skin/jquery-ui/jquery-ui.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
var jk = jQuery.noConflict();
|
var jk = jQuery.noConflict();
|
||||||
jk(function() {
|
jk(function() {
|
||||||
jk( "#kiwixsearchbox" ).autocomplete({
|
jk( "#kiwixsearchbox" ).autocomplete({
|
||||||
|
|
||||||
source: "/suggest?content=__CONTENT__",
|
source: "__ROOT_LOCATION__/suggest?content=__CONTENT__",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
cache: false,
|
cache: false,
|
||||||
|
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
<span id="kiwixtoolbar" class="ui-widget-header">
|
<span id="kiwixtoolbar" class="ui-widget-header">
|
||||||
<div class="kiwix_centered">
|
<div class="kiwix_centered">
|
||||||
<div class="kiwix_button_wrapper">
|
<div class="kiwix_button_wrapper">
|
||||||
<a id="kiwix_serve_taskbar_library_button" href="/"><button>Library</button></a>
|
<a id="kiwix_serve_taskbar_library_button" href="__ROOT_LOCATION__/"><button>Library</button></a>
|
||||||
<a id="kiwix_serve_taskbar_home_button" href="/__CONTENT__/"><button>Home</button></a>
|
<a id="kiwix_serve_taskbar_home_button" href="__ROOT_LOCATION__/__CONTENT__/"><button>Home</button></a>
|
||||||
<a id="kiwix_serve_taskbar_random_button" href="/random?content=__CONTENT__"><button>Random</button></a>
|
<a id="kiwix_serve_taskbar_random_button" href="__ROOT_LOCATION__/random?content=__CONTENT__"><button>Random</button></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="kiwix_searchform">
|
<div class="kiwix_searchform">
|
||||||
<form class="kiwixsearch" method="GET" action="/search" id="kiwixsearchform">
|
<form class="kiwixsearch" method="GET" action="__ROOT_LOCATION__/search" id="kiwixsearchform">
|
||||||
<input type="hidden" name="content" value="__CONTENT__" />
|
<input type="hidden" name="content" value="__CONTENT__" />
|
||||||
<input autocomplete="off" class="ui-autocomplete-input" id="kiwixsearchbox" name="pattern" type="text">
|
<input autocomplete="off" class="ui-autocomplete-input" id="kiwixsearchbox" name="pattern" type="text">
|
||||||
<input type="submit" value="Search">
|
<input type="submit" value="Search">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user