1) hvac 0.1b: transactional, declarative framework for lightweight
web
applications.
2) HStringTemplate 0.3
1) hvac 0.1b
hvac (short for http view and controller) has been my project for
the last
little while, and is finally in a fairly usable state, so I'm
opening up the
repo (darcs get http://community.haskell.org/~sclv/hvac/) for
folks to play
with and to get some feedback. While not quite yet ready for
hackage, the
package as provided should be fully cabal installable.
Documentation is
available at http://community.haskell.org/~sclv/hvac/html_docs/hvac/
The aim of hvac is to provide an environment that makes the
creation of
lightweight fastcgi based web applications as simple as possible,
with an
emphasis on concise, declarative style code, correct concurrent
transactional logic, and transparency in adding caching combinators.
There are two included example programs, naturally neither of
which is
feature complete. They share a common login module of about 50
lines of
code, excluding imports, templates, and database schema.
The first program is a classic, greenspun-style message board with
basic
login functionality. It totals roughly 40 lines and tends to use
just under
4mb of resident memory on my system.
The second is a wiki based on Pandoc and the PandocWiki code. The
code
totals roughly 30 lines (rendering borrowed from PandocWiki aside)
and uses
about 5mb of memory.
hvac processes all requests in the STM monad, with some bells
attached to
properly interleave STM with session, database and filesystem
operations
such that they all conceptually occur together in a single
transaction per
request. Currently it is only fully tested with sqlite, but it should
operate, modulo a few tweaks, with any database accessible via HDBC.
hvac is particularly designed to use the HStringTemplate library
as an
output layer, in a simple declarative fashion. As the
StringTemplate grammar
is explicitly sub-turing, this ensures a clean separation of
program logic
from presentation, while providing a nonetheless fairly powerful
language to
express typical display tasks.
The included cache combinators, still experimental, should allow a
simple
and fine-grained control over the level of caching of various disk-
bound
operations. Phantom types are used to ensure that no functions
that modify
state may be cached.
To give a flavor of hvac code, the following is the complete
(twenty lines!)
source of the wiki controller (due to sql statements, some lines
are rather
long):
wikiController tmpl =
h |/ "login" *> login_plug tmpl
<|>
(h |/ "wiki" |\\ \pageName -> h |// "POST" *>
withValidation [ ("contents", return) ]
(\ [contents] -> do
pageId <- selectVal "id from pages where name=?" [toSql
pageName]
maybe (addErrors [("Login","must be logged in.")] >>
continue)
(\user -> case fromSql pageId of
Just (_::Int) ->
execStat "insert into
page_hist(pageId,contents,author) values(?,?,?)" [pageId, toSql
contents,
toSql . userName $ user]
Nothing -> do
execStat "insert into pages(name,locked)
values(?,?)" [toSql pageName, toSql (0::Int)]
pid <- selectVal "max(id) from pages" []
execStat "insert into
page_hist(pageId,contents,author) values(?,?,?)" [pid, toSql
contents, toSql
. userName $ user]) =<< getSes
continue)
<|> do
pageId <- selectVal "id from pages where name=?" [toSql
pageName]
(join $ renderf (tmpl "showPage") ("pageName", pageName)
<$> "pageContents" |= selectRow "* from page_hist where
pageId=? order by time desc limit 1" [pageId] ))
<|> (redirect . ( ++ "/wiki/Index") =<< scriptName)
Future directions for work on hvac include: Stress testing for
correctness
of transactional logic and benchmarks. Exploration of various
efficiency
tweaks. Unit tests. Further development of the cache combinator API.
Improvement of the example apps and addition of a few others (a
blog maybe).
Expansion of the library of validator functions. Exploration of
transferring
hvac to the standard FastCGI bindings (currently it uses a custom
modified
version to work properly with STM). Improvement of the database
layer,
particularly with regards to common paging functions. Creation of
a set of
simple combinators for generating CRUD (create read update delete)
pages.
Creation of a minimal set of standard templates (maybe).
2) HStringTemplate 0.3.1
This release of HStringTemplate (up now at Hackage) fixes a number
of bugs
pointed out to me by its small but growing user base (thanks, cinema,
elliottt!) ranging from the minor (a particular two-level
iteration pattern
wasn't working properly) to the truly irritating (poor handling of
file
groups). It's still unfortunately skimpy on the docs, outside of the
haddocks and the main StringTemplate grammar documentation at
http://www.stringtemplate.org (although the examples from hvac
should also
prove helpful). However, it does have a set of very nice and handy
new
features for development.
* renderf, a function similar in spirit to printf, that takes an
arbitrary
number of heterogeneous (String, value) tuples as arguments. This
should cut
down considerably on long setAttribute chains. Additionally, with
custom
instances (not, I'll grant, trivial to write) it can be used to
declaratively chain together strings of attribute retrieval
functions in
arbitrary monads, as in the above code example from hvac.
* dumpAttribs, a function/template that prints out the tree of the
entire
attribute environment a template is operating in -- extremely
handy for
development.
* nullGroup, also for use in development, a simple way to display
more
information about templates that can't be found. Error messages in
usafeVolatileDirectoryGroup have also been significantly improved.
* getStringTemplate', a version of getStringTemplate guaranteed
not to be
inlined. While the optimizer will still sometimes rearrange code
such that a
volatile group is not updated properly, this at least helps remedy
the
situation (I think).
* Some minor changes: For grammar reasons, dots have been removed
from
template names -- however, underscores and slashes are now available.
Additionally, there's a much improved logic for which aspects of a
local
environment are overridden and preserved when a template is called
from
another.
For both of these libraries, patches, comments, bug reports,
requests, and
of course contributions more than welcome!
Regards,
Sterl._______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe