Skip to content

Commit 2ab7e0f

Browse files
committed
Update readme
1 parent 3052376 commit 2ab7e0f

File tree

1 file changed

+145
-4
lines changed

1 file changed

+145
-4
lines changed

README.md

+145-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,151 @@
1-
# GHCJS Perch
1+
# Perch #
22

33
[![Build Status](https://travis-ci.org/geraldus/ghcjs-perch.svg?branch=master)](https://travis-ci.org/geraldus/ghcjs-perch)
44

5-
This is a GHCJS port of Perch library originally written by Alberto Gómez
6-
Corona<sup>[1][haste-perch]</sup>.
5+
This is a GHCJS port of Perch library<sup>[1][haste-perch]</sup> originally
6+
written by Alberto Gómez Corona.
77

8-
This library provides `Perch` fake-monad to build and manipulate DOM tree.
8+
![perch](http://i65.tinypic.com/zlu7g1.jpg)
9+
10+
Perch defines DOM element builders (perches) that are append-able, so that
11+
dynamic HTML can be created in the client application in natural way, like
12+
textual HTML but programmatically and with the advantage of static type
13+
checking.
14+
15+
Main use case of Perch is client side applications, however it can be used in
16+
monolithic server-and-client apps too, if this is what you need take a look at
17+
`HPlay`<sup>[2][hplay]</sup> library.
18+
19+
This package makes the creation of DOM elements easy with a syntax similar to
20+
other Haskell HTML generators such as `blaze-html`<sup>[3][blaze]</sup>, using
21+
monoids and monads.
22+
23+
## Examples ##
24+
25+
Build DOM tree
26+
27+
```hs
28+
{-# LANGUAGE ExtendedDefaultRules #-}
29+
{-# LANGUAGE OverloadedStrings #-}
30+
module Main where
31+
32+
import Data.JSString (JSString)
33+
import GHCJS.Perch
34+
import Prelude hiding (div, id)
35+
default (JSString)
36+
37+
dom :: Perch
38+
dom =
39+
div ! id "wrap" $
40+
do div ! id "content" $
41+
do p "Hello World!"
42+
a ! href "https://github.com/geraldus/ghcjs-perch" $
43+
"Perch on GitHub"
44+
div ! id "footer" $ "Happy Haskelling!"
45+
46+
main :: IO ()
47+
main =
48+
do documentBody <- getBody
49+
build dom documentBody
50+
return ()
51+
```
52+
53+
This will create following DOM inside document's body at run time:
54+
```html
55+
<div id="wrap">
56+
<div id="content">
57+
<p>Hello World!</p>
58+
<a href="https://github.com/geraldus/ghcjs-perch">Perch on GitHub</a>
59+
</div>
60+
<div id="footer">Happy Haskelling!</div>
61+
</div>
62+
```
63+
64+
65+
This example program takes already existing DOM element, attaches click event
66+
handler to it and adds some content:
67+
68+
```haskell
69+
import Prelude hiding (div, span)
70+
71+
main :: IO ()
72+
main =
73+
do forElemId_ "my-element" $
74+
do addEvent' this Click (\ _ -> print "Hello, world!")
75+
div $
76+
do span "GHC"
77+
span ! atr "style" "color:red" $ "JS"
78+
return ()
79+
```
80+
81+
yields following DOM as result:
82+
83+
```html
84+
<div id="my-element"> <!-- was already in the DOM -->
85+
"Hello World!"
86+
<div>
87+
<span>GHC</span>
88+
<span style="color:red">JS</span>
89+
</div>
90+
</div>
91+
```
92+
93+
94+
Next example modifies the previously created elements when the event is raised,
95+
the event handler is attched using CSS selector and modifies all elements with
96+
`modify` class:
97+
98+
```haskell
99+
main :: IO ()
100+
main =
101+
do body <- getBody
102+
flip build body $
103+
do div ! atr "class" "modify" $ "click"
104+
div "not changed"
105+
div ! atr "class" "modify" $ "here"
106+
addEvent' this Click $ \_ ->
107+
forElems_ ".modify" $
108+
this ! style "color:red" `child` " modified"
109+
return ()
110+
```
111+
112+
113+
The monoid expression can also be used. Concatenate elements with the `<>`
114+
operator. `term1 <> term2 <> ...` is equivalent to
115+
116+
```
117+
do term1
118+
term2
119+
...
120+
```
121+
122+
Perch can also be used to navigate the tree, search, etc.
123+
124+
The monad instance provided in order to use do-notation. This adds a new level
125+
of syntax in the fashion of `blaze-html` package. This monad invokes the same
126+
appending mechanism. But be aware that `Perch` is a fake-monad, it lacks of
127+
bind function implementation and does not satisfies monad laws.
128+
129+
Perch is a generalization of a list and it is handled in the same way.
130+
131+
While a list is an unary tree, perch create N-ary trees. Monoid instance of
132+
list adds child nodes down, and this is the only direction list can grow. While
133+
perch monoid adds child horizontally at the same level. To create down
134+
branching there is `child` primitive.
135+
136+
137+
## Few Words About Library Name ##
138+
139+
The basic element is a builder that has a "hole" parameter and an IO action
140+
which creates DOM element. That "hole" will be filled with parent element
141+
created by the build action. So builder can be considered like a perch that has
142+
other perches that hang from it. Either no one or an entire tree.
143+
144+
The call `nelem` (new element) is a perch that creates a single DOM element.
145+
Upon created, it is added to the given parent and return itself as parent for
146+
the next build actions that can be hooked from it using `child`. When appending
147+
two elements, both are added to the parent.
9148

10149
[haste-perch]:https://github.com/agocorona/haste-perch
150+
[hplay]:https://github.com/agocorona/ghcjs-hplay
151+
[blaze]:http://hackage.haskell.org/package/blaze-html

0 commit comments

Comments
 (0)