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 mailing list
Has...@haskell.org
http://www.haskell.org/mailman/listinfo/haskell
Excellent! Thanks for these.
-johnnnnnnn
_______________________________________________
Haskell-Cafe mailing list
Haskel...@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
before I start digging further into nginxs end of things, how exactly
is the path constructed, as used by the path consuming combinators? -
because any I use (including what I thought would always work: h |\\
\x -> output x) yield 404s (so it isnt just using the requestURL and
splitting by '/')...
sudo lighttpd -D -f lh.conf
[sudo] password for thartman:
2008-06-03 09:30:02: (log.c.75) server started
so that's okay, but
http://localhost:3000/hvac-board/board/1
in firefox attempted to open a binary file "1".
Same result for http://localhost:3000/hvac-board
I don't know if this is an hvac issue or a fastcgi issue (seems more
likely) but any
advice?
Thomas.
2008/3/22 Sterling Clover <s.cl...@gmail.com>:
> 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
> 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
Regards,
Sterl