basic templating
This commit is contained in:
parent
0d4efc8b77
commit
c7c560a352
|
@ -1,4 +0,0 @@
|
||||||
RewriteEngine on
|
|
||||||
RewriteBase /~j3parker/
|
|
||||||
RewriteRule ^pub/(.*) - [L]
|
|
||||||
RewriteRule ^(.*) bin/web [L]
|
|
157
src/web.d
157
src/web.d
|
@ -1,27 +1,27 @@
|
||||||
//#!/usr/bin/rdmd
|
//#!/usr/bin/rdmd
|
||||||
import std.stdio, std.path, std.process, std.file, std.array, std.string, std.algorithm, std.datetime, std.ascii;
|
import std.stdio, std.path, std.process, std.file, std.array, std.string, std.algorithm, std.datetime, std.ascii, std.regex;
|
||||||
import config;
|
import config;
|
||||||
|
|
||||||
string dweb_root;
|
string dweb_root;
|
||||||
|
string[string] template_variables;
|
||||||
|
string[string] headers;
|
||||||
|
|
||||||
string indent = "";
|
string write_link(string to, bool expand) {
|
||||||
void html(string s) { writeln(indent ~ s); }
|
|
||||||
void html_pop(string s) { indent = indent[0..max(0, $-4)]; html(s); }
|
|
||||||
void html_push(string s) { html(s); indent ~= " "; }
|
|
||||||
|
|
||||||
void write_link(string to, bool expand) {
|
|
||||||
bool isdir = dirExists(dweb_root ~ "/srv/" ~ to[url_root.length..$]);
|
bool isdir = dirExists(dweb_root ~ "/srv/" ~ to[url_root.length..$]);
|
||||||
string flair = nav_tree_chev? (expand? "» " : "› ") : "";
|
string flair = nav_tree_chev? (expand? "» " : "› ") : "";
|
||||||
html_push("<li" ~ (expand? " class=\"thisPage\" " : "") ~ ">");
|
string result = "";
|
||||||
html("<a href=\"" ~ to ~ (isdir ? "/" : "") ~ "\">"
|
result ~= "<li" ~ (expand? " class=\"thisPage\" " : "") ~ ">";
|
||||||
~ flair ~ baseName(to) ~ (isdir ? "/" : "") ~ "</a>");
|
result ~= "<a href=\"" ~ to ~ (isdir ? "/" : "") ~ "\">"
|
||||||
html_pop("</li>");
|
~ flair ~ baseName(to) ~ (isdir ? "/" : "") ~ "</a>";
|
||||||
|
result ~= "</li>";
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nav_tree_r(string url, string cur_loc, string[] subdirs) {
|
string nav_tree_r(string url, string cur_loc, string[] subdirs) {
|
||||||
|
string result = "";
|
||||||
string[] dirs = array(map!"a.name"(dirEntries(dweb_root ~ "/srv/" ~ cur_loc, SpanMode.shallow)));
|
string[] dirs = array(map!"a.name"(dirEntries(dweb_root ~ "/srv/" ~ cur_loc, SpanMode.shallow)));
|
||||||
sort(dirs);
|
sort(dirs);
|
||||||
if (dirs.length == 0) return;
|
if (dirs.length == 0) return "";
|
||||||
bool inserted_ul = false;
|
bool inserted_ul = false;
|
||||||
bool next = false;
|
bool next = false;
|
||||||
string next_loc;
|
string next_loc;
|
||||||
|
@ -31,15 +31,15 @@ void nav_tree_r(string url, string cur_loc, string[] subdirs) {
|
||||||
if (name.length == 0) continue; // e.g. ".md", should we do something else with these files?
|
if (name.length == 0) continue; // e.g. ".md", should we do something else with these files?
|
||||||
if (name == "index") continue; // "index" will never appear in the nav_tree.
|
if (name == "index") continue; // "index" will never appear in the nav_tree.
|
||||||
if (name[0] == '@') continue; // hidden file
|
if (name[0] == '@') continue; // hidden file
|
||||||
if (!inserted_ul) { html_push("<ul>"); inserted_ul = true; }
|
if (!inserted_ul) { result ~= "<ul>"; inserted_ul = true; }
|
||||||
bool expand = subdirs.length > 0 && name == subdirs[0];
|
bool expand = subdirs.length > 0 && name == subdirs[0];
|
||||||
write_link(url_root ~ stripExtension(s), expand);
|
result ~= write_link(url_root ~ stripExtension(s), expand);
|
||||||
|
|
||||||
if (expand && isDir(dweb_root ~ "/srv/" ~ s)) {
|
if (expand && isDir(dweb_root ~ "/srv/" ~ s)) {
|
||||||
if (nav_tree_vert) {
|
if (nav_tree_vert) {
|
||||||
html_push("<li>");
|
result ~= "<li>";
|
||||||
nav_tree_r(url, (cur_loc == "" ? "" : cur_loc ~ "/") ~ subdirs[0], subdirs[1..$]);
|
result ~= nav_tree_r(url, (cur_loc == "" ? "" : cur_loc ~ "/") ~ subdirs[0], subdirs[1..$]);
|
||||||
html_pop("</li>");
|
result ~= "</li>";
|
||||||
} else {
|
} else {
|
||||||
next = true;
|
next = true;
|
||||||
next_loc = (cur_loc == "" ? "" : cur_loc ~ "/") ~ subdirs[0];
|
next_loc = (cur_loc == "" ? "" : cur_loc ~ "/") ~ subdirs[0];
|
||||||
|
@ -47,57 +47,27 @@ void nav_tree_r(string url, string cur_loc, string[] subdirs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inserted_ul) html_pop("</ul>");
|
if (inserted_ul) result ~= "</ul>";
|
||||||
if (next) nav_tree_r(url, next_loc, subdirs[1..$]);
|
if (next) result ~= nav_tree_r(url, next_loc, subdirs[1..$]);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_nav_tree(string url) {
|
string do_nav_tree(string url) {
|
||||||
html_push("<div id=\"" ~ (nav_tree_vert ? "" : "horiz-") ~ "side-bar\">");
|
return nav_tree_r(url, "", cast(string[])array(pathSplitter(url)));
|
||||||
nav_tree_r(url, "", cast(string[])array(pathSplitter(url)));
|
|
||||||
html_pop("</div>\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void not_found(string path) {
|
string not_found(string path) {
|
||||||
html("The page <code>" ~ path ~ "</code> does not exist. (404)");
|
headers["Status"] = "404 Not Found";
|
||||||
}
|
return "The page <code>" ~ path ~ "</code> does not exist. (404)";
|
||||||
|
|
||||||
void do_header() {
|
|
||||||
html_push("<div id=\"header\">");
|
|
||||||
|
|
||||||
html_push("<div class=\"superHeader\">");
|
|
||||||
|
|
||||||
html_push("<div class=\"left\">");
|
|
||||||
html_pop("</div>");
|
|
||||||
|
|
||||||
html_push("<div class=\"right\">");
|
|
||||||
html("<a href=\"" ~ url_root ~ "changelog\">changelog</a>");
|
|
||||||
html_pop("</div>");
|
|
||||||
|
|
||||||
html_pop("</div>");
|
|
||||||
|
|
||||||
html_push("<div class=\"midHeader\">");
|
|
||||||
html_push("<h1 class=\"headerTitle\">");
|
|
||||||
html("<a href=\"" ~ url_root ~ "\">" ~ site_title ~ " <span id=\"headerSubTitle\">" ~ site_subtitle ~ "</span></a>");
|
|
||||||
html_pop("</h1>");
|
|
||||||
html_pop("</div>");
|
|
||||||
|
|
||||||
html_push("<div class=\"subHeader\">");
|
|
||||||
html("<br>");
|
|
||||||
html_pop("</div>");
|
|
||||||
|
|
||||||
html_pop("</div>\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dirExists(string path) { try { if (isDir(path)) return true; else return false; } catch (Exception e) { return false; } }
|
bool dirExists(string path) { try { if (isDir(path)) return true; else return false; } catch (Exception e) { return false; } }
|
||||||
|
|
||||||
void do_content(string url) {
|
string do_content(string url) {
|
||||||
html_push("<div id=\"main-copy\"" ~ (nav_tree_vert? " class=\"main-copy-side-bar\"" : "") ~ ">");
|
|
||||||
// first, see if we have something that wants to handle url outright
|
// first, see if we have something that wants to handle url outright
|
||||||
foreach (string glob, string h; handlers) {
|
foreach (string glob, string h; handlers) {
|
||||||
if (globMatch(url, glob)) {
|
if (globMatch(url, glob)) {
|
||||||
html(shell(dweb_root ~ "/bin/" ~ h ~ " " ~ url));
|
return shell(dweb_root ~ "/bin/" ~ h ~ " " ~ url);
|
||||||
html_pop("</div>");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if that failed, see if we can handle the file
|
// if that failed, see if we can handle the file
|
||||||
|
@ -108,29 +78,13 @@ void do_content(string url) {
|
||||||
if (stripExtension(name) == baseName(url)) {
|
if (stripExtension(name) == baseName(url)) {
|
||||||
foreach (string glob, string h; handlers) {
|
foreach (string glob, string h; handlers) {
|
||||||
if (globMatch(name, glob)) {
|
if (globMatch(name, glob)) {
|
||||||
html(shell(dweb_root ~ "/bin/" ~ h ~ " " ~ f));
|
return shell(dweb_root ~ "/bin/" ~ h ~ " " ~ f);
|
||||||
html_pop("</div>");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (baseName(url) != "index") not_found(url);
|
if (baseName(url) != "index") return not_found(url);
|
||||||
html_pop("</div>");
|
return "";
|
||||||
}
|
|
||||||
|
|
||||||
void do_footer() {
|
|
||||||
html_push("<div id=\"footer\">");
|
|
||||||
|
|
||||||
html_push("<div class=\"left\">");
|
|
||||||
html("<a href=\"" ~ url_root ~ "dweb\">Powered by dweb</a>");
|
|
||||||
html_pop("</div>");
|
|
||||||
|
|
||||||
html_push("<div class=\"right\">");
|
|
||||||
html(" ");
|
|
||||||
html_pop("</div>");
|
|
||||||
|
|
||||||
html_pop("</div>\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool evil(string s) {
|
bool evil(string s) {
|
||||||
|
@ -138,36 +92,41 @@ bool evil(string s) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string simple_template(string text, string[string] vars) {
|
||||||
|
return std.regex.replace!((match) { return vars[match[1]]; })(text, regex("\\{\\{\\s*(\\w+)\\s*\\}\\}", "g"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_headers() {
|
||||||
|
foreach (header, header_body; headers) {
|
||||||
|
writefln("%s: %s", header, header_body);
|
||||||
|
}
|
||||||
|
writeln();
|
||||||
|
}
|
||||||
|
|
||||||
void main(string[] args) {
|
void main(string[] args) {
|
||||||
init_handlers();
|
init_handlers();
|
||||||
dweb_root = getcwd()[0..$-4]; // take out bin/
|
dweb_root = getcwd()[0..$-4]; // take out bin/
|
||||||
|
headers["Content-Type"] = "text/html; charset=UTF-8";
|
||||||
html("Content-type: text/html\n");
|
|
||||||
html("<!DOCTYPE html>");
|
|
||||||
html_push("<html>\n");
|
|
||||||
|
|
||||||
string url = getenv("REQUEST_URI")[url_root.length..$];
|
string url = getenv("REQUEST_URI")[url_root.length..$];
|
||||||
if (evil(url)) { html ("bad url."); return; }
|
if (evil(url)) {
|
||||||
|
headers["Status"] = "400 Bad Request";
|
||||||
|
send_headers();
|
||||||
|
writeln("bad url.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
string pagename = baseName(url);
|
string pagename = baseName(url);
|
||||||
if (pagename.length != 0) pagename = " - " ~ pagename;
|
if (pagename.length != 0) pagename = " - " ~ pagename;
|
||||||
pagename = site_title ~ pagename;
|
pagename = site_title ~ pagename;
|
||||||
|
template_variables["url_root"] = url_root;
|
||||||
html_push("<head>");
|
template_variables["site_title"] = site_title;
|
||||||
html("<title>" ~ pagename ~ "</title>");
|
template_variables["site_subtitle"] = site_subtitle;
|
||||||
html("<link rel=\"stylesheet\" href=\"" ~ url_root ~ "pub/style/style.css\" type=\"text/css\" media=\"screen, handheld\" title=\"default\">");
|
template_variables["pagename"] = pagename;
|
||||||
html("<meta charset=\"UTF-8\">");
|
template_variables["nav_tree"] = do_nav_tree(url);
|
||||||
html("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
|
template_variables["content"] = do_content(url);
|
||||||
html_pop("</head>\n");
|
|
||||||
|
|
||||||
html_push("<body" ~ (page_container? " style=\"text-align: center\"" : "")~ ">");
|
|
||||||
if (page_container) html_push("<div id=\"container\">");
|
|
||||||
do_header();
|
|
||||||
do_nav_tree(url);
|
|
||||||
do_content(url);
|
|
||||||
do_footer();
|
|
||||||
if (page_container) html_pop("</div>");
|
|
||||||
html_pop("</body>\n");
|
|
||||||
|
|
||||||
html_pop("</html>");
|
send_headers();
|
||||||
|
string default_template = readText(dweb_root ~ "/templates/default.html");
|
||||||
|
write(simple_template(default_template, template_variables));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{{ pagename }}</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_root }}pub/style/style.css" type="text/css" media="screen, handheld" title="default">
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="header">
|
||||||
|
<div class="superHeader">
|
||||||
|
<div class="left">
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<a href="{{ url_root }}changelog">changelog</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="midHeader">
|
||||||
|
<h1 class="headerTitle">
|
||||||
|
<a href="{{ url_root }}">{{ site_title }}</a>
|
||||||
|
<span id="headerSubTitle">{{ site_subtitle }}</a>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="horiz-side-bar">
|
||||||
|
{{ nav_tree }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="main-copy">
|
||||||
|
{{ content }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footer">
|
||||||
|
<div class="left">
|
||||||
|
<a href="{{ url_root }}dweb">Powered by dweb</a>
|
||||||
|
</div>
|
||||||
|
<div class="right"> </div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue