Permalink
Browse files

Reorganize code and give haddock some love

  • Loading branch information...
1 parent d2457cc commit b2af34e264fa14b4367c32262a099f23ab3633ee @gregorycollins committed Aug 7, 2009
View
@@ -1,7 +1,6 @@
Name: Blaaargh
Version: 0.3
-Synopsis: A simple content-management system for Happstack,
- suitable for small-to-medium-sized websites
+Synopsis: A simple filesystem-based content management system for Happstack
License: GPL
License-file: COPYING
Author: Gregory Collins
@@ -16,14 +15,14 @@ Library
hs-source-dirs:
src
exposed-modules: Blaaargh
- , Blaaargh.Time
- , Blaaargh.Exception
- , Blaaargh.Util.ExcludeList
- , Blaaargh.Util.Templates
- , Blaaargh.Types
- , Blaaargh.Post
- , Blaaargh.Templates
- , Blaaargh.Handlers
+ other-modules: Blaaargh.Internal.Time
+ , Blaaargh.Internal.Exception
+ , Blaaargh.Internal.Util.ExcludeList
+ , Blaaargh.Internal.Util.Templates
+ , Blaaargh.Internal.Types
+ , Blaaargh.Internal.Post
+ , Blaaargh.Internal.Templates
+ , Blaaargh.Internal.Handlers
ghc-options: -Wall -funbox-strict-fields -O2 -fvia-C -optc-O3 -funfolding-use-threshold=16
View
@@ -1,9 +1,212 @@
+{-|
+
+\"Blaaargh\!\" is a simple filesystem-based content management system for static or
+semi-static publishing. You can run it standalone (...or will be able to soon)
+or integrate it as a component in a larger happstack application.
+
+Like the venerable blosxom (<http://blosxom.sourceforge.net/>) package,
+Blaaargh\! relies on plain-text files on the file system as its content
+database.
+
+FEATURES:
+
+* simple on-disk content database
+
+* posts\/pages written in markdown format
+
+* pages formatted into HTML by a flexible cascading template system based on
+ HStringTemplate (http://hackage.haskell.org/package/HStringTemplate). Page
+ templates can be overridden on a per-page or per-folder basis.
+
+* directories can be given indices using the templating system. Various views
+ of the directory contents (e.g. N most recent pages, pages in forward/reverse
+ chronological order, pages in alphabetical order) are exposed to the index
+ templates.
+
+* directories with defined indices get Atom-format syndication feeds
+
+* configuration parameters (site title, site URL, base URL, etc.) specified in
+ an INI-style config file
+
+
+MISSING FEATURES:
+
+* a web-accessible \"administrative area\"
+
+* a comment system (for my homepage I'm currently just outsourcing this to
+ Disqus)
+
+
+
+INSTRUCTIONS:
+
+The Blaaargh directory consists of the following contents:
+
+ [@config@] an INI-style configuration file
+
+ [@templates\/@] a tree of @.st@ template files, served by HStringTemplate
+
+ [@content\/@] a tree of content files. Markdown-formatted files (with
+ @.md@ extensions) are parsed and read as \"posts\" that
+ are rendered to HTML via the templating mechanism. Other
+ files are served as static content.
+
+
+Let's say you have some files in here:
+
+> config
+> content/grumble.md
+> content/index.md
+> content/posts/bar.md
+> content/posts/bar/photo.jpg
+> content/posts/foo.md
+> content/static/spatula.md
+> templates/404.st
+> templates/post.st
+> templates/static/index.st
+> templates/static/post.st
+> templates/static/spatula.st
+
+Think of it like this -- you request content, either a single post, a
+directory, or an atom feed (hardcoded as @\/[dir]\/feed.xml@). Blaaargh
+searches for the closest matching template.
+
+For @.md@ files (\"posts\" or \"pages\"), the templates /cascade/: e.g. for a
+file @content\/foo\/bar\/baz.md@, we would search @templates\/@ for the following
+templates, in order:
+
+* @foo\/bar\/baz.st@
+
+* @foo\/bar\/post.st@
+
+* @foo\/post.st@
+
+* @post.st@
+
+* @404.st@
+
+For directories, the templates don't cascade; a directory needs to have a
+matching template in order to be served. E.g. for a directory
+@\/foo\/bar\/quux@, we search @templates\/@ for \"@foo\/bar\/quux\/index.st@\",
+and if @content\/foo\/bar\/quux\/index.md@ exists, we read it into the template
+as content text. (More about this in \"TEMPLATING\" below.)
+
+
+CONFIGURATION
+
+A Blaaargh\! @config@ file looks like this:
+
+> [default]
+> # what's the domain name?
+> siteurl = http://example.com
+>
+> # blaaargh content will be served at this base URL
+> baseurl = /foo
+>
+> [feed]
+> # site title
+> title = Example dot com
+> # authors
+> authors = John Smith <john@example.com>
+> # Atom icon
+> icon = /static/icon.png
+>
+> # posts on this list (or directories containing posts) won't be included in
+> # directory indices, nor in atom feeds
+> skipurls = static
+
+Blaaargh\! uses the ConfigFile library for configuration and post header
+parsing. (<http://hackage.haskell.org/package/ConfigFile>)
+
+
+POST FORMATTING
+
+Posts are (mostly) in Markdown format, with the exception of a key-value header
+prefixed by pipe (@\|@) characters. Example:
+
+> | title: Example post
+> | author: John Smith <john@example.com>
+> | published: 2009-09-15T21:18:00-0400
+> | summary: A short summary of the post contents
+>
+> This is an example post in *markdown* format.
+>
+
+Blaaargh\! accepts the following key-values for posts:
+
+ [@title@] The title of the post
+
+ [@author@] The post's author
+
+ [@authors@] same as @author@
+
+ [@summary@] a summary of the post
+
+ [@updated@] the post's last update time in RFC3339 format
+
+ [@published@] the post's publish date in RFC3339 format
+
+The headers are parsed as follows: any lines starting with the @\|@ character
+(up until the first line not starting with @\|@) have the prefix stripped and
+are sent through ConfigFile.
+
+Please see its haddock for input syntax.
+
+
+DATA MODEL
+
+The documents get indexed into a key-value mapping by id. (Where an \"id\" for
+a post is defined as its relative path from @content\/@, with the @.md@ suffix
+removed.)
+
+Files with an @\'.md\'@ suffix are treated as \"posts\"\/\"pages\", and are
+expected to be in markdown format. Files with other suffices are served as
+static files.
+
+
+TEMPLATING
+
+Blaaargh\! uses templates to present the content of posts and lists of posts in
+HTML.
+
+For an individual post (either postname-specific @/postname/.st@ or generic
+@post.st@), Blaaargh exports a template variable called @$post$@ which is a map
+containing the following attributes:
+
+@
+ $id$
+ $date$
+ $url$
+ $title$
+ $content$
+ $summary$
+ $authors$
+@
+
+So in other words, within your template the post's URL can be accessed using
+@$post.id$@.
+
+For directory templates (@index.st@), we collect the posts within that
+directory and present them to the templating system as a list of post objects
+(i.e. containing the @$id$@\/@$date$@\/etc. fields listed above):
+
+@
+ $alphabeticalPosts$
+ $recentPosts$ -- N.B. 5 most recent posts
+ $chronologicalPosts$
+ $reverseChronologicalPosts$
+@
+
+-}
+
+
module Blaaargh
( initBlaaargh
, serveBlaaargh
, runBlaaarghHandler
, addExtraTemplateArguments
, BlaaarghException
+ , blaaarghExceptionMsg
, BlaaarghMonad
, BlaaarghHandler
, BlaaarghState
@@ -24,16 +227,25 @@ import qualified Text.Atom.Feed as Atom
import Text.Printf
------------------------------------------------------------------------------
-import Blaaargh.Handlers
-import Blaaargh.Post
-import Blaaargh.Types
-import qualified Blaaargh.Util.ExcludeList as EL
-import Blaaargh.Util.ExcludeList (ExcludeList)
-import Blaaargh.Util.Templates
+import Blaaargh.Internal.Handlers
+import Blaaargh.Internal.Post
+import Blaaargh.Internal.Types
+import qualified Blaaargh.Internal.Util.ExcludeList as EL
+import Blaaargh.Internal.Util.ExcludeList (ExcludeList)
+import Blaaargh.Internal.Util.Templates
------------------------------------------------------------------------------
-initBlaaargh :: FilePath -> IO BlaaarghState
+{-|
+
+ Initialize a Blaaargh instance. Given the name of a directory on the disk,
+ 'initBlaaargh' searches it for configuration, content, and template files,
+ and produces a finished 'BlaaarghState' value. Throws a 'BlaaarghException'
+ if there was an error reading the state.
+
+-}
+initBlaaargh :: FilePath -- ^ path to blaaargh directory
+ -> IO BlaaarghState
initBlaaargh path = do
-- make sure directories exist
mapM_ failIfNotDir [path, contentDir, templateDir]
@@ -71,6 +283,8 @@ initBlaaargh path = do
templateDir = path </> "templates"
+------------------------------------------------------------------------------
+
getM :: Cfg.Get_C a => Cfg.ConfigParser -> String -> String -> Maybe a
getM cp section = either (const Nothing) Just . Cfg.get cp section
@@ -122,5 +336,3 @@ readConfig fp = do
parseConfig :: FilePath -> IO (Either Cfg.CPError Cfg.ConfigParser)
parseConfig = Cfg.readfile Cfg.emptyCP
-
-
View
@@ -1,14 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable #-}
-
-module Blaaargh.Exception where
-
-import Control.Exception
-import Data.Typeable
-import Prelude hiding (catch)
-
-
-
-data BlaaarghException = BlaaarghException String
- deriving (Show, Typeable)
-
-instance Exception BlaaarghException
@@ -0,0 +1,23 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+
+module Blaaargh.Internal.Exception
+( BlaaarghException(..)
+, blaaarghExceptionMsg )
+where
+
+import Control.Exception
+import Data.Typeable
+import Prelude hiding (catch)
+
+
+-- | 'BlaaarghException' is the exception type thrown when Blaaargh encounters
+-- an error.
+data BlaaarghException = BlaaarghException String
+ deriving (Show, Typeable)
+
+instance Exception BlaaarghException
+
+
+-- | Obtain the error message from a 'BlaaarghException'
+blaaarghExceptionMsg :: BlaaarghException -> String
+blaaarghExceptionMsg (BlaaarghException s) = s
Oops, something went wrong.

0 comments on commit b2af34e

Please sign in to comment.