From fe9a0fef0b31ee3b94b3e73b7e319087a49a3054 Mon Sep 17 00:00:00 2001 From: Harishankar Date: Tue, 19 May 2020 20:17:38 +0530 Subject: [PATCH] Changed the rendering code for templating output Changed from the C sprintf to using library libfmt::format in C++ to use named parameters in the template. NOTE: This means the template file cannot contain any { or } other than the template variables otherwise it screws up. So moved the CSS stylesheet to its own template --- CMakeLists.txt | 2 +- biawebdoclist.hpp | 52 +++++++++---------------- biawebdocument.hpp | 55 ++++++++++++-------------- biawebdocumenttree.hpp | 4 +- biawebsidebar.hpp | 49 ++++++++--------------- biawebstrings.hpp | 2 +- templates/doclist.tpl.html | 4 +- templates/doclistitem.tpl.html | 6 +-- templates/main.tpl.html | 62 ++++-------------------------- templates/sidebar.tpl.html | 4 +- templates/sidebaritem.tpl.html | 2 +- templates/sidebarlinkitem.tpl.html | 2 +- templates/style.tpl.css | 47 ++++++++++++++++++++++ 13 files changed, 128 insertions(+), 163 deletions(-) create mode 100644 templates/style.tpl.css diff --git a/CMakeLists.txt b/CMakeLists.txt index cc14265..47c11a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,5 +2,5 @@ cmake_minimum_required (VERSION 3.0) project (biaweb2 CXX) set (CMAKE_CXX_STANDARD 17) add_executable (biaweb biaweb.cpp) -target_link_libraries (biaweb markdown) +target_link_libraries (biaweb markdown fmt) diff --git a/biawebdoclist.hpp b/biawebdoclist.hpp index 6082b39..7c4efcd 100644 --- a/biawebdoclist.hpp +++ b/biawebdoclist.hpp @@ -4,7 +4,10 @@ #include #include #include +#include #include +#include +#include #include "biawebstrings.hpp" #include "biawebdocument.hpp" @@ -21,7 +24,7 @@ namespace biaweb { public: DocListItem (std::string title, std::string url, std::time_t ctime, std::time_t mtime ) { - this->title = title; + this->title = escape_html (title); this->url = url; this->ctime = ctime; this->mtime = mtime; @@ -52,10 +55,10 @@ namespace biaweb { return this->title; } void set_title(std::string title) { - this->title = title; + this->title = escape_html (title); } - // output to HTML + // output to HTML vide the template std::string to_html (std::string templatedir); }; @@ -66,24 +69,11 @@ namespace biaweb { (std::istreambuf_iterator ()) ); templ.close (); - // Allocate enough size for the output buffer - std::unique_ptr outputstr (new char [templstr.size() + - this->title.size() + - this->url.size () + - 200]); + std::string outputhtml = fmt::format (templstr, fmt::arg("url", this->url), + fmt::arg("doctitle", this->title), + fmt::arg("cdate", *std::localtime (&this->ctime)), + fmt::arg("mdate", *std::localtime (&this->mtime))); - char ctm_str[100]; - char mtm_str[100]; - strftime (ctm_str, 100, DATE_FORMAT, std::localtime (&this->ctime)); - strftime (mtm_str, 100, DATE_FORMAT, std::localtime (&this->mtime)); - - sprintf (outputstr.get(), templstr.c_str(), - this->url.c_str(), - this->title.c_str(), - ctm_str, mtm_str); - - std::string outputhtml; - outputhtml.append (outputstr.get()); return outputhtml; } @@ -94,7 +84,7 @@ namespace biaweb { std::list items; public: void set_title (std::string title) { - this->title = title; + this->title = escape_html (title); } // add a document item void add_document_item (DocListItem docitem) { @@ -109,24 +99,18 @@ namespace biaweb { std::string templstr ( (std::istreambuf_iterator (templ) ), (std::istreambuf_iterator ())); - std::string docitems = ""; + templ.close (); + std::string outputhtml = ""; // if the number of elements is non zero if (this->items.size () != 0) { + std::string docitems = ""; for (DocListItem item : this->items) docitems += item.to_html (templatedir); - - // Allocate space for output buffer - std::unique_ptr outputstr (new char [ - templstr.size () + - docitems.size () + - this->title.size () - ]); - sprintf (outputstr.get(), templstr.c_str(), - this->title.c_str(), - docitems.c_str() ); - - outputhtml.append (outputstr.get()); + + outputhtml = fmt::format (templstr, + fmt::arg ("title", this->title), + fmt::arg ("docitems", docitems)); } return outputhtml; } diff --git a/biawebdocument.hpp b/biawebdocument.hpp index 9829bcd..40b0207 100644 --- a/biawebdocument.hpp +++ b/biawebdocument.hpp @@ -5,7 +5,10 @@ #include #include #include +#include #include +#include +#include #include "biawebutil.hpp" #include "biawebsidebar.hpp" #include "biawebstrings.hpp" @@ -32,9 +35,9 @@ namespace biaweb { bool is_index = false, std::time_t cdate= std::time(nullptr), std::time_t mdate = std::time(nullptr)) { - this->title = title; - this->meta_desc = meta_desc; - this->meta_keywords = meta_keywords; + this->title = escape_html (title); + this->meta_desc = escape_html (meta_desc); + this->meta_keywords = escape_html (meta_keywords); this->content = content; this->is_index = is_index; if (! is_index) @@ -95,11 +98,11 @@ namespace biaweb { void set_markdown_content (std::string str); void set_meta_keywords(std::string meta_keywords) { - this->meta_keywords = meta_keywords; + this->meta_keywords = escape_html (meta_keywords); } void set_meta_desc(std::string meta_desc) { - this->meta_desc = meta_desc; + this->meta_desc = escape_html (meta_desc); } void set_title(std::string title) { @@ -137,41 +140,33 @@ namespace biaweb { void Document::output_to_html (std::string templatedir, std::string path) { - std::ifstream tpl; - tpl.open (templatedir + "/main.tpl.html"); - std::string main_tpl ( (std::istreambuf_iterator (tpl)), + std::ifstream tpl (templatedir + "/main.tpl.html"); + std::string templstr ( (std::istreambuf_iterator (tpl)), (std::istreambuf_iterator ()) ); tpl.close (); + std::ifstream style (templatedir + "/style.tpl.css"); + std::string stylesheet ( (std::istreambuf_iterator (style)), + (std::istreambuf_iterator ())); + style.close (); // first render the sidebars std::string sidebartext; for (SideBar bar : sidebars) { sidebartext += bar.to_html (templatedir); } - char ctm_str[100], mtm_str[100]; - std::time_t creat = this->cdate; - std::time_t modif = this->cdate; - std::strftime (ctm_str, sizeof (ctm_str), - DATE_FORMAT, std::localtime (&creat)); - std::strftime (mtm_str, sizeof (mtm_str), - DATE_FORMAT, std::localtime (&modif)); - - // Allocate enough space for the output buffer - std::unique_ptr final_templ( - new char[main_tpl.size()+ - this->title.size()+ - this->content.size() + - this->meta_desc.size() + - this->meta_keywords.size () + - 200 + - sidebartext.size()]); - std::sprintf (final_templ.get (), main_tpl.c_str(), this->title.c_str(), - this->meta_keywords.c_str(), this->meta_desc.c_str (), - ctm_str, mtm_str, - this->content.c_str(), sidebartext.c_str()); + std::string outputhtml = fmt::format (templstr, + fmt::arg ("title", this->title), + fmt::arg ("keywords", this->meta_keywords), + fmt::arg ("stylesheet", stylesheet), + fmt::arg ("description", this->meta_desc), + fmt::arg ("cdate", *std::localtime (&this->cdate)), + fmt::arg ("mdate", *std::localtime (&this->mdate)), + fmt::arg ("contents", this->content), + fmt::arg ("sidebar", sidebartext) + ); std::ofstream f (path + "/" + this->filename + ".html"); - f << final_templ.get (); + f << outputhtml; f.close (); } } diff --git a/biawebdocumenttree.hpp b/biawebdocumenttree.hpp index 7c44634..66dcd9f 100644 --- a/biawebdocumenttree.hpp +++ b/biawebdocumenttree.hpp @@ -39,7 +39,7 @@ namespace biaweb { // create new top level document tree DocumentTree (std::string title, std::string stub = "") { - this->title = title; + this->title = escape_html (title); // if stub is not empty set it if (stub != "") this->stub = stub; @@ -74,7 +74,7 @@ namespace biaweb { // set the title void set_title (std::string title) { - this->title = title; + this->title = escape_html (title); // if no stub is set if (this->stub == "") this->stub = convert_title (title); diff --git a/biawebsidebar.hpp b/biawebsidebar.hpp index 4aef44f..932aa2c 100644 --- a/biawebsidebar.hpp +++ b/biawebsidebar.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "biawebutil.hpp" // classes to describe the a list of items and sidebar item containers which form part of @@ -21,20 +22,20 @@ namespace biaweb { return this->sidebar_text; } void set_sidebar_text (std::string text) { - this->sidebar_text = text; + this->sidebar_text = escape_html (text); } std::string get_sidebar_url () { return this->sidebar_url; } void set_sidebar_url (std::string url) { - this->sidebar_url = url; + this->sidebar_url = escape_html (url); } // output to HTML using a template directory specified std::string to_html (std::string templatedir); SideBarItem (std::string text = "", std::string url = "") { - this->sidebar_text = text; - this->sidebar_url = url; + this->sidebar_text = escape_html (text); + this->sidebar_url = escape_html (url); } }; @@ -48,13 +49,9 @@ namespace biaweb { std::string tpl_linkitem_str ( (std::istreambuf_iterator (tpl_linkitem)), (std::istreambuf_iterator ())); tpl_linkitem.close (); - std::unique_ptr linktxt (new char[tpl_linkitem_str.size() - + this->sidebar_text.size () - + this->sidebar_url.size ()] ); - std::sprintf (linktxt.get(), tpl_linkitem_str.c_str (), - this->sidebar_url.c_str (), - this->sidebar_text.c_str ()); - html.append (linktxt.get ()); + html = fmt::format (tpl_linkitem_str, + fmt::arg ("itemurl", this->sidebar_url), + fmt::arg ("itemtext", this->sidebar_text)); } // no text or url - item is empty - so it should be blank else @@ -67,10 +64,7 @@ namespace biaweb { std::string tpl_item_str ( (std::istreambuf_iterator (tpl_item)), (std::istreambuf_iterator ())); tpl_item.close (); - std::unique_ptr txt (new char [tpl_item_str.size () + - this->sidebar_text.size ()]); - std::sprintf (txt.get (), tpl_item_str.c_str(), this->sidebar_text.c_str()); - html.append (txt.get ()); + html = fmt::format (tpl_item_str, fmt::arg ("itemtext", this->sidebar_text) ); } return html; } @@ -101,28 +95,19 @@ namespace biaweb { std::string sidetpl_str ( ( std::istreambuf_iterator (sidetpl)) , (std::istreambuf_iterator ())); sidetpl.close (); - std::string listitem; + std::string listitems; // first get the sidebar items and render them to HTML for (SideBarItem item : this->items) { - listitem += item.to_html (templatedir); + listitems += item.to_html (templatedir); } - - std::unique_ptr tpl_final (new char[sidetpl_str.size() + - this->sidebar_title.size () + - listitem.size () ]); - std::string html; - // if there are items, sidebar should be rendered + std::string html = ""; + // if there are items, sidebar should be rendered otherwise not needed if (items.size () > 0) - { - std::sprintf (tpl_final.get (), sidetpl_str.c_str(), - this->sidebar_title.c_str(), listitem.c_str()) ; - html.append ( tpl_final.get ()); - } - // no items in the sidebar, render as empty string (even if it has a heading) - // since heading becomes meaningless without items - else - html = ""; + html = fmt::format (sidetpl_str, + fmt::arg ("title", this->sidebar_title), + fmt::arg ("items", listitems)); + return html; } } diff --git a/biawebstrings.hpp b/biawebstrings.hpp index 1e073f0..702e5a9 100644 --- a/biawebstrings.hpp +++ b/biawebstrings.hpp @@ -8,7 +8,7 @@ namespace biaweb { const char* ART_LIST = "List of Articles"; const char* INDEX = "Index Page"; // DATE FORMAT - const char* DATE_FORMAT = "%d %b %Y, %H:%M"; + const char* DATE_FORMAT = "%d %b %Y, %H:%M %Z"; } #endif diff --git a/templates/doclist.tpl.html b/templates/doclist.tpl.html index 54bf4d4..206c4ac 100644 --- a/templates/doclist.tpl.html +++ b/templates/doclist.tpl.html @@ -1,4 +1,4 @@ -

%s

+

{title}

@@ -8,6 +8,6 @@ - %s + {docitems}
\ No newline at end of file diff --git a/templates/doclistitem.tpl.html b/templates/doclistitem.tpl.html index 4f16239..3a17d80 100644 --- a/templates/doclistitem.tpl.html +++ b/templates/doclistitem.tpl.html @@ -1,5 +1,5 @@ - %s - %s - %s + {doctitle} + {cdate:%d %b %Y, %H:%M %Z} + {mdate:%d %b %Y, %H:%M %Z} \ No newline at end of file diff --git a/templates/main.tpl.html b/templates/main.tpl.html index 0073bfc..804d24c 100644 --- a/templates/main.tpl.html +++ b/templates/main.tpl.html @@ -1,73 +1,27 @@ -My Site - %s - - +My Site - {title} + +
-
Created on: %s, last modified: %s
- %s +
Created on: {cdate:%d %b %Y, %H:%M %Z}, + last modified: {mdate:%d %b %Y, %H:%M %Z}
+ {contents}
- diff --git a/templates/sidebar.tpl.html b/templates/sidebar.tpl.html index a2e7c05..b4356ff 100644 --- a/templates/sidebar.tpl.html +++ b/templates/sidebar.tpl.html @@ -1,4 +1,4 @@ -

%s

+

{title}

    -%s +{items}
\ No newline at end of file diff --git a/templates/sidebaritem.tpl.html b/templates/sidebaritem.tpl.html index c6209ee..9ce49c0 100644 --- a/templates/sidebaritem.tpl.html +++ b/templates/sidebaritem.tpl.html @@ -1 +1 @@ -
  • %s
  • \ No newline at end of file +
  • {itemtext}
  • \ No newline at end of file diff --git a/templates/sidebarlinkitem.tpl.html b/templates/sidebarlinkitem.tpl.html index 07afc4b..ff74287 100644 --- a/templates/sidebarlinkitem.tpl.html +++ b/templates/sidebarlinkitem.tpl.html @@ -1 +1 @@ -
  • %s
  • \ No newline at end of file +
  • {itemtext}
  • \ No newline at end of file diff --git a/templates/style.tpl.css b/templates/style.tpl.css new file mode 100644 index 0000000..4cb611d --- /dev/null +++ b/templates/style.tpl.css @@ -0,0 +1,47 @@ +body { + background-color:white; + color: black; + font-family:Verdana, Geneva, Tahoma, sans-serif; + font-size: 0.9em; + margin: 0; + padding: 0; +} +h1, h2, h3, h4, h5, h6 { + font-family: Georgia, 'Times New Roman', Times, serif; +} +div#header { + width: 100%; + color: white; + background-color:#a1a0c0; + height: 50px; + float: left; +} +div#modification { + width: 100%; + color: darkslateblue; + font-size: 0.9em; + float:left; +} +div#footer { + width: 100%; + text-align: center; + background-color: #a1a0c0; + color: white; + float:left; +} +div#sidebar { + float :right; + background-color: #f0f0f0; + color: black; + width: 30%; + padding: 1%; +} + +div#content { + width: 63%; + margin-right:1%; + margin-left: 1%; + float: left; + line-height: 150%; + text-align: justify; +} -- 2.20.1