diff --git a/README.md b/README.md index 484541493..e25a77678 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,53 @@ cp ninja ../bin 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 -> + +``` + + + + + + <-- Custom Tittle --> + + + + + + + + + +``` + +- To get books listed using `index.js` add - `
` under body tag. +- To get number of books listed add - `

` under body tag. +- To add language select box add - `` under body tag. +- To add language select box add - `` under body tag. +- To add search box for books use following form - + ``` +
+ + +
+ ``` + + If you compile manually Libmicrohttpd, you might need to compile it without GNU TLS, a bug here will empeach further compilation otherwise. diff --git a/include/server.h b/include/server.h index b38ad8c04..b1c3a4232 100644 --- a/include/server.h +++ b/include/server.h @@ -55,6 +55,7 @@ namespace kiwix void setPort(int port) { m_port = port; } void setNbThreads(int threads) { m_nbThreads = threads; } void setVerbose(bool verbose) { m_verbose = verbose; } + void setIndexTemplateString(const std::string& indexTemplateString) { m_indexTemplateString = indexTemplateString; } void setTaskbar(bool withTaskbar, bool withLibraryButton) { m_withTaskbar = withTaskbar; m_withLibraryButton = withLibraryButton; } void setBlockExternalLinks(bool blockExternalLinks) @@ -65,6 +66,7 @@ namespace kiwix NameMapper* mp_nameMapper; std::string m_root = ""; std::string m_addr = ""; + std::string m_indexTemplateString = ""; int m_port = 80; int m_nbThreads = 1; bool m_verbose = false; diff --git a/include/tools.h b/include/tools.h index 150348929..967e22ed3 100644 --- a/include/tools.h +++ b/include/tools.h @@ -167,5 +167,32 @@ std::vector split(const std::string& str, const std::string& delims * @throw std::out_of_range if iso2 code is not known. */ std::string converta2toa3(const std::string& a2code); + +/** Extracts content from given file. + * + * This function provides content of a file provided it's path. + * + * @param path The absolute path provided in string format. + * @return Content of corresponding file in string format. + */ +std::string getFileContent(const std::string& path); + +/** checks if file exists. + * + * This function returns boolean stating if file exists or not. + * + * @param path The absolute path provided in string format. + * @return Boolean representing if file exists or not. + */ +bool fileExists(const std::string& path); + +/** provides mimetype from filename. + * + * This function provides mimetype from file-name. + * + * @param filename string containing filename. + * @return mimetype from filename in string format. + */ +std::string getMimeTypeForFile(const std::string& filename); } #endif // KIWIX_TOOLS_H diff --git a/src/server.cpp b/src/server.cpp index e82bf3cee..255f88883 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -48,7 +48,8 @@ bool Server::start() { m_verbose, m_withTaskbar, m_withLibraryButton, - m_blockExternalLinks)); + m_blockExternalLinks, + m_indexTemplateString)); return mp_server->start(); } diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp index 0e474ad86..6ff949380 100644 --- a/src/server/internalServer.cpp +++ b/src/server/internalServer.cpp @@ -128,7 +128,8 @@ InternalServer::InternalServer(Library* library, bool verbose, bool withTaskbar, bool withLibraryButton, - bool blockExternalLinks) : + bool blockExternalLinks, + std::string indexTemplateString) : m_addr(addr), m_port(port), m_root(normalizeRootUrl(root)), @@ -137,6 +138,7 @@ InternalServer::InternalServer(Library* library, m_withTaskbar(withTaskbar), m_withLibraryButton(withLibraryButton), m_blockExternalLinks(blockExternalLinks), + m_indexTemplateString(indexTemplateString.empty() ? RESOURCE::templates::index_html : indexTemplateString), mp_daemon(nullptr), mp_library(library), mp_nameMapper(nameMapper ? nameMapper : &defaultNameMapper) @@ -336,7 +338,7 @@ InternalServer::get_matching_if_none_match_etag(const RequestContext& r) const std::unique_ptr 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); } /** diff --git a/src/server/internalServer.h b/src/server/internalServer.h index cfaceb9ec..898ff0390 100644 --- a/src/server/internalServer.h +++ b/src/server/internalServer.h @@ -54,7 +54,8 @@ class InternalServer { bool verbose, bool withTaskbar, bool withLibraryButton, - bool blockExternalLinks); + bool blockExternalLinks, + std::string indexTemplateString); virtual ~InternalServer() = default; MHD_Result handlerCallback(struct MHD_Connection* connection, @@ -103,6 +104,7 @@ class InternalServer { bool m_withTaskbar; bool m_withLibraryButton; bool m_blockExternalLinks; + std::string m_indexTemplateString; struct MHD_Daemon* mp_daemon; Library* mp_library; diff --git a/src/tools/pathTools.cpp b/src/tools/pathTools.cpp index d66aa6f8b..b4fabf450 100644 --- a/src/tools/pathTools.cpp +++ b/src/tools/pathTools.cpp @@ -269,7 +269,7 @@ std::string getFileSizeAsString(const std::string& path) return convert.str(); } -std::string getFileContent(const std::string& path) +std::string kiwix::getFileContent(const std::string& path) { #ifdef _WIN32 auto wpath = Utf8ToWide(path); @@ -302,7 +302,7 @@ std::string getFileContent(const std::string& path) return content; } -bool fileExists(const std::string& path) +bool kiwix::fileExists(const std::string& path) { #ifdef _WIN32 return PathFileExistsW(Utf8ToWide(path).c_str()); @@ -505,7 +505,7 @@ static std::map extMimeTypes = { }; /* Try to get the mimeType from the file extension */ -std::string getMimeTypeForFile(const std::string& filename) +std::string kiwix::getMimeTypeForFile(const std::string& filename) { std::string mimeType = "text/plain"; auto pos = filename.find_last_of("."); diff --git a/src/tools/pathTools.h b/src/tools/pathTools.h index d8450b83f..82c2a8678 100644 --- a/src/tools/pathTools.h +++ b/src/tools/pathTools.h @@ -29,13 +29,10 @@ std::wstring Utf8ToWide(const std::string& str); unsigned int getFileSize(const std::string& path); std::string getFileSizeAsString(const std::string& path); -std::string getFileContent(const std::string& path); -bool fileExists(const std::string& path); bool makeDirectory(const std::string& path); std::string makeTmpDirectory(); bool copyFile(const std::string& sourcePath, const std::string& destPath); bool writeTextFile(const std::string& path, const std::string& content); -std::string getMimeTypeForFile(const std::string& filename); #endif diff --git a/test/server.cpp b/test/server.cpp index 85f553ce0..afffee224 100644 --- a/test/server.cpp +++ b/test/server.cpp @@ -54,7 +54,7 @@ public: // types public: // functions ZimFileServer(int serverPort, std::string libraryFilePath); - ZimFileServer(int serverPort, const FilePathCollection& zimpaths); + ZimFileServer(int serverPort, const FilePathCollection& zimpaths, std::string indexTemplateString = ""); ~ZimFileServer(); Response GET(const char* path, const Headers& headers = Headers()) @@ -68,7 +68,7 @@ public: // functions } private: - void run(int serverPort); + void run(int serverPort, std::string indexTemplateString = ""); private: // data kiwix::Library library; @@ -88,7 +88,7 @@ ZimFileServer::ZimFileServer(int serverPort, std::string libraryFilePath) run(serverPort); } -ZimFileServer::ZimFileServer(int serverPort, const FilePathCollection& zimpaths) +ZimFileServer::ZimFileServer(int serverPort, const FilePathCollection& zimpaths, std::string indexTemplateString) : manager(&this->library) { 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 + "'"); } - 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"; nameMapper.reset(new kiwix::HumanReadableNameMapper(library, false)); @@ -108,6 +108,9 @@ void ZimFileServer::run(int serverPort) server->setPort(serverPort); server->setNbThreads(2); server->setVerbose(false); + if (!indexTemplateString.empty()) { + server->setIndexTemplateString(indexTemplateString); + } if ( !server->start() ) throw std::runtime_error("ZimFileServer failed to start"); @@ -211,6 +214,35 @@ ResourceCollection all200Resources() 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, "" + "Welcome to kiwix library" + "" + ""); + EXPECT_EQ("" + "Welcome to kiwix library" + "" + "" + "", zfs.GET("/")->body); +} + TEST_F(ServerTest, 200) { for ( const Resource& res : all200Resources() )