remove mustache
This commit is contained in:
@@ -118,12 +118,10 @@ void StaticFileFrontend::ProcessNewMessage(const fs::path &fpath)
|
||||
std::clog << "cannot find thread with root " << rootmsgid << std::endl;
|
||||
return;
|
||||
}
|
||||
TemplateEngine::Args_t thread_args;
|
||||
thread_args["posts"] = thread;
|
||||
if (m_TemplateEngine)
|
||||
{
|
||||
FileHandle_ptr out = OpenFile(threadFilePath, eWrite);
|
||||
if (!out || !m_TemplateEngine->WriteTemplate("thread.mustache", thread_args, out))
|
||||
if (!out || !m_TemplateEngine->WriteThreadPage(thread, out))
|
||||
{
|
||||
std::clog << "failed to write " << threadFilePath << std::endl;
|
||||
return;
|
||||
@@ -135,27 +133,19 @@ void StaticFileFrontend::ProcessNewMessage(const fs::path &fpath)
|
||||
uint32_t pageno = 0;
|
||||
while (pageno < m_Pages)
|
||||
{
|
||||
page.clear();
|
||||
page.threads.clear();
|
||||
if (!m_MessageDB->LoadBoardPage(page, name, 10, m_Pages))
|
||||
{
|
||||
std::clog << "cannot load board page " << pageno << " for " << name << std::endl;
|
||||
break;
|
||||
}
|
||||
TemplateEngine::Args_t page_args;
|
||||
page_args["group"] = name;
|
||||
page_args["threads"] = page;
|
||||
page_args["pageno"] = std::to_string(pageno);
|
||||
if (pageno)
|
||||
page_args["prev_pageno"] = std::to_string(pageno - 1);
|
||||
if (pageno + 1 < m_Pages)
|
||||
page_args["next_pageno"] = std::to_string(pageno + 1);
|
||||
fs::path boardPageFilename(name + "-" + std::to_string(pageno) + ".html");
|
||||
if (m_TemplateEngine)
|
||||
{
|
||||
fs::path outfile = m_OutDir / boardPageFilename;
|
||||
FileHandle_ptr out = OpenFile(outfile, eWrite);
|
||||
if (out)
|
||||
m_TemplateEngine->WriteTemplate("board.mustache", page_args, out);
|
||||
m_TemplateEngine->WriteBoardPage(page, out);
|
||||
else
|
||||
std::clog << "failed to open board page " << outfile << std::endl;
|
||||
}
|
||||
|
@@ -1,165 +1,92 @@
|
||||
#include <iostream>
|
||||
#include <mstch/mstch.hpp>
|
||||
#include <nntpchan/sanitize.hpp>
|
||||
#include <nntpchan/template_engine.hpp>
|
||||
#include <sstream>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
|
||||
template <class... Ts> struct overloaded : Ts...
|
||||
{
|
||||
using Ts::operator()...;
|
||||
};
|
||||
template <class... Ts> overloaded(Ts...)->overloaded<Ts...>;
|
||||
|
||||
namespace mustache = mstch;
|
||||
|
||||
static mustache::map post_to_map(const nntpchan::model::Post &post)
|
||||
{
|
||||
mustache::map m;
|
||||
mustache::array attachments;
|
||||
mustache::map h;
|
||||
|
||||
for (const auto &att : nntpchan::model::GetAttachments(post))
|
||||
struct StdTemplateEngine : public TemplateEngine
|
||||
{
|
||||
mustache::map a;
|
||||
a["filename"] = nntpchan::model::GetFilename(att);
|
||||
a["hexdigest"] = nntpchan::model::GetHexDigest(att);
|
||||
a["thumbnail"] = nntpchan::model::GetThumbnail(att);
|
||||
attachments.push_back(a);
|
||||
}
|
||||
|
||||
for (const auto &item : nntpchan::model::GetHeader(post))
|
||||
{
|
||||
mustache::array vals;
|
||||
for (const auto &v : item.second)
|
||||
vals.push_back(v);
|
||||
h[item.first] = vals;
|
||||
}
|
||||
|
||||
m["attachments"] = attachments;
|
||||
m["message"] = nntpchan::model::GetBody(post);
|
||||
m["header"] = h;
|
||||
return m;
|
||||
}
|
||||
|
||||
static mustache::map thread_to_map(const nntpchan::model::Thread &t)
|
||||
{
|
||||
mustache::map thread;
|
||||
mustache::array posts;
|
||||
for (const auto &post : t)
|
||||
{
|
||||
posts.push_back(post_to_map(post));
|
||||
}
|
||||
auto &opHeader = nntpchan::model::GetHeader(t[0]);
|
||||
thread["title"] = nntpchan::model::HeaderIFind(opHeader, "subject", "None")[0];
|
||||
thread["posts"] = posts;
|
||||
return thread;
|
||||
}
|
||||
|
||||
struct MustacheTemplateEngine : public TemplateEngine
|
||||
{
|
||||
struct Impl
|
||||
{
|
||||
|
||||
Impl(const std::map<std::string, std::string> &partials) : m_partials(partials) {}
|
||||
|
||||
bool ParseTemplate(const FileHandle_ptr &in)
|
||||
struct RenderContext
|
||||
{
|
||||
std::stringstream str;
|
||||
std::string line;
|
||||
while (std::getline(*in, line))
|
||||
str << line << "\n";
|
||||
m_tmplString = str.str();
|
||||
return in->eof();
|
||||
}
|
||||
|
||||
bool RenderFile(const Args_t &args, const FileHandle_ptr &out)
|
||||
{
|
||||
mustache::map obj;
|
||||
for (const auto &item : args)
|
||||
bool Load(const fs::path & path)
|
||||
{
|
||||
std::visit(overloaded{[&obj, item](const nntpchan::model::Model &m) {
|
||||
std::visit(overloaded{[&obj, item](const nntpchan::model::BoardPage &p) {
|
||||
mustache::array threads;
|
||||
for (const auto &thread : p)
|
||||
{
|
||||
threads.push_back(thread_to_map(thread));
|
||||
}
|
||||
obj[item.first] = threads;
|
||||
},
|
||||
[&obj, item](const nntpchan::model::Thread &t) {
|
||||
obj[item.first] = thread_to_map(t);
|
||||
}},
|
||||
m);
|
||||
},
|
||||
[&obj, item](const std::string &str) { obj[item.first] = str; }},
|
||||
item.second);
|
||||
// clear out previous data
|
||||
m_Data.clear();
|
||||
// open file
|
||||
std::ifstream f;
|
||||
f.open(path);
|
||||
if(f.is_open())
|
||||
{
|
||||
for(std::string line; std::getline(f, line, '\n');)
|
||||
{
|
||||
m_Data += line + "\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string str = mustache::render(m_tmplString, obj);
|
||||
out->write(str.c_str(), str.size());
|
||||
out->flush();
|
||||
return !out->fail();
|
||||
}
|
||||
virtual bool Render(const FileHandle_ptr & out) const = 0;
|
||||
|
||||
std::string m_tmplString;
|
||||
const std::map<std::string, std::string> &m_partials;
|
||||
};
|
||||
std::string m_Data;
|
||||
};
|
||||
|
||||
virtual bool WriteTemplate(const fs::path &fpath, const Args_t &args, const FileHandle_ptr &out)
|
||||
{
|
||||
auto templFile = OpenFile(fpath, eRead);
|
||||
if (!templFile)
|
||||
struct BoardRenderContext : public RenderContext
|
||||
{
|
||||
std::clog << "no such template at " << fpath << std::endl;
|
||||
return false;
|
||||
}
|
||||
const nntpchan::model::BoardPage & m_Page;
|
||||
|
||||
std::map<std::string, std::string> partials;
|
||||
if (!LoadPartials(fpath.parent_path(), partials))
|
||||
{
|
||||
std::clog << "failed to load partials" << std::endl;
|
||||
return false;
|
||||
}
|
||||
BoardRenderContext(const nntpchan::model::BoardPage & page) : m_Page(page) {};
|
||||
|
||||
Impl impl(partials);
|
||||
if (impl.ParseTemplate(templFile))
|
||||
{
|
||||
return impl.RenderFile(args, out);
|
||||
}
|
||||
|
||||
std::clog << "failed to parse template " << fpath << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LoadPartials(fs::path dir, std::map<std::string, std::string> &partials)
|
||||
{
|
||||
const auto partial_files = {"header", "footer"};
|
||||
for (const auto &fname : partial_files)
|
||||
{
|
||||
auto file = OpenFile(dir / fs::path(fname + std::string(".html")), eRead);
|
||||
if (!file)
|
||||
virtual bool Render(const FileHandle_ptr & out) const
|
||||
{
|
||||
std::clog << "no such partial: " << fname << std::endl;
|
||||
*out << m_Data;
|
||||
return false;
|
||||
}
|
||||
std::string line;
|
||||
std::stringstream input;
|
||||
while (std::getline(*file, line))
|
||||
input << line << "\n";
|
||||
partials[fname] = input.str();
|
||||
};
|
||||
|
||||
struct ThreadRenderContext : public RenderContext
|
||||
{
|
||||
const nntpchan::model::Thread & m_Thread;
|
||||
|
||||
ThreadRenderContext(const nntpchan::model::Thread & thread) : m_Thread(thread) {};
|
||||
|
||||
virtual bool Render(const FileHandle_ptr & out) const
|
||||
{
|
||||
*out << m_Data;
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
bool WriteBoardPage(const nntpchan::model::BoardPage & page, const FileHandle_ptr & out)
|
||||
{
|
||||
BoardRenderContext ctx(page);
|
||||
if(ctx.Load("board.html"))
|
||||
{
|
||||
return ctx.Render(out);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
bool WriteThreadPage(const nntpchan::model::Thread & thread, const FileHandle_ptr & out)
|
||||
{
|
||||
ThreadRenderContext ctx(thread);
|
||||
if(ctx.Load("thread.html"))
|
||||
{
|
||||
return ctx.Render(out);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
TemplateEngine *CreateTemplateEngine(const std::string &dialect)
|
||||
{
|
||||
auto d = ToLower(dialect);
|
||||
if (d == "mustache")
|
||||
return new MustacheTemplateEngine;
|
||||
if (d == "std")
|
||||
return new StdTemplateEngine;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
Reference in New Issue
Block a user