commit
c3c1116e5f
@ -0,0 +1,3 @@ |
||||
pub/* |
||||
srv/* |
||||
bin/web |
@ -0,0 +1,4 @@ |
||||
RewriteEngine on |
||||
RewriteBase /~j3parker/ |
||||
RewriteRule ^pub/(.*) - [L] |
||||
RewriteRule ^(.*) /users/j3parker/www/bin/web [L] |
@ -0,0 +1,2 @@ |
||||
Options +ExecCGI |
||||
SetHandler cgi-script |
@ -0,0 +1,3 @@ |
||||
echo "<ul>" |
||||
git log --pretty=format:'<li>%s - %aN (%ae) <b>(%cr)</b></li>' --abbrev-commit --date=relative |
||||
echo "</ul>" |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,335 @@ |
||||
/* Default werc style */ |
||||
|
||||
/* General style guidelines: |
||||
- All font-size at least 14px (recommended 16px) |
||||
- Line-height: 1.5 for paragraph body, 1.1 for header |
||||
*/ |
||||
|
||||
body { |
||||
color: black; |
||||
background-color: white; |
||||
font-family: Helvetica, Verdana, Arial, 'Liberation Sans', FreeSans, sans-serif; |
||||
font-size: 84%; /* Enables font size scaling in MSIE */ |
||||
margin: 0; |
||||
padding: 0; |
||||
} |
||||
|
||||
|
||||
/* # Header # */ |
||||
.superHeader { |
||||
color: white; |
||||
background-color: rgb(100,135,220); |
||||
height: 1.6em; |
||||
} |
||||
|
||||
.superHeader img { vertical-align: bottom; } |
||||
|
||||
.superHeader a { |
||||
color: white; |
||||
background-color: transparent; |
||||
font-size: 91%; |
||||
margin: 0; |
||||
padding: 0 0.5ex 0 0.25ex; |
||||
} |
||||
|
||||
a { text-decoration: none; } |
||||
a:hover { text-decoration: underline; } |
||||
|
||||
.superHeader div { |
||||
position: absolute; |
||||
top: 0.40ex; |
||||
} |
||||
|
||||
.superHeader .left { left: 0.4em; } |
||||
.superHeader .right { right: 0.4em; } |
||||
|
||||
.midHeader { |
||||
color: rgb(39,78,144); |
||||
background-color: rgb(140,170,230); |
||||
background-color: #ff6d06; |
||||
border: solid 0 black; |
||||
border-width: 2px 0; |
||||
} |
||||
|
||||
.headerTitle { |
||||
color: black; |
||||
font-size: 233%; |
||||
font-weight: normal; |
||||
margin: 0 0 0 4mm; |
||||
padding: 0.25ex 0; |
||||
} |
||||
#headerSubTitle { |
||||
font-size: 50%; |
||||
font-style: italic; |
||||
margin-left: 1em; |
||||
} |
||||
|
||||
.headerTitle a { color: black; } |
||||
.headerTitle a:hover { text-decoration: none; } |
||||
|
||||
.subHeader { |
||||
display: none; |
||||
color: white; |
||||
background-color: rgb(0,51,153); |
||||
margin: 0; |
||||
padding: 1ex 1ex 1ex 1.5mm; |
||||
} |
||||
|
||||
.subHeader a { |
||||
color: white; |
||||
background-color: transparent; |
||||
font-weight: bold; |
||||
margin: 0; |
||||
padding: 0 0.75ex 0 0.5ex; |
||||
} |
||||
|
||||
.superHeader .highlight, .subHeader .highlight { |
||||
color: rgb(253,160,91); |
||||
background-color: transparent; |
||||
} |
||||
|
||||
|
||||
/* # Side # */ |
||||
#side-bar { |
||||
width: 16em; |
||||
float: left; |
||||
clear: left; |
||||
border-right: 1px solid #ddd; |
||||
} |
||||
|
||||
#side-bar div { |
||||
border-bottom: 1px solid #ddd; |
||||
} |
||||
|
||||
.sideBarTitle { |
||||
font-weight: bold; |
||||
margin: 0 0 0.5em 2mm; |
||||
padding: 1em 0 0 0; |
||||
} |
||||
|
||||
#side-bar ul { |
||||
list-style-type: none; |
||||
list-style-position: outside; |
||||
margin: 0; |
||||
padding: 0 0 0.3em 0; |
||||
} |
||||
|
||||
li ul { |
||||
padding-left: 0.6em !important; |
||||
} |
||||
|
||||
#side-bar li { |
||||
margin: 0; |
||||
padding: 0.1ex 0; /* Circumvents a rendering bug (?) in MSIE 6.0 XXX should move to iehacks.css, this causes an ugly gap */ |
||||
} |
||||
|
||||
#side-bar a { |
||||
color: rgb(0,102,204); |
||||
background-color: transparent; |
||||
margin: 0; |
||||
padding: 0.25em 1ex 0.25em 2mm; |
||||
display: block; |
||||
text-transform: capitalize; |
||||
font-weight: bold!important; |
||||
font-size: 102%; |
||||
border-left: white solid 0.2em; |
||||
} |
||||
|
||||
.thisPage, .thisPage a { |
||||
color: black!important; |
||||
background-color: white; |
||||
padding-left: 5mm; |
||||
} |
||||
|
||||
#side-bar a:hover { |
||||
color: white; |
||||
background-color: rgb(100,135,220); |
||||
border-left: black solid 0.2em; |
||||
text-decoration: none; |
||||
} |
||||
|
||||
.sideBarText { |
||||
line-height: 1.5em; |
||||
margin: 0 0 1em 0; |
||||
padding: 0 1.5ex 0 2.5mm; |
||||
display: block; |
||||
} |
||||
|
||||
#side-bar .sideBarText a { |
||||
margin: 0; |
||||
padding: 0; |
||||
display: inline; |
||||
} |
||||
|
||||
#side-bar .sideBarText a:hover { |
||||
color: rgb(0,102,204); |
||||
background-color: transparent; |
||||
text-decoration: none; |
||||
} |
||||
|
||||
|
||||
/* # Main Copy # */ |
||||
#main-copy { |
||||
max-width: 70em; |
||||
color: black; |
||||
background-color: transparent; |
||||
text-align: justify; |
||||
line-height: 1.5em; |
||||
margin: 0em 0 0 16em; |
||||
padding: 0.5mm 5mm 5mm 5mm; |
||||
border-left: 1px solid #ddd; |
||||
} |
||||
|
||||
#bodyText { |
||||
margin: 0 0 0 15.5em; |
||||
padding: 2mm 5mm 2mm 5mm; |
||||
} |
||||
|
||||
#main-copy p { |
||||
margin: 1em 1ex 1em 1ex !important; /* Need !important so troff-generated pages don't look totally squezed */ |
||||
padding: 0; |
||||
} |
||||
|
||||
#main-copy a { |
||||
color: rgb(0,102,204); |
||||
background-color: transparent; |
||||
} |
||||
|
||||
#main-copy a:hover { |
||||
color: rgb(100,135,220); |
||||
} |
||||
|
||||
#main-copy h1, #main-copy h2 { |
||||
color: rgb(0,102,204); |
||||
background-color: transparent; |
||||
font-size: 145.5%; |
||||
font-weight: bold; |
||||
margin: 2em 0 0 0; |
||||
padding: 0.5ex 0 0.5ex 0.6ex; |
||||
border-bottom: 2px solid rgb(0,102,204); |
||||
} |
||||
|
||||
#main-copy h2 { |
||||
font-size: 115.5%; |
||||
border-bottom: 1px solid rgb(0,102,204); |
||||
} |
||||
|
||||
#main-copy .topOfPage { |
||||
color: rgb(0,102,204); |
||||
background-color: transparent; |
||||
font-size: 91%; |
||||
font-weight: bold; |
||||
text-decoration: none; |
||||
margin: 3ex 1ex 0 0; |
||||
padding: 0; |
||||
float: right; |
||||
} |
||||
|
||||
dl { |
||||
margin: 1em 1ex 2em 1ex; |
||||
padding: 0; |
||||
} |
||||
|
||||
dt { |
||||
font-weight: bold; |
||||
margin: 0 0 0 0; |
||||
padding: 0; |
||||
} |
||||
|
||||
dd { |
||||
margin: 0 0 2em 2em; |
||||
padding: 0; |
||||
} |
||||
|
||||
|
||||
/* # Footer # */ |
||||
#footer { |
||||
color: white; |
||||
background-color: rgb(100,135,220); |
||||
padding: 1em; |
||||
clear: both; |
||||
} |
||||
|
||||
#footer .left { |
||||
text-align: left; |
||||
line-height: 1.55em; |
||||
float: left; |
||||
clear: left; |
||||
} |
||||
|
||||
#footer .right { |
||||
text-align: right; |
||||
line-height: 1.45em; |
||||
} |
||||
|
||||
#footer a { |
||||
color: white; |
||||
background-color: transparent; |
||||
} |
||||
|
||||
|
||||
/* GENERAL */ |
||||
|
||||
table { |
||||
border: solid 1px black; |
||||
} |
||||
th { |
||||
background-color: #abc; |
||||
border: solid 1px black; |
||||
text-align: center; |
||||
} |
||||
td { |
||||
background-color: #def; |
||||
border: solid 1px black; |
||||
} |
||||
|
||||
hr { |
||||
border-width: 0px 0px 0.1em 0px; |
||||
border-color: black; |
||||
} |
||||
|
||||
acronym, .titleTip { |
||||
border-bottom: 1px solid #ddd; |
||||
cursor: help; |
||||
margin: 0; |
||||
padding: 0 0 0.4px 0; |
||||
} |
||||
|
||||
pre { |
||||
margin-left: 2em; |
||||
font-size: 1.2em; |
||||
} |
||||
|
||||
blockquote { |
||||
border-left: 1px solid blue; |
||||
font-style: italic; |
||||
} |
||||
|
||||
.smallCaps { |
||||
font-size: 110%; |
||||
font-variant: small-caps; |
||||
} |
||||
|
||||
.doNotDisplay { display: none; } |
||||
|
||||
|
||||
.notify_errors, |
||||
.notify_notes, |
||||
.notify_success { padding: .8em; margin-bottom: 1em; border: 2px solid #ddd; } |
||||
|
||||
.notify_errors { background: #FBE3E4; color: #8a1f11; border-color: #FBC2C4; } |
||||
.notify_notes { background: #FFF6BF; color: #514721; border-color: #FFD324; } |
||||
.notify_success { background: #E6EFC2; color: #264409; border-color: #C6D880; } |
||||
.notify_errors a { color: #8a1f11; } |
||||
.notify_notes a { color: #514721; } |
||||
.notify_success a { color: #264409; } |
||||
|
||||
|
||||
/* # Page/Handler specific # */ |
||||
h1.dir-list-head, ul.dir-list { |
||||
text-transform: capitalize; |
||||
font-weight: bold; |
||||
} |
||||
ul.sitemap-list a { |
||||
text-transform: capitalize; |
||||
} |
@ -0,0 +1,6 @@ |
||||
const string url_root = "/~j3parker/"; |
||||
const string dweb_root = "/users/j3parker/www/"; |
||||
const string site_root = dweb_root ~ "srv/"; |
||||
|
||||
const string site_title = "Test Title"; |
||||
const string site_subtitle = "this is a subtitle"; |
@ -0,0 +1,186 @@ |
||||
//#!/usr/bin/rdmd
|
||||
import std.stdio; |
||||
import std.process; |
||||
import std.file; |
||||
import std.array; |
||||
import std.string; |
||||
import std.algorithm; |
||||
import config; |
||||
|
||||
string indent = ""; |
||||
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 root, string file, bool expand) { |
||||
bool isdir = dirExists(file); |
||||
html_push("<li>"); |
||||
html("<a href=\"" ~ construct_rel_link(root, file) ~ "\"" ~ |
||||
(expand? " class=\"thisPage\">» <i>" : ">› ") |
||||
~ last_in_path(file) ~ (isdir ? "/" : "") |
||||
~ (expand? "</i>" : "") ~ "</a>"); |
||||
html_pop("</li>"); |
||||
} |
||||
|
||||
void nav_tree_r(string root, string cur_loc, string[] subdirs) { |
||||
html_push("<ul>"); |
||||
foreach(string s; dir(cur_loc)) { |
||||
if (s[max(0,$-8)..$]=="index.md") continue; |
||||
bool hidden = last_in_path(s).length > 0 && last_in_path(s)[0] == '.'; |
||||
bool expand = s[cur_loc.length..$] == (subdirs.length == 0 ? "" : subdirs[0]); |
||||
if (hidden && !expand) continue; |
||||
write_link(root, s, expand); |
||||
if (expand && isDir(cur_loc ~ subdirs[0])) { |
||||
html_push("<li>"); |
||||
nav_tree_r(root, cur_loc ~ subdirs[0] ~ "/", subdirs[1..$]); |
||||
html_pop("</li>"); |
||||
} |
||||
} |
||||
html_pop("</ul>"); |
||||
} |
||||
|
||||
// this could be better
|
||||
string[] dir(string path) { |
||||
string[] files; |
||||
foreach(string s; dirEntries(path, SpanMode.shallow)) files ~= s; |
||||
sort(files); |
||||
return files; |
||||
} |
||||
|
||||
void do_nav_tree(string path) { |
||||
try { if (isDir(path) && path[path.length - 1] != '/') { path = site_root; } } |
||||
catch (Exception e) { path = site_root; } |
||||
|
||||
html_push("<div id=\"side-bar\">"); |
||||
|
||||
string root = get_root_dir(path); |
||||
string[] subdirs = explode_slashes(path[site_root.length..$]); |
||||
nav_tree_r(root, site_root, subdirs); |
||||
html_pop("</div>\n"); |
||||
} |
||||
|
||||
string last_in_path(string path) { |
||||
auto i = max(path.length,1) - 1; |
||||
while (i-- > 0) if (path[i] == '/') return path[min(i+1,$)..$]; |
||||
return path; |
||||
} |
||||
|
||||
string chomp_slashes(string path) { return chompPrefix(chomp(path, "/"), "/"); } |
||||
string[] explode_slashes(string path) { return split(chomp_slashes(path), "/"); } |
||||
|
||||
string get_root_dir(string path) { |
||||
if (path == "") return ""; |
||||
if (isDir(path)) return path[path.length - 1] == '/' ? path : path ~ "/"; |
||||
auto i = path.length - 1; |
||||
while (--i > 0) if (path[i] == '/') return path[0..i]; |
||||
return "/"; |
||||
} |
||||
|
||||
string construct_rel_link(string src, string dst) { |
||||
string rel = ""; |
||||
string[] srcs = explode_slashes(src); |
||||
string[] dsts = explode_slashes(dst); |
||||
ulong i = 0; |
||||
while(i < srcs.length && i < dsts.length && srcs[i] == dsts[i]) i++; |
||||
if (i == srcs.length && i == dsts.length) return "."; |
||||
foreach (ulong j; 0..(srcs.length - i)) rel ~= "../"; |
||||
foreach (string s; dsts[i..$]) rel ~= s ~ "/"; |
||||
return isDir(dst) ? rel : rel[0..$-1]; |
||||
} |
||||
|
||||
void not_found(string path) { |
||||
html("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=\"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"); |
||||
} |
||||
|
||||
void do_markdown(string file) { |
||||
// sanity check file first?!?!?
|
||||
html(shell("cat " ~ file ~ "|" ~ dweb_root ~ "bin/contrib/Markdown.pl")); |
||||
} |
||||
|
||||
bool fileExists(string path) { try { if (isFile(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 path) { |
||||
html_push("<div id=\"main-copy\">"); |
||||
string url = path[site_root.length..$]; |
||||
switch (url) { |
||||
case "changelog": |
||||
html(shell(dweb_root ~ "bin/changelog")); |
||||
break; |
||||
default: |
||||
try { |
||||
if (isDir(path) && fileExists(path ~ "index.md")) path ~= "index.md"; |
||||
if (fileExists(path)) do_markdown(path); |
||||
} catch (Exception e) { |
||||
not_found(path); |
||||
} |
||||
} |
||||
html_pop("</div>\n"); |
||||
} |
||||
|
||||
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"); |
||||
} |
||||
|
||||
void main(string[] args) { |
||||
html("Content-type: text/html\n"); |
||||
html("<!DOCTYPE html>"); |
||||
html_push("<html>\n"); |
||||
|
||||
string url = getenv("SCRIPT_URL")[url_root.length..$]; |
||||
string path = site_root ~ url; |
||||
|
||||
string pagename = last_in_path(url); |
||||
if (pagename.length != 0) pagename = " - " ~ pagename; |
||||
pagename = site_title ~ pagename; |
||||
|
||||
html_push("<head>"); |
||||
html("<title>" ~ pagename ~ "</title>"); |
||||
html("<link rel=\"stylesheet\" href=\"" ~ url_root ~ "pub/style/style.css\" type=\"text/css\" media=\"screen, handheld\" title=\"default\">"); |
||||
html("<link rel=\"shortcut\" href=\"" ~ url_root ~ "pub/favicon.ico\" type=\"image/vnd.microsoft.icon\">"); |
||||
html("<meta charset=\"UTF-8\">"); |
||||
html("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">"); |
||||
html_pop("</head>\n"); |
||||
|
||||
html_push("<body>"); |
||||
do_header(); |
||||
do_nav_tree(path); |
||||
do_content(path); |
||||
do_footer(); |
||||
html_pop("</body>\n"); |
||||
|
||||
html_pop("</html>"); |
||||
} |
@ -0,0 +1,53 @@ |
||||
dweb - A simple website written in D |
||||
===== |
||||
dweb is a simple website framework based off the [werc][werc] software. |
||||
|
||||
Its principles are: |
||||
|
||||
- Database free, uses files and directories instead. |
||||
- Written using the D programming language. |
||||
- Minimize tedious work: eg., no need to ever write HTML, use markdown instead. |
||||
- Very minimalist yet extensible codebase. Handlers for special things should be easy to add. |
||||
|
||||
It was created because werc was annoying to deploy on UW Computer Science Club's Apache setup and because [Not Invented Here](http://en.wikipedia.org/wiki/Not_Invented_Here). |
||||
|
||||
[werc]:http://werc.cat-v.org/ |
||||
[md]:http://daringfireball.net/projects/markdown |
||||
|
||||
Install Guide |
||||
------ |
||||
You will need: |
||||
- An HTTP server with CGI support. |
||||
- The D compiler. |
||||
|
||||
Extract the contents into the location you want to serve webpages from. Edit the following files: |
||||
|
||||
- <code>$DWEB_ROOT/.htaccess</code>: make the paths work for your setup. |
||||
- <code>$DWEB_ROOT/src/config.d</code>: change these strings as necessary. |
||||
- <code>$DWEB_ROOT/src/web.d</code>: this is the main web code. |
||||
- <code>$DWEB_ROOT/pub/</code>: static content goes here. |
||||
- <code>$DWEB_ROOT/srv/</code>: directories, markdown webpages etc. go in here. |
||||
- <code>$DWEB_ROOT/bin/</code>: custom handlers go here. |
||||
|
||||
Run <code>build</code> in <code>$DWEB_ROOT/src</code> to recompile the website software. |
||||
|
||||
Source |
||||
-------- |
||||
|
||||
You can get the source code on [github](https://github.com/j3parker/dweb) or by running |
||||
|
||||
git clone git://github.com/j3parker/Go-OpenGL.git |
||||
|
||||
Contact |
||||
-------- |
||||
For questions, suggestions, bug reports and contributing patches email [j3parker](mailto:j3parker@csclub.uwaterloo.ca) |
||||
|
||||
License |
||||
------- |
||||
Public domain. |
||||
|
||||
Credits |
||||
------- |
||||
The idea and css stolen from [werc][werc]. This page itself also plagarised. |
||||
|
||||
Thanks to John Gruber for the [Markdown.pl][md] script. |
Loading…
Reference in new issue