BSD-3-Clause licensed by Chris Done
Maintained by [email protected]
This version can be pinned in stack with:lucid2-0.0.20240424@sha256:772e0056d65ccb4070e6a6088891e79c939062d64cae0cdc6976e5bfd8bfef75,2169

Module documentation for 0.0.20240424

lucid2

Note: For a list of changes from lucid1 to lucid2, see CHANGELOG.md

Clear to write, read and edit DSL for writing HTML

Table of Contents

Version

This is version 2 of the lucid package, according to the Immutable Publishing Policy.

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:

λ> "123 < 456" :: Html ()
123 &lt; 456

Elements nest by function application:

λ> table_ (tr_ (td_ (p_ "Hello, World!"))) :: Html ()
<table><tr><td><p>Hello, World!</p></td></tr></table>

Elements are juxtaposed via monoidal append:

λ> p_ "hello" <> p_ "sup" :: Html ()
<p>hello</p><p>sup</p>

Or monadic sequencing:

λ> div_ (do p_ "hello"; p_ "sup") :: Html ()
<div><p>hello</p><p>sup</p></div>

Attributes are set by providing an argument list:

λ> p_ [class_ "brand"] "Lucid Inc" :: Html ()
<p class="brand">Lucid Inc</p>

Here is a fuller example of Lucid:

table_ [rows_ "2"]
       (tr_ (do td_ [class_ "top",colspan_ "2",style_ "color:red"]
                    (p_ "Hello, attributes!")
                td_ "yay!"))
<table rows="2">
  <tr>
    <td style="color:red" colspan="2" class="top">
      <p>Hello, attributes!</p>
    </td>
    <td>yay!</td>
  </tr>
</table>

Rendering

For proper rendering you can easily run some HTML immediately with:

λ> renderText (p_ "Hello!")
"<p>Hello!</p>"

Or to bytes:

λ> renderBS (p_ [style_ "color:red"] "Hello!")
"<p style=\"color:red\">Hello!</p>"

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.

λ> runReader (renderTextT (html_ (body_ (do name <- lift ask
                                            p_ [class_ "name"] (toHtml name)))))
             ("Chris" :: String)
"<html><body><p class=\"name\">Chris</p></body></html>"

Copyright

  • Copyright (c) 2014-2022 Chris Done
  • Copyright (c) 2013 Leon P Smith
  • Copyright (c) 2010 Jasper Van der Jeugt, 2010-2011 Simon Meier

Changes

0.0.20240424

0.0.20230706

0.0.20221012

  • Fix commuteHtmlT in favor of newly added commuteHtmlT2

0.0.20220526

This release adds some extra functions for running different monad stacks, prompted by Joe Vargas.

  • Add generalizeHtmlT, commuteHtmlT and hoistHtmlT.
  • Deprecate the accidentally exported relaxHtmlT = undefined.

0.0.20220509

  • Use explicit imports for mtl, avoiding mtl-2.3 incompatibility.

New in lucid2

lucid2 is a new package published to Hackage and maintained under lucid2/ in this repository alongside lucid1. Releases are made under the Immutable Publishing Policy, and users had asked for many breaking changes, therefore we needed a completely new namespace to work under, hence, “lucid2”. Many things have also been dropped in the process, to simplify the codebase.

This upgrade is entirely optional.

People using lucid will not have to do anything. They can continue using that package indefinitely, it will be maintained alongside lucid2, to keep it building with GHCs and things. You can even use both packages in the same codebase with -XPackageImports.

Changed:

  • All on* attributes and style_ do not escape their values anymore. Be careful. Though you were probably being careful with these anyway, as they are inherently dangerous for XXS.
  • The Attribute type has been replaced by Attributes, which is a Monoid instance. This makes it really easy to write code like if X then class_ "foo" else mempty.
  • The class_ and style_ attributes combine with a space and ; between them when there are duplicates, e.g. [class_ "x",class_ "y"] produces class="x y". These are special cases, the rest of the attributes do not have special combining behavior and will be simple concatenation.

Renamed:

  • makeAttribute is renamed to makeAttributes.
  • Added makeAttributesRaw.

Dropped:

  • Eq/Ord/Show instances for Attribute.
  • Drop the Lucid.Bootstrap module entirely.
  • Dropped the mmorph dependency (breaking changes often, not reliable), instead we provide a simple hoist function of the right type.
  • Drop MonadError.
  • Drop MonadWriter.
  • Drop hashable.
  • Drop XML elements.

Dependencies:

  • We now only depend on blaze-builder, and the rest are libraries that come with GHC, which are held to a slightly higher standard of not breaking changes.