diff --git a/.DS_Store b/.DS_Store
new file mode 100644
Binary files /dev/null and b/.DS_Store differ
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Tupil nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/regular-web.cabal b/regular-web.cabal
new file mode 100644
--- /dev/null
+++ b/regular-web.cabal
@@ -0,0 +1,78 @@
+Name:            regular-web
+Version:         0.1
+Synopsis:        Generic programming for the web
+License:         BSD3
+License-file:    LICENSE
+Category:        Generics, Web
+Copyright:       (c) Chris Eidhof
+Author:          Chris Eidhof
+Maintainer:      Chris Eidhof <chris+hackage@eidhof.nl>
+Homepage:        http://github.com/chriseidhof/basil
+Exposed-Modules:   Generics.Regular.Formlets
+                 , Generics.Regular.Views
+                 , Generics.Regular.JSON
+Other-Modules:   Generics.Regular.Extras
+Build-Type:      Simple
+hs-source-dirs:  src
+Build-Depends:   base >= 4 && < 5, 
+                 mtl,
+                 xhtml,
+                 formlets == 0.6.1,
+                 applicative-extras,
+                 regular >= 0.1.0.2,
+                 fclabels >= 0.4.2,
+                 json >= 0.4.3
+
+Description: 
+  This package implements generic functions for web programming.
+  Based on the @regular@ library [1], we provide generic functions for generating @HTML@, @Formlets@, and @JSON@.
+  For a larger example, see the @Example.lhs@ [2] file on github.
+  .
+    1. <http://hackage.haskell.org/package/regular>
+  .
+    2. <http://github.com/chriseidhof/regular-web/blob/master/Example.lhs>
+  .
+  /Example/
+  .
+  Consider the following datatypes:
+  .
+  > data Person = Person {
+  >     _name   :: String
+  >   , _age    :: Int
+  >   , _isMale :: Bool
+  >   , _place  :: Place
+  >   }
+  
+  > data Place = Place {
+  >     _city      :: String
+  >   , _country   :: String
+  >   , _continent :: String
+  > }
+  .
+  We can now derive a @Regular@ instance for the @Person@ datatype using Template
+  Haskell:
+  .
+  > $(deriveAll ''Place  "PFPlace")
+  > $(deriveAll ''Person "PFPerson")
+  .
+  >
+  > type instance PF Place  = PFPlace
+  > type instance PF Person = PFPerson
+  .
+  We can construct an example person:
+  .
+  > location :: Place
+  > location = Place "Utrecht" "The Netherlands" "Europe"
+  > chris    :: Person
+  > chris    = Person "chris" 25 True location
+  .
+  > And, as an example, we can generate |HTML| and |JSON| values:
+  .
+  > locationHtml :: X.Html
+  > locationHtml = ghtml location
+  .
+  > personHtml :: X.Html
+  > personHtml = ghtml chris
+  .
+  > locationJSON :: JSValue
+  > locationJSON = gto location
diff --git a/src/.DS_Store b/src/.DS_Store
new file mode 100644
Binary files /dev/null and b/src/.DS_Store differ
diff --git a/src/Generics/.DS_Store b/src/Generics/.DS_Store
new file mode 100644
Binary files /dev/null and b/src/Generics/.DS_Store differ
diff --git a/src/Generics/Regular/Extras.hs b/src/Generics/Regular/Extras.hs
new file mode 100644
--- /dev/null
+++ b/src/Generics/Regular/Extras.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE KindSignatures #-}
+module Generics.Regular.Extras where
+
+import Generics.Regular
+import Data.Char (isAlpha, toUpper)
+
+prodFst :: (:*:) l r t1 -> l t1
+prodSnd :: (:*:) l r t1 -> r t1
+prodFst (x :*: _) = x
+prodSnd (_ :*: y) = y
+
+-- | Capitalizes the first letter and filters out all the non-alpha characters.
+humanReadable :: String -> String
+humanReadable = filter isAlpha . capitalize
+
+-- | Capitalize the first letter of the string.
+capitalize :: String -> String
+capitalize "" = ""
+capitalize (c:cs) = toUpper c : cs
+
+-- | Generates a human-readable version of a selector.
+h :: Selector s => t s (f :: * -> *) r -> String	
+h = humanReadable . selName
diff --git a/src/Generics/Regular/Formlets.hs b/src/Generics/Regular/Formlets.hs
new file mode 100644
--- /dev/null
+++ b/src/Generics/Regular/Formlets.hs
@@ -0,0 +1,153 @@
+{-# LANGUAGE FlexibleContexts, FlexibleInstances, TypeOperators, TypeSynonymInstances #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Generics.Regular.Formlets
+-- Copyright   :  (c) 2010 Chris Eidhof
+-- License     :  BSD3
+--
+-- Maintainer  :  chris@eidhof.nl
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+-- Generic generation of formlets <http://hackage.haskell.org/package/formlets>. 
+-- These functions are only defined for record datatypes that contain
+-- a single constructor.
+--
+-- Consider the datatype @Person@:
+--  
+-- > data Person = Person {
+-- >    _name   :: String
+-- >  , _age    :: Int
+-- >  , _isMale :: Bool
+-- > } deriving (Show, Eq)
+--
+-- We prefix all our fields with an underscore (@_@), so that our datatype will play nice with @fclabels@. 
+-- 
+-- > $(deriveAll ''Person "PFPerson")
+-- 
+-- > type instance PF Person = PFPerson
+-- 
+-- We can construct an example person:
+-- 
+-- > chris    :: Person
+-- > chris    = Person "chris" 25 True
+-- 
+-- > personForm :: XFormlet Identity Person
+-- > personForm = gformlet
+-- 
+-- We can print @formHtml@ to get the @Html@ of the form with the @chris@ value
+-- already filled in:
+-- 
+-- > formHtml :: X.Html
+-- > (_, Identity formHtml, _) = F.runFormState [] (personForm (Just chris))
+-----------------------------------------------------------------------------
+module Generics.Regular.Formlets (
+  -- * Generic forms
+  gform,
+  gformlet,
+  GFormlet,
+  XForm,
+  XFormlet,
+  -- * Generic forms with fclabels
+  projectedForm,
+  -- * Default Formlet typeclass
+  Formlet (..),
+  -- * Extra form types
+  -- | Currently, this section is very limited. We expect to add more types in the future, suggestions are welcome.
+  YesNo (..),
+  boolToYesNo
+  ) where
+
+import Control.Applicative
+import Control.Monad.Identity
+import Text.XHtml.Strict ((+++), (<<))
+import qualified Text.XHtml.Strict as X
+import qualified Text.XHtml.Strict.Formlets as F
+import Generics.Regular
+import Generics.Regular.Extras
+import Data.Record.Label
+
+
+gform :: (Regular a, GFormlet (PF a), Functor m, Applicative m, Monad m) => Maybe a -> XForm m a
+gform x = to <$> (gformf gformlet (from <$> x))
+
+gformlet :: (Regular a, GFormlet (PF a), Functor m, Applicative m, Monad m) => XFormlet m a
+gformlet x = to <$> (gformf gformlet (from <$> x))
+
+-- |
+-- Generic forms almost never match the real world. If you want to change a generic form, you can either implement it from scratch, or use the 'projectedForm' function.
+-- 
+-- As an example, we will to remove the 'age' field from the form, and change the '_isMale' field to a Yes\/No choice instead of a True\/False choice. The datatype 'YesNo' is defined in this module.
+-- 
+-- > data PersonView = PersonView {
+-- >    __name   :: String
+-- >  , __isMale :: YesNo
+-- > }
+-- 
+-- 
+-- > $(deriveAll ''PersonView "PFPersonView")
+-- > type instance PF PersonView = PFPersonView
+-- 
+-- We can now use @fclabels@ to convert back and forth between @Person@ and
+-- @PersonView@. First, we use Template Haskell to generate some accessor functions:
+-- 
+-- > $(mkLabels [''Person])
+-- 
+-- This is the bidirectional function between @Person@ and @PersonView@. How to write such a function is explained in the well-documented @fclabels@ package at <http://hackage.haskell.org/package/fclabels>.
+-- 
+-- > toView :: Person :-> PersonView
+-- > toView = Label (PersonView <$> __name `for` name <*> __isMale `for` (boolToYesNo `iso` isMale))
+-- 
+-- Now that we have a function with type @Person :-> PersonView@, we can render a
+-- form for @personView@ and update the original person. Note that the argument is
+-- not a @Maybe@ value, in contrast with the @gformlet@ function.
+-- 
+-- > personForm' :: Person -> XForm Identity Person
+-- > personForm' = projectedForm toView
+-- 
+-- > formHtml' :: X.Html
+-- > (_, Identity formHtml', _) = F.runFormState [] (personForm' chris)
+
+projectedForm :: (Regular a, GFormlet (PF a), Applicative m, Monad m) 
+              => (b :-> a) -> b -> XForm m b
+projectedForm toView x = (flip (set toView) x) <$> (gform (get toView <$> (Just x)))
+
+type XForm m a = F.XHtmlForm m a
+type XFormlet m a = F.XHtmlFormlet m a
+
+class    Formlet a      where  formlet :: (Functor m, Applicative m, Monad m) => XFormlet m a
+
+instance Formlet Bool   where  formlet   = F.enumSelect []
+instance Formlet Int    where  formlet x = fromIntegral <$> F.inputInteger (toInteger <$> x)
+instance Formlet String where  formlet   = F.input
+
+class GFormlet f where
+  gformf :: (Functor m, Applicative m, Monad m) => XFormlet m a -> XFormlet m (f a)
+
+instance (Constructor c, GFormlet f) => GFormlet (C c f) where
+  gformf f x = C <$> (gformf f $ unC <$> x)
+
+instance Formlet a => GFormlet (K a) where
+  gformf _ x = K <$> (formlet (unK <$> x))
+
+instance (GFormlet (S s f), GFormlet g) => GFormlet ((S s f) :*: g) where
+  gformf f x = (:*:) <$> (gformf f (prodFst <$> x)) <* F.xml X.br <*> (gformf f (prodSnd <$> x))
+
+ 
+instance (Selector s, GFormlet f) => GFormlet (S s f) where
+  gformf f x = F.plug ((X.label << (h (fromJust x) ++ ": ")) +++) $ S <$> gformf f (unS <$> x)
+   where fromJust (Just y) = y
+         fromJust _        = error "Generic formlets fromJust should not be computed."
+
+-- | This datatype is used to display 'Bool' values as @Yes@ or @No@.
+data YesNo = Yes | No 
+  deriving (Eq, Show, Bounded, Enum)
+instance Formlet YesNo where formlet = F.enumSelect []
+
+-- | This is an @fclabels@ function that converts between 'Bool' and 'YesNo' values.
+boolToYesNo :: Bool :<->: YesNo
+boolToYesNo = to <-> from
+ where  from Yes = True
+        from No  = False
+        to x  = if x then Yes else No
diff --git a/src/Generics/Regular/JSON.hs b/src/Generics/Regular/JSON.hs
new file mode 100644
--- /dev/null
+++ b/src/Generics/Regular/JSON.hs
@@ -0,0 +1,73 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Generics.Regular.Views
+-- Copyright   :  (c) 2010 Chris Eidhof
+-- License     :  BSD3
+--
+-- Maintainer  :  chris@eidhof.nl
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+-- Generic generation of 'JSON' values. Note that the generic
+-- functions are only defined for record datatypes that contain
+-- a single constructor.
+--
+-- The code that is generated by 'gto' should be parseable by 'gfrom'.
+-----------------------------------------------------------------------------
+module Generics.Regular.JSON (gfrom, gto, GJSON) where
+
+import Text.JSON
+import Generics.Regular
+import Generics.Regular.Extras
+import Control.Applicative
+import Data.List (unionBy)
+
+-- | The function 'gfrom' tries to parse a 'JSValue'. The 'Result' datatype is used for error-messages if parsing fails.
+gfrom :: (Regular a, GJSON (PF a)) => JSValue -> Result a
+gfrom = fmap to . gfrom'
+
+-- | The function 'gto' generates a 'JSValue' for all types that are an instance of 'GJSON'.
+gto :: (Regular a, GJSON (PF a)) => a -> JSValue
+gto = gto' . from
+
+-- | This class is used for both generation and parsing of 'JSON'.
+class GJSON f where
+  gto'   :: f a -> JSValue
+  gfrom' :: JSValue -> Result (f a)
+
+instance GJSON U where
+  gto'   U = JSNull
+  gfrom' JSNull = Ok U
+  gfrom' _      = Error "could not parse U"
+
+instance JSON a => GJSON (K a) where
+  gto' (K x) = showJSON x
+  gfrom' x = K <$> readJSON x
+
+instance (GJSON (S s f), GJSON g) => GJSON ((S s f) :*: g) where
+  gto' (a :*: b) = merge (gto' a) (gto' b)
+  gfrom' x       = do (:*:) <$> gfrom' x <*> gfrom' x
+
+instance (Selector s, GJSON f) => GJSON (S s f) where
+  gto' s@(S x) = JSObject $ toJSObject [(humanReadable $ selName s, gto' x)]
+  gfrom' (JSObject obj) = let s = humanReadable $ selName (undefined :: S s f x) 
+                         in case valFromObj s obj of
+                                 Ok x    -> S <$> gfrom' x
+                                 Error e -> Error e
+  gfrom' x              = Error $ "Expected json object, got " ++ show x
+
+instance GJSON f => GJSON (C c f) where
+  gto' (C x) = gto' x
+  gfrom' x   = C <$> gfrom' x
+
+merge :: JSValue -> JSValue -> JSValue
+merge (JSObject l) (JSObject r) = JSObject (toJSObject $ mergeList (fromJSObject l) (fromJSObject r))
+merge _            _            = error "Cannot merge objects."
+
+mergeList :: [(String, JSValue)] -> [(String, JSValue)] -> [(String, JSValue)]
+mergeList = unionBy (\x y -> fst x == fst y)
diff --git a/src/Generics/Regular/Views.hs b/src/Generics/Regular/Views.hs
new file mode 100644
--- /dev/null
+++ b/src/Generics/Regular/Views.hs
@@ -0,0 +1,104 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Generics.Regular.Views
+-- Copyright   :  (c) 2010 Chris Eidhof
+-- License     :  BSD3
+--
+-- Maintainer  :  chris@eidhof.nl
+-- Stability   :  experimental
+-- Portability :  non-portable
+--
+-- Summary: Functions for generating HTML.
+-----------------------------------------------------------------------------
+
+
+module Generics.Regular.Views (
+  -- * Generic HTML generation.
+  ghtml, 
+  Html (..),
+  GHtml
+  -- gtable, 
+  -- gtableRow,
+  -- Table (..),
+  -- GTable
+  ) where
+
+import Text.XHtml.Strict ((+++), (<<))
+import qualified Text.XHtml.Strict as X
+
+import Generics.Regular
+import Generics.Regular.Extras
+
+-- | The function 'ghtml' converts an 'a' value into 'X.Html'
+ghtml :: (Regular a, GHtml (PF a)) => a -> X.Html
+ghtml x = ghtmlf ghtml (from x)
+
+-- | The function 'gtable' converts a list of 'a's into an 'X.Html' table with a row for each element.
+gtable :: (Regular a, GTable (PF a)) => [a] -> X.Html
+gtable xs = X.table << map gtableRow xs
+
+-- | The class 'Html' converts a simple value 'a' into 'X.Html'.
+class Html a where
+  html :: a -> X.Html
+
+instance Html Float  where html = X.toHtml . show
+instance Html Int    where html = X.toHtml . show
+instance Html Bool   where html = X.toHtml . show
+instance Html String where html = X.toHtml 
+
+-- | The class 'GHtml' converts a simple value 'a' into 'X.Html'.
+class GHtml f where
+  ghtmlf :: (a -> X.Html) -> f a -> X.Html
+
+instance GHtml I where
+  ghtmlf f (I r) = f r
+
+instance (Constructor c, GHtml f) => GHtml (C c f) where
+  ghtmlf f cx@(C x) = (X.h1 << capitalize (conName cx)) +++ ghtmlf f x
+
+instance Html a => GHtml (K a) where
+  ghtmlf _ (K x) = html x
+
+instance (GHtml f, GHtml g) => GHtml (f :*: g) where
+  ghtmlf f (x :*: y) = ghtmlf f x +++ X.br +++ ghtmlf f y
+
+instance (GHtml f, GHtml g) => GHtml (f :+: g) where
+  ghtmlf f (L x) = ghtmlf f x
+  ghtmlf f (R y) = ghtmlf f y
+
+instance (Selector s, GHtml f) => GHtml (S s f) where
+  ghtmlf f s@(S x) = X.label << ((h s) ++ ": ") +++ ghtmlf f x
+
+
+class Table a where
+  table :: a -> X.Html
+
+instance Table Float  where table = html
+instance Table String where table = html
+instance Table Int    where table = html
+instance Table Bool   where table = html
+
+class GTable f where
+  gtablef :: (a -> X.Html) -> f a -> X.Html
+
+instance GTable I where
+  gtablef f (I r) = f r
+
+instance (Constructor c, GTable f) => GTable (C c f) where
+  gtablef f (C x) = X.tr << (gtablef f x)
+
+instance Table a => GTable (K a) where
+  gtablef _ (K x) = table x
+
+instance (GTable f, GTable g) => GTable (f :*: g) where
+  gtablef f (x :*: y) = gtablef f x +++ gtablef f y
+
+instance (Selector s, GTable f) => GTable (S s f) where
+  gtablef f (S x) = X.td << gtablef f x
+
+gtableRow :: (Regular a, GTable (PF a)) => a -> X.Html
+gtableRow x = gtablef gtableRow (from x)
