fkin finally
This commit is contained in:
13
src/errors.cpp
Normal file
13
src/errors.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include "errors.hpp"
|
||||
|
||||
|
||||
std::string render_404_template(const crow::request& req) {
|
||||
return templating.render_template_string("errors/404.html", {{"requested_url", req.url}});
|
||||
}
|
||||
|
||||
void CustomErrorHandler::after_handle(crow::request& req, crow::response& res, context&) {
|
||||
if (res.code == 404 && res.body.empty()) {
|
||||
res.set_header("Content-Type", "text/html");
|
||||
res.body = render_404_template(req);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#define CROW_STATIC_DIRECTORY "../static"
|
||||
#include "templating.hpp"
|
||||
#include "errors.hpp"
|
||||
#include <crow.h>
|
||||
|
||||
|
||||
@@ -7,7 +8,7 @@ Templating templating{"../templates"};
|
||||
|
||||
|
||||
int main() {
|
||||
crow::SimpleApp app;
|
||||
crow::App<CustomErrorHandler> app;
|
||||
|
||||
CROW_ROUTE(app, "/")([]() {
|
||||
return templating.render_template("index.html");
|
||||
|
||||
@@ -1,16 +1,76 @@
|
||||
#include "templating.hpp"
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <stdexcept>
|
||||
|
||||
Templating::Templating(const std::string& template_dir)
|
||||
: inja_env(std::filesystem::canonical(template_dir).string()),
|
||||
template_dir(std::filesystem::canonical(template_dir).string())
|
||||
{
|
||||
inja_env.set_search_included_templates_in_files(true);
|
||||
}
|
||||
|
||||
std::string Templating::preprocess_template(const std::string& template_name) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
fs::path abs_template_dir = fs::path(template_dir);
|
||||
fs::path abs_template_file = fs::canonical(abs_template_dir / template_name);
|
||||
|
||||
std::ifstream file(abs_template_file);
|
||||
if (!file.is_open()) {
|
||||
throw std::runtime_error("Failed to open template file: " + abs_template_file.string());
|
||||
}
|
||||
|
||||
std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||
|
||||
std::regex extends_regex(R"(\{\%\s*extends\s*(['"])(.+?)\1\s*\%\})");
|
||||
std::smatch match;
|
||||
|
||||
if (std::regex_search(content, match, extends_regex)) {
|
||||
std::string quote = match[1].str();
|
||||
std::string original_path = match[2].str();
|
||||
|
||||
if (original_path.find("/") == std::string::npos &&
|
||||
!original_path.empty() &&
|
||||
original_path.front() != '/') {
|
||||
|
||||
fs::path abs_extended_template = fs::canonical(abs_template_dir / original_path);
|
||||
fs::path rel_path = fs::relative(abs_extended_template, abs_template_file.parent_path());
|
||||
|
||||
std::string new_path = rel_path.generic_string();
|
||||
|
||||
content = std::regex_replace(content, extends_regex,
|
||||
"{% extends " + quote + new_path + quote + " %}");
|
||||
}
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
crow::response Templating::render_template(const std::string& template_name, const inja::json& data) {
|
||||
try {
|
||||
inja::Template template_obj = inja_env.parse_template(template_name);
|
||||
std::string rendered = inja_env.render(template_obj, data);
|
||||
std::string preprocessed = preprocess_template(template_name);
|
||||
inja::Template tpl = inja_env.parse(preprocessed);
|
||||
std::string rendered = inja_env.render(tpl, data);
|
||||
return crow::response(rendered);
|
||||
|
||||
} catch (const inja::RenderError& e) {
|
||||
} catch (const std::exception& e) {
|
||||
return crow::response(500, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
crow::response Templating::render_template(const std::string& template_name) {
|
||||
return render_template(template_name, inja::json{});
|
||||
}
|
||||
}
|
||||
|
||||
std::string Templating::render_template_string(const std::string& template_name, const inja::json& data) {
|
||||
std::string preprocessed = preprocess_template(template_name);
|
||||
inja::Template tpl = inja_env.parse(preprocessed);
|
||||
return inja_env.render(tpl, data);
|
||||
}
|
||||
|
||||
std::string Templating::render_template_string(const std::string& template_name) {
|
||||
return render_template_string(template_name, inja::json{});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user