Contribution:
happstack
Headline
Web programming in Language:Haskell with Technology:Happstack
Motivation
The implementation demonstrates web programming in Language:Haskell with the Technology:Happstack framework. The templating engine Technology:Heist for Language:XHTML is used for the composition of dynamic web pages. The system:Company is implemented as a web application using a client-server architecture. The company is stored in a client-side cookie. (The server initializes the cookie with a sample company.) URLs are used to encode requests and ids of involved data. There are these requests, which essentially correspond to user actions: a user can either view a specific part of the company, save an edited part, or cut salaries in the selected scope. The part to be viewed, cut, or saved is specified by making use of a Zipper-inspired focus concept that is also leveraged by Contribution:wxHaskell. Modified data is validated. That is, when processing a save request, sent by an HTML form, the server applies various validators and potentially returns error messages, which will be displayed to the user in the web browser. As a response, the client receives HTML documents, which are composed using Technology:Heist.
Illustration
In the following we will demonstrate how a specific request is processed by the server.
Saving an Employee
Scenario: After requesting to view a manager the user manipulates the input fields and submits a request by clicking a save button. The browser sends an HTTP-request together with a company-cookie to the server. The URL looks like this:
http://localhost:8000/Employee/Save/ManagerFocus%20[0]/?Name=Erik&Address=
Utrecht&Salary=1234.0
Routing filter
We set up a simple HTTP server:
main = simpleHTTP nullConf $
msum [ path $ \v -> path $ \a -> path $
\f -> mainPart a v f
, serveDirectory EnableBrowsing [] "static"]
ServerPartT
MonadPlus
msum
path
The view (here
Employee
Save
ManagerFocus [0]
mainPart
mainPart :: Action -> View -> Focus -> ServerPartT IO Response
mainPart View = viewPart
mainPart Cut = cutPart
mainPart Save = savePart
mainPart
Save
savePart
Saving
savePart :: View -> Focus -> ServerPartT IO Response
savePart v f = do
s <- save
case s of
(Left errs) -> do
c <- readCCookie
displayPart v f c errs
(Right newc) -> displayPart v f newc []
where
save = case v of
CompanyV -> saveCompany f
DeptV -> saveDepartment f
EmployeeV -> saveEmployee f
View
save
Focus -> ServerPartT IO (Either [(ENames,String)] Company)
savePart
displayPart
displayPart
saveEmployee
savePart
saveEmployee :: Focus -> ServerPartT IO (Either [(ENames,String)] Company)
saveEmployee f = do
c <- readCCookie
name <- look "Name"
address <- look "Address"
salary <- lookRead "Salary"
let newe = Employee name address salary
let ev = validateEmployee c f newe
case ev of
(Just errs)
-> return $ Left errs
Nothing
-> do
let newc = writeEM f c newe
addCookie Session $
(mkCookie "company" (show newc))
return $ Right newc
saveEmployee
Employee
validateEmployee
Company -> Focus -> a -> Maybe [(ENames,String)]
validateEmployee
Nothing
validateEmployee
saveEmployee
Validation
The validation functionality can be found in the Validators module:
validateEmployee :: Validations Employee
validateEmployee c f (Employee n a s) = if null vs
then Nothing
else Just $ concat vs
where
vs = catMaybes
[ validateNA c f (n,a)
, validateSalary c f s]
validateEmployee
validateNA
c
validateSalary
- It checks whether by changing the salary the employee's department-manager still receives the highest salary within the department.
- It checks whether the salary has a positive value.
Nothing
validateEmployee
Nothing
Binding and Responding
The user might have tried to assign an invalid salary and an invalid name/address pair to the manager in question. Validation therefore would return error information.
savePart
displayPart
displayPart :: View -> Focus -> Company -> [(ENames,String)] -> ServerPart Response
displayPart v f c errs = do
td <- newTemplateDirectory' tDir $
eNamesBinder errs $ binder f c $
emptyTemplateState tDir
render td (B.pack tname)
where
binder = case v of
CompanyV -> companyBinder
DeptV -> departmentBinder
EmployeeV -> employeeBinder
where
tname = case v of
CompanyV -> "company"
DeptV -> "department"
EmployeeV -> "employee"
displayPart
case
eNamesBinder
Monad m => TemplateState m -> TemplateState m
displayPart
Architecture
this!!Main.hs holds the server using various server parts in this!!Serverparts.hs. The actual save action is performed by functionality in this!!Save.hs. this!!Binder.hs contains functions to bind template variables. The validators can be found in this!!Validators.hs using helper functions hosted by this!!Utils.hs. The algebraic datatype for companies can be found in this!!Company.hs, a sample company in this!!SampleCompany.hs. Functionality to total and cut is provided by this!!Total.hs and this!!Cut.hs. this!!Focus.hs provides a focus datatype and functions on top of it. Various types used by the server can be found in this!!Types.hs. The this!!static folder contains the sytlesheet for the application and images, while this!!templates contains the (X)HTML templates.
Usage
Build
A number of cabal packages are needed:
- happstack
- xmlhtml
- heist
- happstack-heist
Run
- this!!Main.hs can to be consulted with runhaskell to avoid the compilation step.
- Open http://localhost:8000/Company/View/CompanyFocus to demo, starting with the root view.
There are no revisions for this page.
User contributions
User edits
Syntax for editing wiki
For you are available next options:will make text bold.
will make text italic.
will make text underlined.
will make text striked.
will allow you to paste code headline into the page.
will allow you to link into the page.
will allow you to paste code with syntax highlight into the page. You will need to define used programming language.
will allow you to paste image into the page.
is list with bullets.
is list with numbers.
will allow your to insert slideshare presentation into the page. You need to copy link to presentation and insert it as parameter in this tag.
will allow your to insert youtube video into the page. You need to copy link to youtube page with video and insert it as parameter in this tag.
will allow your to insert code snippets from @worker.
Syntax for editing wiki
For you are available next options:will make text bold.
will make text italic.
will make text underlined.
will make text striked.
will allow you to paste code headline into the page.
will allow you to link into the page.
will allow you to paste code with syntax highlight into the page. You will need to define used programming language.
will allow you to paste image into the page.
is list with bullets.
is list with numbers.
will allow your to insert slideshare presentation into the page. You need to copy link to presentation and insert it as parameter in this tag.
will allow your to insert youtube video into the page. You need to copy link to youtube page with video and insert it as parameter in this tag.
will allow your to insert code snippets from @worker.