article.cpp (4647B)
1 #include <format> 2 #include <iostream> 3 #include <numeric> 4 5 #include "article.hpp" 6 7 #include <hemplate/attribute.hpp> 8 #include <hemplate/classes.hpp> 9 10 #include "utility.hpp" 11 12 namespace stamd { 13 14 std::optional<std::string> article::get(const std::string& key) const 15 { 16 const auto itr = m_symbols.find(key); 17 if (itr == end(m_symbols)) 18 { 19 // std::cerr << "Warning: getting invalid value for: " << key << std::endl; 20 return {}; 21 } 22 return itr->second; 23 } 24 25 std::string article::get_filename() const 26 { 27 return m_symbols.find("filename")->second; 28 } 29 30 std::string article::get_date() const 31 { 32 return get("date").value_or("0000-00-00"); 33 } 34 35 std::string article::get_title() const 36 { 37 return get("title").value_or(get_filename()); 38 } 39 40 std::string article::get_language() const 41 { 42 return get("language").value_or("en"); 43 } 44 45 void article::print_nav(std::ostream& ost) 46 { 47 using namespace hemplate; // NOLINT 48 49 static const char* base = "https://dimitrijedobrota.com/blog"; 50 51 ost << html::nav() 52 .add(html::a("<-- back", {{"class", "back"}})) 53 .add(html::a("index", {{"href", base}})) 54 .add(html::a("home -->", {{"href", "/"}})); 55 } 56 57 void article::print_categories(std::ostream& ost, 58 const categories_t& categories) 59 { 60 using namespace hemplate; // NOLINT 61 62 ost << html::nav().set("class", "categories"); 63 ost << html::h3("Categories: "); 64 ost << html::p(); 65 for (const auto& category : categories) 66 { 67 auto ctgry = category; 68 normalize(ctgry); 69 ost << html::a(category, {{"href", std::format("./{}.html", ctgry)}}); 70 } 71 ost << html::p(); 72 ost << html::nav(); 73 } 74 75 void article::write_header(std::ostream& ost) const 76 { 77 using namespace hemplate; // NOLINT 78 79 static const char* description_s = 80 "Dimitrije Dobrota's personal site. You can find my daily " 81 "findings in a " 82 "form of articles on my blog as well as various programming " 83 "projects."; 84 85 static const attributeList icon = {{"rel", "icon"}, {"type", "image/png"}}; 86 static const attributeList style = {{"rel", "stylesheet"}, 87 {"type", "text/css"}}; 88 89 static const attributeList viewport = { 90 {"content", "width=device-width, initial-scale=1"}, 91 {"name", "viewport"}}; 92 93 static const attributeList description = {{"name", "description"}, 94 {"content", description_s}}; 95 96 static const attributeList rss = {{"rel", "alternate"}, 97 {"type", "application/atom+xml"}, 98 {"title", "RSS feed"}, 99 {"href", "/blog/rss.xml"}}; 100 101 static const attributeList atom = {{"rel", "alternate"}, 102 {"type", "application/atom+xml"}, 103 {"title", "Atom feed"}, 104 {"href", "/blog/atom.xml"}}; 105 106 ost << html::doctype(); 107 ost << html::html().set("lang", get_language()); 108 ost << html::head() 109 .add(html::title(get_title())) 110 .add(html::meta(viewport)) 111 .add(html::meta({{"charset", "UTF-8"}})) 112 .add(html::meta(description)) 113 .add(html::link(style).set("href", "/css/index.css")) 114 .add(html::link(style).set("href", "/css/colors.css")) 115 .add(html::link(rss)) 116 .add(html::link(atom)) 117 .add(html::link(icon) 118 .set("sizes", "32x32") 119 .set("href", "/img/favicon-32x32.png")) 120 .add(html::link(icon) 121 .set("sizes", "16x16") 122 .set("href", "/img/favicon-16x16.png")); 123 124 ost << html::body(); 125 ost << html::input() 126 .set("type", "checkbox") 127 .set("id", "theme_switch") 128 .set("class", "theme_switch"); 129 130 ost << html::div().set("id", "content"); 131 132 if (!m_nonav) 133 { 134 ost << html::header(); 135 print_nav(ost); 136 ost << html::hr(); 137 ost << html::header(); 138 } 139 140 ost << html::main(); 141 ost << html::label(" ") 142 .set("for", "theme_switch") 143 .set("class", "switch_label"); 144 145 if (!m_categories.empty()) print_categories(ost, m_categories); 146 } 147 148 void article::write_footer(std::ostream& ost) const 149 { 150 using namespace hemplate; // NOLINT 151 152 ost << html::main(); 153 154 if (!m_nonav) 155 { 156 ost << html::footer(); 157 ost << html::hr(); 158 print_nav(ost); 159 ost << html::footer(); 160 } 161 162 ost << html::div(); 163 ost << html::script(" ").set("src", "/scripts/main.js"); 164 ost << html::body(); 165 ost << html::html(); 166 } 167 168 } // namespace stamd