#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 {
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 (tpl->get_stringbit (SUB_CAT) + this->title);
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);
par1 = par1->parent;
}
+ // rss feed
+ std::unique_ptr<RSSFeed> feed (new RSSFeed ());
+ feed.get()->set_pub_date (index.get()->get_creation_date());
+
+ // iterate through the documents and generate the document
for (Document doc : this->docs) {
+ // 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 to the document list
DocListItem item (doc.get_title(),
urlpath + doc.get_filename() + ".html",
doc.get_creation_date(), doc.get_modified_date (),
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
--- /dev/null
+#ifndef __BIAWEBRSSFEED__
+#define __BIAWEBRSSFEED__
+
+#include "biawebutil.hpp"
+#include "biawebtemplate.hpp"
+#include <ctime>
+#include <list>
+#include "fmt/format.h"
+
+namespace biaweb {
+ // class to define and implement an RSS feed item
+ class RSSFeedItem {
+ protected:
+ std::string title;
+ std::string description;
+ std::string url;
+ std::time_t pub_date;
+ public:
+ // Main Constructor
+ RSSFeedItem (std::string title, std::string desc,
+ std::string url, std::time_t pub) {
+ this->title = escape_html (title);
+ this->description = escape_html (desc);
+ this->url = url;
+ this->pub_date = pub;
+ }
+
+ // generate HTML using specified template
+ std::string to_html (Template *t);
+
+ std::string get_title() {
+ return this->title;
+ }
+ void set_title(std::string title) {
+ this->title = escape_html (title);
+ }
+ std::string get_description() {
+ return this->description;
+ }
+ void set_description(std::string description) {
+ this->description = escape_html (description);
+ }
+ std::string get_url() {
+ return this->url;
+ }
+ void set_url(std::string url) {
+ this->url = url;
+ }
+ std::time_t get_pub_date() {
+ return this->pub_date;
+ }
+ void set_pub_date(std::time_t pub_date) {
+ this->pub_date = pub_date;
+ }
+ };
+ std::string RSSFeedItem::to_html (Template *t) {
+ std::string item_tpl = t->get_rss_item_tpl ();
+
+ std::tm ct = *std::localtime (&this->pub_date);
+
+ std::string output = fmt::format (item_tpl,
+ fmt::arg ("title", this->title),
+ fmt::arg ("description", this->description),
+ fmt::arg ("url", this->url),
+ fmt::arg ("pubdate", ct));
+ return output;
+ }
+
+ // class to implement an RSS feed
+ class RSSFeed {
+ protected:
+ std::time_t pub_date;
+ std::list<RSSFeedItem> items;
+ public:
+ // add a feed item
+ void add_rss_item (RSSFeedItem item) {
+ this->items.insert (items.cend(), item);
+ }
+
+ // number of items
+ std::size_t get_num_items () {
+ return this->items.size ();
+ }
+
+ std::time_t get_pub_date() {
+ return this->pub_date;
+ }
+ void set_pub_date(std::time_t pub_date) {
+ this->pub_date = pub_date;
+ }
+
+ // output the RSS feed file as feed.xml
+ void output_to_html (Template *t, std::string path) {
+ std::string templ_str = t->get_rss_tpl ();
+ // only if there are feed items, output the feed.xml file
+ if (this->items.size () != 0) {
+ std::string items_str ;
+ // get the items
+ for (auto item : this->items)
+ items_str += item.to_html (t);
+
+ std::tm ct = *std::localtime (&this->pub_date);
+
+ std::string output = fmt::format (templ_str,
+ fmt::arg ("pubdate", ct),
+ fmt::arg ("items", items_str) );
+ std::ofstream f (path + "/feed.xml");
+ f << output;
+ f.close ();
+ }
+ }
+ };
+}
+
+#endif
\ No newline at end of file
\t<templatedir> - directory containing the templates\n \
NOTE: directory argument need not terminate with the separator (/)";
+ // MAXIMUM SIZE OF RSS FEED
+ const unsigned int MAX_RSS_FEED = 10;
+
// NAMED INDEX FOR DOCUMENT STRING BITS (LOADED FROM TEMPLATE FILE stringbits.txt)
const unsigned int HOME = 0;
const unsigned int ARTICLES_LIST = 1;
const unsigned int NAVIGATION = 3;
const unsigned int SUB_CAT = 4;
const unsigned int GO_UP = 5;
+ const unsigned int SUBSCRIBE = 6;
+ const unsigned int RSS_FEED = 7;
+
}
#endif
std::string navigationbit_tpl;
std::string sidebar_tpl;
std::string style_tpl;
- std::array<std::string, 6> stringbits;
+ std::string rss_tpl;
+ std::string rss_item_tpl;
+ std::array<std::string, 8> stringbits;
public:
// constructor: generate the template bits from a template directory
Template (std::string templatedir) ;
std::string get_sidebar_tpl () { return this->sidebar_tpl; }
std::string get_style_tpl () { return this->style_tpl; }
std::string get_stringbit (unsigned int id) { return this->stringbits[id]; }
+ std::string get_rss_tpl () { return this->rss_tpl; }
+ std::string get_rss_item_tpl () { return this->rss_item_tpl; }
};
// construct a template from a source directory
this->navigationbit_tpl = load_from_file (templatedir + "/navigationbit.tpl.html");
this->sidebar_tpl = load_from_file (templatedir + "/sidebar.tpl.html");
this->style_tpl = load_from_file (templatedir + "/style.tpl.css");
-
+ this->rss_tpl = load_from_file (templatedir + "/rss.tpl.xml");
+ this->rss_item_tpl = load_from_file (templatedir + "/rssitem.tpl.xml");
// read the stringbits into the array
std::ifstream f (templatedir + "/stringbits.txt");
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<rss version="2.0">
+<channel>
+ <!-- change title description and link as needed-->
+ <title>My Site</title>
+ <description>Site Description</description>
+ <link>http://my.site</link>
+ <pubDate>{pubdate:%a, %d %b %Y %H:%M:%S %z}</pubDate>
+ {items}
+</channel>
+</rss>
\ No newline at end of file
--- /dev/null
+ <item>
+ <title>{title}</title>
+ <description>{description}</description>
+ <!-- change http://my.site to your actual site URL -->
+ <!-- don't touch anything within the curly braces-->
+ <link>http://my.site/{url}</link>
+ <guid isPermaLink="false">http://my.site/{url}</guid>
+ <pubDate>{pubdate:%a, %d %b %Y %H:%M:%S %z}</pubDate>
+ </item>
\ No newline at end of file
Index Page
Navigation
Sub categories:
-Go up
\ No newline at end of file
+Go up
+Subscribe
+RSS Feed
\ No newline at end of file