mirror of https://github.com/kiwix/libkiwix.git
added custom index template
This commit is contained in:
parent
e46b0c07b5
commit
b7b385d87b
47
README.md
47
README.md
|
@ -146,6 +146,53 @@ cp ninja ../bin
|
||||||
cd ..
|
cd ..
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Custom Index Page
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
to use custom welcome page mention `customIndexPage` argument in `kiwix::internalServer()` or use `kiwix::server->setCustomIndexTemplate()`.
|
||||||
|
(note - while using custom html file please mention all external links as absolute path.)
|
||||||
|
|
||||||
|
to create a HTML template with custom JS you need to have a look at various OPDS based endpoints as mentioned [here](https://wiki.kiwix.org/wiki/OPDS) to load books.
|
||||||
|
|
||||||
|
To use JS provided by kiwix-serve you can use the following template to start with ->
|
||||||
|
|
||||||
|
```
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<title><-- Custom Tittle --></title>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="{{root}}/skin/jquery-ui/external/jquery/jquery.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="{{root}}/skin/jquery-ui/jquery-ui.min.js"
|
||||||
|
></script>
|
||||||
|
<script src="{{root}}/skin/isotope.pkgd.min.js" defer></script>
|
||||||
|
<script src="{{root}}/skin/iso6391To3.js"></script>
|
||||||
|
<script type="text/javascript" src="{{root}}/skin/index.js" defer></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
- To get books listed using `index.js` add - `<div class="book__list"></div>` under body tag.
|
||||||
|
- To get number of books listed add - `<h3 class="kiwixHomeBody__results"></h3>` under body tag.
|
||||||
|
- To add language select box add - `<select id="languageFilter"></select>` under body tag.
|
||||||
|
- To add language select box add - `<select id="categoryFilter"></select>` under body tag.
|
||||||
|
- To add search box for books use following form -
|
||||||
|
```
|
||||||
|
<form id='kiwixSearchForm'>
|
||||||
|
<input type="text" name="q" placeholder="Search" id="searchFilter" class='kiwixSearch filter'>
|
||||||
|
<input type="submit" class="searchButton" value="Search"/>
|
||||||
|
</form>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
If you compile manually Libmicrohttpd, you might need to compile it
|
If you compile manually Libmicrohttpd, you might need to compile it
|
||||||
without GNU TLS, a bug here will empeach further compilation
|
without GNU TLS, a bug here will empeach further compilation
|
||||||
otherwise.
|
otherwise.
|
||||||
|
|
|
@ -55,6 +55,7 @@ namespace kiwix
|
||||||
void setPort(int port) { m_port = port; }
|
void setPort(int port) { m_port = port; }
|
||||||
void setNbThreads(int threads) { m_nbThreads = threads; }
|
void setNbThreads(int threads) { m_nbThreads = threads; }
|
||||||
void setVerbose(bool verbose) { m_verbose = verbose; }
|
void setVerbose(bool verbose) { m_verbose = verbose; }
|
||||||
|
void setIndexTemplateString(const std::string& indexTemplateString) { m_indexTemplateString = indexTemplateString; }
|
||||||
void setTaskbar(bool withTaskbar, bool withLibraryButton)
|
void setTaskbar(bool withTaskbar, bool withLibraryButton)
|
||||||
{ m_withTaskbar = withTaskbar; m_withLibraryButton = withLibraryButton; }
|
{ m_withTaskbar = withTaskbar; m_withLibraryButton = withLibraryButton; }
|
||||||
void setBlockExternalLinks(bool blockExternalLinks)
|
void setBlockExternalLinks(bool blockExternalLinks)
|
||||||
|
@ -65,6 +66,7 @@ namespace kiwix
|
||||||
NameMapper* mp_nameMapper;
|
NameMapper* mp_nameMapper;
|
||||||
std::string m_root = "";
|
std::string m_root = "";
|
||||||
std::string m_addr = "";
|
std::string m_addr = "";
|
||||||
|
std::string m_indexTemplateString = "";
|
||||||
int m_port = 80;
|
int m_port = 80;
|
||||||
int m_nbThreads = 1;
|
int m_nbThreads = 1;
|
||||||
bool m_verbose = false;
|
bool m_verbose = false;
|
||||||
|
|
|
@ -48,7 +48,8 @@ bool Server::start() {
|
||||||
m_verbose,
|
m_verbose,
|
||||||
m_withTaskbar,
|
m_withTaskbar,
|
||||||
m_withLibraryButton,
|
m_withLibraryButton,
|
||||||
m_blockExternalLinks));
|
m_blockExternalLinks,
|
||||||
|
m_indexTemplateString));
|
||||||
return mp_server->start();
|
return mp_server->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,8 @@ InternalServer::InternalServer(Library* library,
|
||||||
bool verbose,
|
bool verbose,
|
||||||
bool withTaskbar,
|
bool withTaskbar,
|
||||||
bool withLibraryButton,
|
bool withLibraryButton,
|
||||||
bool blockExternalLinks) :
|
bool blockExternalLinks,
|
||||||
|
std::string indexTemplateString) :
|
||||||
m_addr(addr),
|
m_addr(addr),
|
||||||
m_port(port),
|
m_port(port),
|
||||||
m_root(normalizeRootUrl(root)),
|
m_root(normalizeRootUrl(root)),
|
||||||
|
@ -137,6 +138,7 @@ InternalServer::InternalServer(Library* library,
|
||||||
m_withTaskbar(withTaskbar),
|
m_withTaskbar(withTaskbar),
|
||||||
m_withLibraryButton(withLibraryButton),
|
m_withLibraryButton(withLibraryButton),
|
||||||
m_blockExternalLinks(blockExternalLinks),
|
m_blockExternalLinks(blockExternalLinks),
|
||||||
|
m_indexTemplateString(indexTemplateString.empty() ? RESOURCE::templates::index_html : indexTemplateString),
|
||||||
mp_daemon(nullptr),
|
mp_daemon(nullptr),
|
||||||
mp_library(library),
|
mp_library(library),
|
||||||
mp_nameMapper(nameMapper ? nameMapper : &defaultNameMapper)
|
mp_nameMapper(nameMapper ? nameMapper : &defaultNameMapper)
|
||||||
|
@ -336,7 +338,7 @@ InternalServer::get_matching_if_none_match_etag(const RequestContext& r) const
|
||||||
|
|
||||||
std::unique_ptr<Response> InternalServer::build_homepage(const RequestContext& request)
|
std::unique_ptr<Response> InternalServer::build_homepage(const RequestContext& request)
|
||||||
{
|
{
|
||||||
return ContentResponse::build(*this, RESOURCE::templates::index_html, get_default_data(), "text/html; charset=utf-8", true);
|
return ContentResponse::build(*this, m_indexTemplateString, get_default_data(), "text/html; charset=utf-8", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -54,7 +54,8 @@ class InternalServer {
|
||||||
bool verbose,
|
bool verbose,
|
||||||
bool withTaskbar,
|
bool withTaskbar,
|
||||||
bool withLibraryButton,
|
bool withLibraryButton,
|
||||||
bool blockExternalLinks);
|
bool blockExternalLinks,
|
||||||
|
std::string indexTemplateString);
|
||||||
virtual ~InternalServer() = default;
|
virtual ~InternalServer() = default;
|
||||||
|
|
||||||
MHD_Result handlerCallback(struct MHD_Connection* connection,
|
MHD_Result handlerCallback(struct MHD_Connection* connection,
|
||||||
|
@ -103,6 +104,7 @@ class InternalServer {
|
||||||
bool m_withTaskbar;
|
bool m_withTaskbar;
|
||||||
bool m_withLibraryButton;
|
bool m_withLibraryButton;
|
||||||
bool m_blockExternalLinks;
|
bool m_blockExternalLinks;
|
||||||
|
std::string m_indexTemplateString;
|
||||||
struct MHD_Daemon* mp_daemon;
|
struct MHD_Daemon* mp_daemon;
|
||||||
|
|
||||||
Library* mp_library;
|
Library* mp_library;
|
||||||
|
|
|
@ -54,7 +54,7 @@ public: // types
|
||||||
|
|
||||||
public: // functions
|
public: // functions
|
||||||
ZimFileServer(int serverPort, std::string libraryFilePath);
|
ZimFileServer(int serverPort, std::string libraryFilePath);
|
||||||
ZimFileServer(int serverPort, const FilePathCollection& zimpaths);
|
ZimFileServer(int serverPort, const FilePathCollection& zimpaths, std::string indexTemplateString = "");
|
||||||
~ZimFileServer();
|
~ZimFileServer();
|
||||||
|
|
||||||
Response GET(const char* path, const Headers& headers = Headers())
|
Response GET(const char* path, const Headers& headers = Headers())
|
||||||
|
@ -68,7 +68,7 @@ public: // functions
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void run(int serverPort);
|
void run(int serverPort, std::string indexTemplateString = "");
|
||||||
|
|
||||||
private: // data
|
private: // data
|
||||||
kiwix::Library library;
|
kiwix::Library library;
|
||||||
|
@ -88,7 +88,7 @@ ZimFileServer::ZimFileServer(int serverPort, std::string libraryFilePath)
|
||||||
run(serverPort);
|
run(serverPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZimFileServer::ZimFileServer(int serverPort, const FilePathCollection& zimpaths)
|
ZimFileServer::ZimFileServer(int serverPort, const FilePathCollection& zimpaths, std::string indexTemplateString)
|
||||||
: manager(&this->library)
|
: manager(&this->library)
|
||||||
{
|
{
|
||||||
for ( const auto& zimpath : zimpaths ) {
|
for ( const auto& zimpath : zimpaths ) {
|
||||||
|
@ -96,10 +96,10 @@ ZimFileServer::ZimFileServer(int serverPort, const FilePathCollection& zimpaths)
|
||||||
throw std::runtime_error("Unable to add the ZIM file '" + zimpath + "'");
|
throw std::runtime_error("Unable to add the ZIM file '" + zimpath + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
run(serverPort);
|
run(serverPort, indexTemplateString);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZimFileServer::run(int serverPort)
|
void ZimFileServer::run(int serverPort, std::string indexTemplateString)
|
||||||
{
|
{
|
||||||
const std::string address = "127.0.0.1";
|
const std::string address = "127.0.0.1";
|
||||||
nameMapper.reset(new kiwix::HumanReadableNameMapper(library, false));
|
nameMapper.reset(new kiwix::HumanReadableNameMapper(library, false));
|
||||||
|
@ -108,6 +108,9 @@ void ZimFileServer::run(int serverPort)
|
||||||
server->setPort(serverPort);
|
server->setPort(serverPort);
|
||||||
server->setNbThreads(2);
|
server->setNbThreads(2);
|
||||||
server->setVerbose(false);
|
server->setVerbose(false);
|
||||||
|
if (!indexTemplateString.empty()) {
|
||||||
|
server->setIndexTemplateString(indexTemplateString);
|
||||||
|
}
|
||||||
|
|
||||||
if ( !server->start() )
|
if ( !server->start() )
|
||||||
throw std::runtime_error("ZimFileServer failed to start");
|
throw std::runtime_error("ZimFileServer failed to start");
|
||||||
|
@ -211,6 +214,35 @@ ResourceCollection all200Resources()
|
||||||
return concat(resources200Compressible, resources200Uncompressible);
|
return concat(resources200Compressible, resources200Uncompressible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(indexTemplateStringTest, emptyIndexTemplate) {
|
||||||
|
const int PORT = 8001;
|
||||||
|
const ZimFileServer::FilePathCollection ZIMFILES {
|
||||||
|
"./test/zimfile.zim",
|
||||||
|
"./test/corner_cases.zim"
|
||||||
|
};
|
||||||
|
|
||||||
|
ZimFileServer zfs(PORT, ZIMFILES, "");
|
||||||
|
EXPECT_EQ(200, zfs.GET("/")->status);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(indexTemplateStringTest, indexTemplateCheck) {
|
||||||
|
const int PORT = 8001;
|
||||||
|
const ZimFileServer::FilePathCollection ZIMFILES {
|
||||||
|
"./test/zimfile.zim",
|
||||||
|
"./test/corner_cases.zim"
|
||||||
|
};
|
||||||
|
|
||||||
|
ZimFileServer zfs(PORT, ZIMFILES, "<!DOCTYPE html><head>"
|
||||||
|
"<title>Welcome to kiwix library</title>"
|
||||||
|
"</head>"
|
||||||
|
"</html>");
|
||||||
|
EXPECT_EQ("<!DOCTYPE html><head>"
|
||||||
|
"<title>Welcome to kiwix library</title>"
|
||||||
|
"<link type=\"root\" href=\"\">"
|
||||||
|
"</head>"
|
||||||
|
"</html>", zfs.GET("/")->body);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ServerTest, 200)
|
TEST_F(ServerTest, 200)
|
||||||
{
|
{
|
||||||
for ( const Resource& res : all200Resources() )
|
for ( const Resource& res : all200Resources() )
|
||||||
|
|
Loading…
Reference in New Issue