lucid2 ===== **Note**: For a list of changes from lucid1 to lucid2, see [CHANGELOG.md](https://github.com/chrisdone/lucid/blob/master/lucid2/CHANGELOG.md) Clear to write, read and edit DSL for writing HTML **Table of Contents** - [Introduction](#introduction) - [Rendering](#rendering) - [Good to know](#good-to-know) - [Transforming](#transforming) ## Version This is version 2 of the lucid package, according to the [Immutable Publishing Policy](https://chrisdone.com/posts/ipp/). There never be any breaking changes made to this package. ## Introduction HTML terms in Lucid are written with a postfix ‘`_`’ to indicate data rather than code. Some examples: `p_`, `class_`, `table_`, `style_` See `Lucid.Html5` for a complete list of Html5 combinators. Plain text is written using the `OverloadedStrings` and `ExtendedDefaultRules` extensions, and is automatically escaped: ``` haskell λ> "123 < 456" :: Html () ``` ``` html 123 < 456 ``` Elements nest by function application: ``` haskell λ> table_ (tr_ (td_ (p_ "Hello, World!"))) :: Html () ``` ``` html

Hello, World!

``` Elements are juxtaposed via monoidal append: ``` haskell λ> p_ "hello" <> p_ "sup" :: Html () ``` ``` html

hello

sup

``` Or monadic sequencing: ``` haskell λ> div_ (do p_ "hello"; p_ "sup") :: Html () ``` ``` html

hello

sup

``` Attributes are set by providing an argument list: ``` haskell λ> p_ [class_ "brand"] "Lucid Inc" :: Html () ``` ``` html

Lucid Inc

``` Here is a fuller example of Lucid: ``` haskell table_ [rows_ "2"] (tr_ (do td_ [class_ "top",colspan_ "2",style_ "color:red"] (p_ "Hello, attributes!") td_ "yay!")) ``` ``` html

Hello, attributes!

yay!
``` ## Rendering For proper rendering you can easily run some HTML immediately with: ``` haskell λ> renderText (p_ "Hello!") ``` ``` html "

Hello!

" ``` Or to bytes: ``` haskell λ> renderBS (p_ [style_ "color:red"] "Hello!") ``` ``` html "

Hello!

" ``` For ease of use in GHCi, there is a `Show` instance, as demonstrated above. If the above rendering functions aren't suited for your purpose, you can run the monad directly via `execHtml` and use the more low-level blaze `Builder`, which has a plethora of output modes in Blaze.ByteString.Builder. See the documentation for the `Lucid` module for information about using it as a monad transformer. ## Good to know * Attributes are escaped, so you cannot write arbitrary JavaScript in attributes. Instead, do something like `onclick_ "foo()"`. * Attributes are rendered in the order that they are written in your Haskell code. ## Transforming You can use `lift` to call parent monads. ``` haskell λ> runReader (renderTextT (html_ (body_ (do name <- lift ask p_ [class_ "name"] (toHtml name))))) ("Chris" :: String) ``` ``` html "

Chris

" ```