#include "App.hpp" #include "../fw/Negotiate.hpp" #include "../fw/Router.hpp" #include "../fw/StaticFiles.hpp" #include "../fw/Templates.hpp" #include "../fw/Validate.hpp" namespace molo::example::app { namespace { fw::Model contact_model() { return fw::Model( {{"name", fw::FieldType::String, true, 1, 80, 0, 0, false, ""}, {"email", fw::FieldType::Email, true, 3, 120, 0, 0, false, ""}, {"message", fw::FieldType::String, true, 1, 2000, 0, 0, false, ""}}); } fw::Model user_model() { fw::Field age{"age", fw::FieldType::Integer, true, 0, 0, 0, 150, true, ""}; return fw::Model( {{"username", fw::FieldType::String, true, 3, 40, 0, 0, false, ""}, {"email", fw::FieldType::Email, true, 3, 120, 0, 0, false, ""}, age}); } } // namespace void register_formats_demo(fw::Router& router, Services& services) { fw::Environment* env = services.templates.get(); std::map embedded = services.embedded; std::string static_root = services.static_root; router.get("/templates/page", "template-page", [env](fw::Request req) { (void)req; fw::TemplateCtx ctx; ctx["title"] = std::string("Templates"); ctx["heading"] = std::string("Template demo"); ctx["author"] = std::string("ada"); ctx["snippet"] = std::string("bold"); fw::TemplateList items; items.push_back({{"name", "extends"}, {"kind", "inheritance"}}); items.push_back({{"name", "include"}, {"kind", "partial"}}); items.push_back({{"name", "for"}, {"kind", "loop"}}); ctx["items"] = items; return fw::Response(200, env->render("page.html", ctx), "text/html; charset=utf-8"); }); router.get("/formats/data", "formats", [](fw::Request req) { std::vector offers = {"application/json", "application/xml", "text/html", "text/plain"}; std::string pick = fw::negotiate(req.headers.get("Accept"), offers); if (pick == "application/json") return fw::Response( 200, "{\"format\":\"json\",\"value\":42}", "application/json"); if (pick == "application/xml") return fw::Response(200, "42", "application/xml"); if (pick == "text/html") return fw::Response(200, "

value: 42

", "text/html; charset=utf-8"); return fw::Response(200, "value: 42", "text/plain; charset=utf-8"); }); router.get("/forms/contact", "contact-get", [env](fw::Request req) { (void)req; fw::TemplateCtx ctx; ctx["title"] = std::string("Contact"); ctx["posted"] = std::string(""); ctx["name"] = std::string(""); ctx["email"] = std::string(""); ctx["message"] = std::string(""); return fw::Response(200, env->render("contact.html", ctx), "text/html; charset=utf-8"); }); router.post("/forms/contact", "contact-post", [env](fw::Request req) { fw::Form form(contact_model()); fw::TemplateCtx ctx; ctx["title"] = std::string("Contact"); try { auto clean = form.bind(req); ctx["posted"] = std::string("true"); ctx["name"] = clean["name"]; ctx["email"] = clean["email"]; ctx["message"] = clean["message"]; } catch (const fw::ValidationError& e) { ctx["posted"] = std::string(""); auto input = fw::parse_form(req.body); ctx["name"] = input.count("name") ? input["name"] : ""; ctx["email"] = input.count("email") ? input["email"] : ""; ctx["message"] = input.count("message") ? input["message"] : ""; ctx["error"] = e.to_json(); return fw::Response(422, env->render("contact.html", ctx), "text/html; charset=utf-8"); } return fw::Response(200, env->render("contact.html", ctx), "text/html; charset=utf-8"); }); router.post("/validate/user", "validate-user", [](fw::Request req) { fw::Model model = user_model(); auto input = fw::parse_json_object_flat(req.body); if (input.empty()) input = fw::parse_form(req.body); try { auto clean = model.validate(input); return fw::JsonResponse( "{\"ok\":true,\"username\":\"" + fw::json_escape(clean["username"]) + "\"}", 200); } catch (const fw::ValidationError& e) { return fw::JsonResponse(e.to_json(), 422); } }); router.get("/static/{name}", "static", [static_root](fw::Request req) { return fw::serve_disk_file(static_root, req.param_or("name", "")); }); router.get("/embedded/{name}", "embedded", [embedded](fw::Request req) { return fw::serve_embedded(embedded, req.param_or("name", "")); }); router.get("/redirect/here", "redirect", [](fw::Request req) { bool permanent = req.query_or("mode", "temp") == "perm"; return fw::Response(fw::RedirectResponse("/health", permanent)); }); } } // namespace molo::example::app