Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
169 lines (131 sloc) 6.68 KB
todo:
- cache: frontpage, 404 page, 500 page don't have cache entry
* server and client side form validation
- session should stay open on multiple tabs and when window is
closed
- make experimental branch of to check perf on file-only db.
* write more tests
- template inheritance
* build backend interface: add/rm folders/pages, edit content
- catch SIG's for safe shutdown
* do a fsck on *.tmp, *.bak files and repair writes that didn't finish
* make a test from mem->db db<-mem over the filesystem in addition to http
stack:
the root node doesn't have a contents file hmm... if i add it, make sure
mem->disk-walk checks for it
when there's no on disk file for a node, a warning is sent to the user,
but we doesn't have to deal with it immediately. be prepared for doom ;)
no lookstep yet on enlive transformations.
templates configurable per item and template inheritance.
virtualhost support
for testing: launch separate test db w/ diff test data
gzip
cleanup the passing around of url lists / converting to str/path etc
# technical design of whabbit
## The Database
the pages are orgnized into a tree structure, similar to a file system
with folders and files. this folder structure dictates the hierarchy while
navigating the website. to minimize disc access, there is a in memory
representation of the tree structure. when you click on a page, this tree
gets searched in memory, to see if the page exists (when not, a 404 get's
returned). then the item get's read from disc. in this file there are
(sofar) two fields: content and comments. content is a string of what
get's rendered in the template (can be html) and comments is a vector
of comments that appears on the page. further information about the
post (author, date created, tags, etc) is stored in the in-memory
tree.
here's a specification of the database format:
a folder is a map with these keys and values:
:folder "display name"
:id "click-me"
:author "user_name" ; optional
:date-create 1298209094 ; optional
:date-mod 1298210074 ; optional
:no-comments true ; optional
:template "html/p.html" ; optional
:css "span#about" ; optional
:items ()
the value of :folder is what's get showed to the user, when he see's
it. the value of :id is used to represent the item in a URL. the
user see's this at the end in the address bar. the value of :items is
a list of either folders, pages or it can be empty. :date-create is a
timestamp when the post was initially created. :date-mod is the date
of the latest edit. when :no-comments
is set to true, then commenting is diabled for this item. if a different
template should be used, than the default defined in config, then the
:template keyword can be set. the html file is searched for in the "src"
directory.
the value of :css denotes a CSS selector. the item will not appear in
the main navigation menu, but instead be put into the container of the
CSS selector. this allows arbitrary placement of links on the website.
a page is a map with the same keys as a folder, except the key :page
is used instead of the key :folder and pages can not have subitems
like folders, so the key :items doesn't apply.
the actual content of pages and folders is stored on disc. it
searches in a folder specificied in the config.clj file (default:
pages). from there each "folder" in the tree is taken as a folder in
the filesystem. when a folder is requested (not a page), a special
file ".folder" inside the folder represents it. so when folder's are
clicked on, content and comments can appear.
a folder or page on disc is a map with these keys and values:
:content "First post!"
:file-mod 1298210074 ; optional
:comments [{:name "ulises" :date 1298158700626" ; optional
:comment "Hello world."}]
the value of :content is what get's displayed to the user (can be
html). the value of :comments is a vector of comment maps (only a safe
subset of html / or plain text for now).
:file-mod is the last time the file was modified
on disc (either via a new comment or content change).
the in memory tree starts off with a root folder that has a key
:version. this can be used to upgrade old formats. inside "root" there
are two folders: pages and users. "pages" is where the content of the
website is stored with futher folders and pages. users contains all
the users with a login.
a user is a map of these keys and values:
:id "user_name"
:name "John Doe"
:password "$2a$10$xyz...abc"
:roles ["admin" "guest" "author" "moderator"]
the value of :id is the login user name. the value of :name is the
specified display name of the user. the value of :password is a hashed
password using bcrypt. the value of :roles is a vector of
roles. "admin" means he can change anything on the site. "guest" is
for user's who can post comments. "author" is for people who can
submit and edit pages. "moderator" is for people who can moderate
comments. even an "admin" needs to be an "author" in order to edit
pages.
## tree traversal:
there will be one main function that traverses the tree on each page load
(or cache fill). it returns a vector of three things:
1) the node of the given url, or nil if not found.
2) a string of html that represents the navigation menu. here folders are
opened up to the current view.
3) a map of css selectors to nodes. while traversing, any node that has a
CSS tag will not appear in the main navigation menu, but selected out
and put into this map. enlive will put these nodes in their appropiate
place according to the CSS selector. this allows arbitrary menu
structures and links put on the website.
in addition if the user wants the item both in the main menu and in
custom place, an attribute eg: "show-in-main-menu" can be set.
it's important to understand that custom CSS positioning only happens
"when you're in the folder". we don't traverse the whole tree to find
css selectors, only on the current folder that's being viewed. global
selectors can still be done by simply placing them under the root
directory (since everything here get's displayed anyways).
expanded thoughts:
what if you want to place documents on arbitrary position?
one way... simply let enlive do that :)
what if a certain page has a different template?
ditto!
is it intuitive to build multi layer navigation menus like this?
...
caching for 404 pages with abitrary urls.
there should be an option to show the entire tree, regardless of location!
## graphical design:
Reference Layout:
http://web.archive.org/web/20010925020630/http://www.sicnarf.com/
the start page should look like this, how i once had it way back in
2001.
## configuration:
will be in a clojure map structure stored on disk and read in.
Jump to Line
Something went wrong with that request. Please try again.