Readme.md - added Section for customization and notes
[biaweb2.git] / biawebdocumenttree.hpp
index 9122feb..a9f1ccd 100644 (file)
@@ -11,6 +11,8 @@
 #include "biawebstrings.hpp"
 #include "biawebutil.hpp"
 #include "biawebdoclist.hpp"
+#include "biawebtemplate.hpp"
+#include "biawebrss.hpp"
 
 // class to implement a document tree - both with or without subtrees
 namespace biaweb {
@@ -29,17 +31,12 @@ namespace biaweb {
         std::string stub;
         // list of documents in this tree
         std::list<Document> docs;
-        // common strings used for template generation 
-        std::array<std::string, 6> doc_strings;
         // set the parent - protected function as this has to be 
         // called only by add_child
         void set_parent (DocumentTree *parent) {
             this->parent = parent;
         }
 
-        // load document generation strings from file stringbits.txt from template dir
-        void load_doc_strings (std::string templatedir);
-
       public:
         // method to build a document tree from a path
         void document_tree_builder (std::string srcpath);
@@ -77,7 +74,7 @@ namespace biaweb {
         }
 
         // create the document index for this tree
-        void create_tree_html (std::string templatedir, std::string destdir);
+        void create_tree_html (Template *t, std::string destdir);
 
         // set the title 
         void set_title (std::string title) {
@@ -136,22 +133,6 @@ namespace biaweb {
             return lev;
     }
 
-    // load document generation strings from file stringbits.txt from template dir
-    void DocumentTree::load_doc_strings (std::string templatedir) {
-        // load the template file
-        std::ifstream stringsfile (templatedir + "/stringbits.txt");
-        
-        std::string line;
-        // read line by line and append it to doc_strings
-        int i = 0;
-        while (! stringsfile.eof () && i < this->doc_strings.size ()) {
-            std::getline (stringsfile, line);
-            this->doc_strings[i] = line;
-            i ++;
-        }
-        stringsfile.close ();
-    }
-
     // get the stub hierarchy for this tree
     std::string DocumentTree::stub_hierarchy () {
             std::list<std::string> levels;
@@ -185,9 +166,7 @@ namespace biaweb {
 
     // create the tree - the index file for this tree and all the documents and
     // the child trees recursively - using the template specified
-    void DocumentTree::create_tree_html (std::string templatedir, std::string destdir) {
-        // load the document string bits to be used in templates
-        this->load_doc_strings (templatedir);
+    void DocumentTree::create_tree_html (Template *tpl, std::string destdir) {
 
         // create a document to represent the index of the tree.
         std::unique_ptr<Document> index (new Document (this->title));
@@ -208,21 +187,20 @@ namespace biaweb {
         // If this tree has a parent, create a sidebar link to the level up
         std::unique_ptr<SideBar> bar1 (new SideBar());
         GenericLinkItem item0;
-        bar1.get()->set_title (this->doc_strings [NAVIGATION]);
-        item0.set_item_text (this->doc_strings[INDEX]);
+        bar1.get()->set_title (tpl->get_stringbit (NAVIGATION));
+        item0.set_item_text (tpl->get_stringbit (INDEX));
         item0.set_item_url (urlpath + "index.html");
         bar1.get()->add_sidebar_item (item0);
         if (this->get_parent() != nullptr) {
             GenericLinkItem item1;
-            item1.set_item_text (this->doc_strings[GO_UP]);
+            item1.set_item_text (tpl->get_stringbit(GO_UP));
             item1.set_item_url (this->stub_hierarchy() + "index.html");
             bar1.get()->add_sidebar_item (item1);
         }
-        index.get()->add_side_bar (*bar1.get());
-
         // create a sidebar for the child levels if there are children
         std::unique_ptr<SideBar> bar2 (new SideBar ());
-        bar2.get()->set_title (this->doc_strings[SUB_CAT] + this->title);
+        bar2.get()->set_title (tpl->get_stringbit (SUB_CAT) + this->title);
         for (DocumentTree tree : this->children) {
             // we use site relative URLs that rely on the base href tag
             // so for biaweb generated sites, the base href tag should be 
@@ -231,14 +209,13 @@ namespace biaweb {
                                             tree.stub + "/" + "index.html");
             bar2.get()->add_sidebar_item (item);
         }
-        index.get()->add_side_bar (*bar2.get());
 
         // create the path and then the index file
         std::filesystem::create_directories (filepath);
 
         // Create the list of documents in this tree with links
         std::unique_ptr<DocList> article_list (new DocList ());
-        article_list.get()->set_title (this->title + ": " + this->doc_strings[ARTICLES_LIST]);
+        article_list.get()->set_title (this->title + ": " + tpl->get_stringbit (ARTICLES_LIST));
         // sort the documents as per creation time and then add the document
         // links - newest documents should appear above older ones.
         sort_documents_creation_time ();
@@ -250,37 +227,69 @@ namespace biaweb {
         // an inline list
         while (par1 != nullptr) {
             if (par1->parent != nullptr)
-                navbit.get()->add_link_item (GenericLinkItem(par1->stub
+                navbit.get()->add_link_item (GenericLinkItem(par1->title
                             par1->stub_hierarchy() + par1->stub + "/index.html"));
             else
-                navbit.get()->add_link_item (GenericLinkItem(this->doc_strings[HOME], "index.html"));
+                navbit.get()->add_link_item (GenericLinkItem(tpl->get_stringbit(HOME), "index.html"));
             par1 = par1->parent;
         }
 
+        // rss feed
+        std::unique_ptr<RSSFeed> feed (new RSSFeed ());
+        feed.get()->set_pub_date (index.get()->get_creation_date());
+        feed.get()->set_title (this->get_title());
+
+        // iterate through the documents and generate the document
         for (Document doc : this->docs) {
-            DocListItem item (doc.get_title(),
-                            urlpath + doc.get_filename() + ".html", 
-                            doc.get_creation_date(), doc.get_modified_date ());
+            // Add the document to RSS feed
+            RSSFeedItem fitem (doc.get_title(), doc.get_meta_desc (),
+                        urlpath + doc.get_filename() + ".html", 
+                        doc.get_creation_date());
+            // If the items don't exceed max size of RSS feed
+            if (feed.get()->get_num_items() < MAX_RSS_FEED)
+                feed.get()->add_rss_item (fitem);                        
+            // Add the document details to the document list
+            DocListItem item (&doc, urlpath);
             article_list.get()->add_document_item (item);
             // output the document also, add the navigation bit and side bars
 
             doc.set_navigation_bit (*navbit.get());
             doc.add_side_bar (*bar1.get());
             doc.add_side_bar (*bar2.get());
-            doc.output_to_html (templatedir, filepath);
+            doc.output_to_html (tpl, filepath);
+        }
+
+        // output the rss feed 
+        feed.get()->output_to_html (tpl, filepath);
+
+        // add the side bars
+        index.get()->add_side_bar (*bar1.get());
+        index.get()->add_side_bar (*bar2.get());
+
+        // sidebar for RSS feed
+        // if there are are items in the feed add the link
+        if (feed.get()->get_num_items () > 0) {
+            std::unique_ptr<SideBar> bar3 (new SideBar ());
+            bar3.get()->set_title (tpl->get_stringbit (SUBSCRIBE));
+            bar3.get()->add_sidebar_item (
+                    GenericLinkItem (tpl->get_stringbit(RSS_FEED), urlpath + "feed.xml"));
+            index.get()->add_side_bar (*bar3.get());
         }
 
         // add the navigation bit
         index.get()->set_navigation_bit (*navbit.get());
-        // index should contain the summary followed by the article list
-        index.get()->set_content (this->summary + article_list.get()->to_html(templatedir));
+        // index should contain the summary followed by the the article list
+        // and the sub categories
+        index.get()->set_content (this->summary +
+                                article_list.get()->to_html(tpl) +
+                                bar2.get()->to_html (tpl));
 
         // output the index file
-        index.get()->output_to_html (templatedir, filepath);
+        index.get()->output_to_html (tpl, filepath);
 
         // recursively create index for children
         for (DocumentTree tree : this->children)
-            tree.create_tree_html (templatedir, destdir);
+            tree.create_tree_html (tpl, destdir);
     }
 
     // build a document tree from a filesystem path recursively
@@ -300,16 +309,14 @@ namespace biaweb {
                     
                     this->add_child (doctree.get());
                 }
-                // add the regular files as documents in the tree
-                else if (fsitem.is_regular_file ()) {
+                // add the regular files as documents in the tree and not symlink
+                else if (fsitem.is_regular_file () && !fsitem.is_symlink()) {
                     // if it is an index file (specially named as index 
                     // or index.md or whatever) directly add 
                     // the contents to the summary of the Doctree 
                     if (fsitem.path().stem().string() == "index")
                     {
-                        std::ifstream infile (fsitem.path());
-                        std::string infilestr ( (std::istreambuf_iterator<char> (infile)),
-                                                (std::istreambuf_iterator<char> ()) );
+                        std::string infilestr = load_from_file (fsitem.path ()); 
                         this->set_markdown_summary (infilestr);
                     }
                     // else it is a non-index file-