Havard's Crappy Blog
I whipped up a quick bloggish app in php, but decided to port it over to AOLserver for good measure. It's not very complete, has little to no sanity checking, was written in a little under an hour without any thought or planning, and is barely useful, but it does work.
First thing's first, you'll need to create a pool for your PostgreSQL database. Let's assume for this project the name of the pool is pool1.
schema.pgsql
CREATE DOMAIN AUTHOR_ID AS VARCHAR(16) NOT NULL;
CREATE DOMAIN EMAIL AS VARCHAR(128) NOT NULL;
CREATE DOMAIN SLUG AS VARCHAR(32) NOT NULL;
CREATE TABLE AUTHOR (
ID AUTHOR_ID PRIMARY KEY,
PERSONAL_NAME VARCHAR(64) NOT NULL,
DISPLAY_EMAIL EMAIL,
REAL_EMAIL EMAIL,
PASSWORD VARCHAR(64) NOT NULL
);
CREATE TABLE ARTICLE (
SLUG SLUG NOT NULL,
PUBDATE DATE NOT NULL,
UPDATED TIMESTAMP NOT NULL,
AUTHOR AUTHOR_ID REFERENCES AUTHOR(ID) NOT NULL,
LEAD TEXT NOT NULL,
BODY TEXT NOT NULL,
TITLE VARCHAR(128) NOT NULL,
PRIMARY KEY (SLUG, PUBDATE)
);
init.tcl
proc do_article {} {
set mainStuff ""
# /article/YYYY/MM/DD/slug/junk
set urlv [ns_conn urlv]
set qslug [lindex $urlv 4]
set qpubdate [lindex $urlv 1]-[lindex $urlv 2]-[lindex $urlv 3]
set qry "SELECT ARTICLE.*,AUTHOR.PERSONAL_NAME FROM ARTICLE,AUTHOR WHERE AUTHOR.ID=ARTICLE.AUTHOR AND PUBDATE = '${qpubdate}' AND SLUG = '${qslug}'"
catch {
set hdl [ns_db gethandle pool1]
set res [ns_db 1row $hdl $qry]
#[ns_db getrow $hdl $res]
set slug [subst [ns_set get $res slug ]]
set pubdate [subst [ns_set get $res pubdate]]
set updated [subst [ns_set get $res updated]]
set author [subst [ns_set get $res author ]]
set title [subst [ns_set get $res title ]]
set lead [subst [ns_set get $res lead ]]
set body [subst [ns_set get $res body ]]
ns_db releasehandle $hdl
}
if { [string compare $slug $qslug] == 0 } {
set mainStuff [ns_adp_parse -file template/article.adp]
set rPole [ns_adp_parse -file template/rpole.adp]
ns_return 200 "text/html" [ns_adp_parse -file template/template.adp]
} else {
ns_returnfile 404 "text/html" "global/file-not-found.html"
}
}
ns_register_proc GET /article do_article
ns_log warning "We processed init.tcl!"
index.adp
<% set mainStuff "" set qry "SELECT ARTICLE.*,AUTHOR.PERSONAL_NAME FROM ARTICLE,AUTHOR WHERE AUTHOR.ID=ARTICLE.AUTHOR ORDER BY PUBDATE DESC, UPDATED DESC LIMIT 10" catch { set hdl [ns_db gethandle pool1] set res [ns_db select $hdl $qry] while {[ns_db getrow $hdl $res]} { set slug [subst [ns_set get $res slug ]] set pubdate [subst [ns_set get $res pubdate]] set updated [subst [ns_set get $res updated]] set author [subst [ns_set get $res author ]] set title [subst [ns_set get $res title ]] set lead [subst [ns_set get $res lead ]] set body [subst [ns_set get $res body ]] set pubdate [string map {- /} $pubdate] set mainStuff "$mainStuff [ns_adp_parse -file template/entry.adp]" } } ns_adp_puts [ns_adp_parse -file template/template.adp] %>
/admin/post.adp
<html>
<head>
<title>Post an article</title>
</head>
<body>
<table>
<form method="POST" action="do_post.adp">
Title
<input name="title" size="80" value=""/>
username
<input name="username" value=""/>
password
<input type="password" name="password" value=""/>
date (YYYY/MM/DD)
<input name="date" value=""/>
slug
<input name="slug" value=""/>
lead
<textarea name="lead" cols="80" rows="5"></textarea>
body
<textarea name="body" cols="80" rows="12"></textarea>
<input type="submit">
<input type="reset">
</form>
</body>
</html>
/admin/do_post.adp
<%
set title [ns_dbquotevalue [ns_queryget title]]
set user [ns_dbquotevalue [ns_queryget username]]
set pass [ns_dbquotevalue [ns_queryget password]]
set date [ns_dbquotevalue [ns_queryget date]]
set slug [ns_dbquotevalue [ns_queryget slug]]
set lead [ns_dbquotevalue [ns_queryget lead]]
set body [ns_dbquotevalue [ns_queryget body]]
set qry "INSERT INTO ARTICLE VALUES ($slug, $date, now(), (SELECT ID FROM AUTHOR WHERE ID = $user and PASSWORD = $pass), $lead, $body, $title)"
set hdl [ns_db gethandle pool1]
if {[catch {ns_db dml $hdl $qry} res]} {
ns_adp_puts "post probably failed, hit back and try again"
ns_adp_puts "$res"
} else {
ns_adp_puts "post was a success!"
ns_adp_puts "$res"
}
%>
notes
You'll need a template directory off your pageroot. The files entry.adp and article.adp are virtually the same except that entry.adp is used for the home page listing, while article.adp is used for the full article page. You'll generally want to use the lead in entry.adp and body in article.adp. The main template is template.adp. The main content section is filled with the mainStuff variable.
Your links to articles will be in the form of /article/YYYY/MM/DD/slug/whatever.html. If you'll notice, pubdate has dashes substituted for slashes. This makes forming the URL nice and easy. What I use to form the Read More link is:
<a href="/article/<%= $pubdate %>/<%= $slug %>/article.html">Read More</a>