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 "
+ ""
+ "