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!
About hvac (hope this is the right place for support questions) - I'm trying to get it working with lighttpd's spawn-fcgi but using nginx as the web server... the problem seems to be getting the information about the path. The most rudimentary investigation has led me to see that requestURL is the proper url (debug printing using logHVAC), but pathInfo returns an empty string. I know the comments say that pathInfo is only used for a workaround with lighttpd, but I was wondering if that shows where the problem may lie...
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 '/')...
> 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!
Probably best not to keep this discussion in -cafe after this, as this is more of a debugging-type issue, but in my experience, I bet the lighttpd server is trying to serve the hvac-board fcgi file directly as a binary, rather than launching it as a fastcgi instance at all. The configurations files I've built have worked fine for me, but your milage may vary -- getting fastcgi up and running can be a bit of a bear at times. At a minimum, you should make sure that the lh.conf file points correctly to your binary in the fastcgi.server variable, and that you have all the proper fastcgi libraries installed on your system.
>> 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!