Giter VIP home page Giter VIP logo

blazet's Introduction

blazeT Build Status Hackage

A true monad (transformer) version of the blaze-markup and blaze-html libraries:

BlazeHtml is a blazingly fast HTML combinator library for the Haskell programming language. It embeds HTML templates in Haskell code for optimal efficiency and composability.

— from https://jaspervdj.be/blaze/.

What’s wrong with blaze?

Blaze’s Markup and Html cannot be used as Monads, let alone Monad transformers.

While blaze's Markup and Html types have Monad instances and can leverage the concise do notation, they do not satisfy the Monad Laws.

How do Monads help? - Use Cases

The MarkupT Monad Transformer enables us to write Markup (e.g. HTML) templates that have access to all those Monads you cannot live without anymore.

The first things that come to mind:

  • Accessing an environment (MonadReader)
  • Logging and other diagnostic output (MonadWriter),
  • IO (e.g. for database access)

The reason for the existence of this library is its use in Lykah, which powers my personal website http://johannesgerer.com. In Lykah, the HTML templates have access to the whole site structure (to build things like menus or blog post lists) and automatically check, insert and keep track of referenced pages and assets, which turns out to be very useful functionality of a static website generator.

Usage

Integrating with your existing code

The library is intended to serve as a drop-in replacement for the blaze-markup and blaze-html libraries and should be backwards compatible:

Simply replace your module Text.Blaze.* imports with module Text.BlazeT.* and it should give the same results.

For usage of blaze check out their documentation.

Unleash the monads

Text.BlazeT exports runWith and execWith, which work on any Text.BlazeT.Renderer.*. The rendered markup will be returned within the base monad, whose actions can be lifted into the Markup, as shown in the following example (from here):

{-# LANGUAGE OverloadedStrings #-}

import Data.Time (getCurrentTime)
import Text.BlazeT.Html5 hiding (main)
import Text.BlazeT.Renderer.String
import Control.Monad.Trans.Class (lift)

-- Backwords compatible Blaze HTML
old :: Markup
old = do
  p $ "created with blaze-html"

-- BlazeT HTML with lifted IO actions
new :: MarkupT IO ()
new = do
  time <- lift getCurrentTime
  p $ string $ "created with blazeT at " ++ show time

main :: IO ()
main = do
  putStrLn $            renderMarkup old
  putStrLn =<< execWith renderMarkup new
  

prints:

<p>created with blaze-html</p>
<p>created with blazeT at 2016-10-26 01:09:16.969147361 UTC</p>

Installation

  1. To make it available on your system (or sandbox) use cabal install blazeT.

  2. To play around with the source, obtain by cloning this repo or use cabal get blazet, enter the directory and run:

cabal sandbox init #optional
cabal install

Documentation on Hackage

Implementation

... is contained in Text.BlazeT.Internals.

Everything is build around the simple newtype definition of the MarkupT transformer, which makes use the Monoid instance of Blaze.Markup and is simply a WriterT writing Blaze.Markup:

newtype MarkupT m a = MarkupT { fromMarkupT :: WriterT B.Markup m a }

The old Text.Blaze.Markup type is replaced by a rank-2 version of the transformer:

type Markup = forall m . Monad m => MarkupT m ()

Wrappers used to lift all Blaze entities into BlazeT are trivially expressible using basic WriterT class methods. Wrapping Blaze.Markup is simply WriterT.tell:

wrapMarkupT :: Monad m => B.Markup -> MarkupT m ()
wrapMarkupT = tell

Wrapping functions that modify Blaze.Markup is simply WriterT.censor:

wrapMarkupT2 :: Monad m => (B.Markup -> B.Markup) -> MarkupT m a -> MarkupT m a
wrapMarkupT2 = censor

blazet's People

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

blazet's Issues

Setup.hs does not compile with Cabal > 2.0.1.1

Problem:

/home/user/Packages/Haskell/Own/teilfeil-0.1.0.2/dist-newstyle/tmp/src-16404/blazeT-0.0.5/dist/setup/setup.hs:11:9:
error:
Not in scope: ‘haddockHscolour’
Perhaps you meant ‘haddockHscolourCss’ (imported from
Distribution.Simple.Setup)
)

Reason: package Cabal:
Distribution.Simple.Setup.HaddockFlags
does not anymore have the field:
haddockHscolour.

Solution:

Remove corresponding line in Setup.hs

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.