| 1261 | } |
| 1262 | |
| 1263 | void Webserver::RenderUrlWithTemplate(const struct sq_connection* connection, |
| 1264 | const WebRequest& req, const UrlHandler& url_handler, stringstream* output, |
| 1265 | ContentType* content_type, const std::string& csrf_token) { |
| 1266 | Document document; |
| 1267 | document.SetObject(); |
| 1268 | GetCommonJson(&document, connection, req, csrf_token); |
| 1269 | |
| 1270 | const auto& arguments = req.parsed_args; |
| 1271 | url_handler.callback()(req, &document); |
| 1272 | bool plain_json = (arguments.find("json") != arguments.end()) |
| 1273 | || document.HasMember(ENABLE_PLAIN_JSON_KEY); |
| 1274 | if (plain_json) { |
| 1275 | // Callbacks may optionally be rendered as a text-only, pretty-printed Json document |
| 1276 | // (mostly for debugging or integration with third-party tools). |
| 1277 | StringBuffer strbuf; |
| 1278 | // Write the JSON out with human-readable formatting. The settings are tweaked to |
| 1279 | // reduce extraneous whitespace characters, compared to the default formatting. |
| 1280 | PrettyWriter<StringBuffer> writer(strbuf); |
| 1281 | writer.SetIndent('\t', 1); |
| 1282 | writer.SetFormatOptions(kFormatSingleLineArray); |
| 1283 | document.Accept(writer); |
| 1284 | (*output) << strbuf.GetString(); |
| 1285 | *content_type = JSON; |
| 1286 | } else { |
| 1287 | if (arguments.find("raw") != arguments.end()) { |
| 1288 | document.AddMember(rapidjson::StringRef(ENABLE_RAW_HTML_KEY), "true", |
| 1289 | document.GetAllocator()); |
| 1290 | } |
| 1291 | if (document.HasMember(ENABLE_RAW_HTML_KEY)) { |
| 1292 | *content_type = PLAIN; |
| 1293 | } |
| 1294 | |
| 1295 | const string& full_template_path = |
| 1296 | Substitute("$0/$1/$2", FLAGS_webserver_doc_root, DOC_FOLDER, |
| 1297 | url_handler.template_filename()); |
| 1298 | ifstream tmpl(full_template_path.c_str()); |
| 1299 | if (!tmpl.is_open()) { |
| 1300 | (*output) << "Could not open template: " << full_template_path; |
| 1301 | *content_type = PLAIN; |
| 1302 | } else { |
| 1303 | stringstream buffer; |
| 1304 | buffer << tmpl.rdbuf(); |
| 1305 | bool success = RenderTemplate(buffer.str(), |
| 1306 | Substitute("$0/", FLAGS_webserver_doc_root), document, |
| 1307 | output); |
| 1308 | LOG_IF(WARNING, !success) << "could not render template " << full_template_path; |
| 1309 | } |
| 1310 | } |
| 1311 | } |
| 1312 | |
| 1313 | void Webserver::RegisterUrlCallback(const string& path, |
| 1314 | const string& template_filename, const UrlCallback& callback, bool is_on_nav_bar) { |