Safe Haskell | None |
---|---|
Language | Haskell2010 |
A haskell library for representing web pages.
This library is a collection of web page abstractions, together with a reimagining of suavemente.
I wanted to expose the server delivery mechanism, switch the streaming nature of the gap between a web page and a haskell server, and concentrate on getting a clean interface between pure haskell and the world that is a web page.
See app/examples.hs and Examples
for usage.
Synopsis
- data RepF r a = Rep {}
- type Rep a = RepF (Html ()) a
- oneRep :: (Monad m, MonadIO m) => Rep a -> (Rep a -> HashMap Text Text -> m ()) -> StateT (HashMap Text Text) m (HashMap Text Text, Either Text a)
- newtype SharedRepF m r a = SharedRep {}
- type SharedRep m a = SharedRepF m (Html ()) a
- runOnce :: Monad m => SharedRep m a -> (Html () -> HashMap Text Text -> m ()) -> m (HashMap Text Text, Either Text a)
- zeroState :: Monad m => SharedRep m a -> m (Html (), (HashMap Text Text, Either Text a))
- register :: Monad m => (Text -> Either Text a) -> (a -> Text) -> (Text -> a -> r) -> a -> SharedRepF m r a
- genName :: MonadState Int m => m Text
- genNamePre :: MonadState Int m => Text -> m Text
- data Page = Page {}
- data PageConfig = PageConfig {}
- defaultPageConfig :: FilePath -> PageConfig
- data Concerns a = Concerns {
- cssConcern :: a
- jsConcern :: a
- htmlConcern :: a
- suffixes :: Concerns FilePath
- concernNames :: FilePath -> FilePath -> Concerns FilePath
- data PageConcerns
- data PageStructure
- = HeaderBody
- | Headless
- | Snippet
- | Svg
- data PageRender
- type Css = StyleM ()
- data RepCss
- = RepCss Css
- | RepCssText Text
- renderCss :: Css -> Text
- renderRepCss :: PageRender -> RepCss -> Text
- newtype JS = JS {}
- data RepJs
- onLoad :: RepJs -> RepJs
- renderRepJs :: PageRender -> RepJs -> Text
- parseJs :: Text -> JS
- renderJs :: JS -> Text
- module Web.Rep.SharedReps
- module Web.Rep.Render
- module Web.Rep.Server
- module Web.Rep.Socket
- module Web.Rep.Html
- module Web.Rep.Html.Input
- module Web.Rep.Bootstrap
- module Web.Rep.Mathjax
- data HashMap k v
Shared Representation
Information contained in a web page can usually be considered to be isomorphic to a map of named values - a HashMap
. This is especially true when considering a differential of information contained in a web page. Looking at a page from the outside, it often looks like a streaming differential of a hashmap.
RepF consists of an underlying value being represented, and, given a hashmap state, a way to produce a representation of the underlying value (or error), in another domain, together with the potential to alter the hashmap state.
oneRep :: (Monad m, MonadIO m) => Rep a -> (Rep a -> HashMap Text Text -> m ()) -> StateT (HashMap Text Text) m (HashMap Text Text, Either Text a) Source #
stateful result of one step, given a RepF
, and a monadic action.
Useful for testing and for initialising a page.
newtype SharedRepF m r a Source #
Driven by the architecture of the DOM, web page components are compositional, and tree-like, where components are often composed of other components, and values are thus shared across components.
This is sometimes referred to as "observable sharing". See data-reify as another library that reifies this (pun intended), and provided the initial inspiration for this implementation.
unshare should only be run once, which is a terrible flaw that might be fixed by linear types.
runOnce :: Monad m => SharedRep m a -> (Html () -> HashMap Text Text -> m ()) -> m (HashMap Text Text, Either Text a) Source #
Compute the initial state of a SharedRep and then run an action once (see tests).
zeroState :: Monad m => SharedRep m a -> m (Html (), (HashMap Text Text, Either Text a)) Source #
compute the initial state of a SharedRep (testing)
:: Monad m | |
=> (Text -> Either Text a) | Parser |
-> (a -> Text) | Printer |
-> (Text -> a -> r) | create initial object from name and initial value |
-> a | initial value |
-> SharedRepF m r a |
Create a sharedRep
genName :: MonadState Int m => m Text Source #
name supply for elements of a SharedRepF
genNamePre :: MonadState Int m => Text -> m Text Source #
sometimes a number doesn't work properly in html (or js???), and an alpha prefix seems to help
Web Rep Components
Components of a web page.
A web page can take many forms but still have the same underlying representation. For example, CSS can be linked to in a separate file, or can be inline within html, but still be the same css and have the same expected external effect. A Page represents the practical components of what makes up a static snapshot of a web page.
Instances
Show Page Source # | |
Generic Page Source # | |
Semigroup Page Source # | |
Monoid Page Source # | |
type Rep Page Source # | |
Defined in Web.Rep.Page type Rep Page = D1 (MetaData "Page" "Web.Rep.Page" "web-rep-0.7.0-FbnLiBhVUXzFOFUBGflJ1L" False) (C1 (MetaCons "Page" PrefixI True) ((S1 (MetaSel (Just "libsCss") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 [Html ()]) :*: (S1 (MetaSel (Just "libsJs") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 [Html ()]) :*: S1 (MetaSel (Just "cssBody") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 RepCss))) :*: ((S1 (MetaSel (Just "jsGlobal") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 RepJs) :*: S1 (MetaSel (Just "jsOnLoad") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 RepJs)) :*: (S1 (MetaSel (Just "htmlHeader") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Html ())) :*: S1 (MetaSel (Just "htmlBody") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Html ())))))) |
data PageConfig Source #
Configuration options when rendering a Page
.
PageConfig | |
|
Instances
defaultPageConfig :: FilePath -> PageConfig Source #
Default configuration is inline ecma and css, separate html header and body, minified code, with the suggested filename prefix.
A web page typically is composed of some css, javascript and html.
Concerns
abstracts this structural feature of a web page.
Concerns | |
|
Instances
concernNames :: FilePath -> FilePath -> Concerns FilePath Source #
Create filenames for each Concern element.
data PageConcerns Source #
Is the rendering to include all Concerns
(typically in a html file) or be separated (tyypically into separate files and linked in the html file)?
Instances
Eq PageConcerns Source # | |
Defined in Web.Rep.Page (==) :: PageConcerns -> PageConcerns -> Bool # (/=) :: PageConcerns -> PageConcerns -> Bool # | |
Show PageConcerns Source # | |
Defined in Web.Rep.Page showsPrec :: Int -> PageConcerns -> ShowS # show :: PageConcerns -> String # showList :: [PageConcerns] -> ShowS # | |
Generic PageConcerns Source # | |
Defined in Web.Rep.Page type Rep PageConcerns :: Type -> Type # from :: PageConcerns -> Rep PageConcerns x # to :: Rep PageConcerns x -> PageConcerns # | |
type Rep PageConcerns Source # | |
data PageStructure Source #
Various ways that a Html file can be structured.
Instances
Eq PageStructure Source # | |
Defined in Web.Rep.Page (==) :: PageStructure -> PageStructure -> Bool # (/=) :: PageStructure -> PageStructure -> Bool # | |
Show PageStructure Source # | |
Defined in Web.Rep.Page showsPrec :: Int -> PageStructure -> ShowS # show :: PageStructure -> String # showList :: [PageStructure] -> ShowS # | |
Generic PageStructure Source # | |
Defined in Web.Rep.Page type Rep PageStructure :: Type -> Type # from :: PageStructure -> Rep PageStructure x # to :: Rep PageStructure x -> PageStructure # | |
type Rep PageStructure Source # | |
Defined in Web.Rep.Page type Rep PageStructure = D1 (MetaData "PageStructure" "Web.Rep.Page" "web-rep-0.7.0-FbnLiBhVUXzFOFUBGflJ1L" False) ((C1 (MetaCons "HeaderBody" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "Headless" PrefixI False) (U1 :: Type -> Type)) :+: (C1 (MetaCons "Snippet" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "Svg" PrefixI False) (U1 :: Type -> Type))) |
data PageRender Source #
Post-processing of page concerns
Instances
Eq PageRender Source # | |
Defined in Web.Rep.Page (==) :: PageRender -> PageRender -> Bool # (/=) :: PageRender -> PageRender -> Bool # | |
Show PageRender Source # | |
Defined in Web.Rep.Page showsPrec :: Int -> PageRender -> ShowS # show :: PageRender -> String # showList :: [PageRender] -> ShowS # | |
Generic PageRender Source # | |
Defined in Web.Rep.Page type Rep PageRender :: Type -> Type # from :: PageRender -> Rep PageRender x # to :: Rep PageRender x -> PageRender # | |
type Rep PageRender Source # | |
Defined in Web.Rep.Page |
Css
Unifies css as either a Css
or as Text.
Instances
Show RepCss Source # | |
Generic RepCss Source # | |
Semigroup RepCss Source # | |
Monoid RepCss Source # | |
type Rep RepCss Source # | |
Defined in Web.Rep.Page type Rep RepCss = D1 (MetaData "RepCss" "Web.Rep.Page" "web-rep-0.7.0-FbnLiBhVUXzFOFUBGflJ1L" False) (C1 (MetaCons "RepCss" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Css)) :+: C1 (MetaCons "RepCssText" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Text))) |
renderRepCss :: PageRender -> RepCss -> Text Source #
Render RepCss
as text.
JS
wrapper for JSAST
Unifies javascript as JSStatement
and script as Text
.
Instances
Eq RepJs Source # | |
Show RepJs Source # | |
Generic RepJs Source # | |
Semigroup RepJs Source # | |
Monoid RepJs Source # | |
type Rep RepJs Source # | |
Defined in Web.Rep.Page type Rep RepJs = D1 (MetaData "RepJs" "Web.Rep.Page" "web-rep-0.7.0-FbnLiBhVUXzFOFUBGflJ1L" False) (C1 (MetaCons "RepJs" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 JS)) :+: C1 (MetaCons "RepJsText" PrefixI False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Text))) |
renderRepJs :: PageRender -> RepJs -> Text Source #
re-export modules
module Web.Rep.SharedReps
module Web.Rep.Render
module Web.Rep.Server
module Web.Rep.Socket
module Web.Rep.Html
module Web.Rep.Html.Input
module Web.Rep.Bootstrap
module Web.Rep.Mathjax
re-exports
A map from keys to values. A map cannot contain duplicate keys; each key can map to at most one value.
Instances
Bifoldable HashMap | Since: unordered-containers-0.2.11 |
Eq2 HashMap | |
Ord2 HashMap | |
Defined in Data.HashMap.Internal | |
Show2 HashMap | |
Hashable2 HashMap | |
Defined in Data.HashMap.Internal | |
FunctorWithIndex k (HashMap k) | |
Defined in Control.Lens.Indexed | |
FoldableWithIndex k (HashMap k) | |
TraversableWithIndex k (HashMap k) | |
Defined in Control.Lens.Indexed itraverse :: Applicative f => (k -> a -> f b) -> HashMap k a -> f (HashMap k b) # itraversed :: IndexedTraversal k (HashMap k a) (HashMap k b) a b # | |
Functor (HashMap k) | |
Foldable (HashMap k) | |
Defined in Data.HashMap.Internal fold :: Monoid m => HashMap k m -> m # foldMap :: Monoid m => (a -> m) -> HashMap k a -> m # foldr :: (a -> b -> b) -> b -> HashMap k a -> b # foldr' :: (a -> b -> b) -> b -> HashMap k a -> b # foldl :: (b -> a -> b) -> b -> HashMap k a -> b # foldl' :: (b -> a -> b) -> b -> HashMap k a -> b # foldr1 :: (a -> a -> a) -> HashMap k a -> a # foldl1 :: (a -> a -> a) -> HashMap k a -> a # toList :: HashMap k a -> [a] # length :: HashMap k a -> Int # elem :: Eq a => a -> HashMap k a -> Bool # maximum :: Ord a => HashMap k a -> a # minimum :: Ord a => HashMap k a -> a # | |
Traversable (HashMap k) | |
Eq k => Eq1 (HashMap k) | |
Ord k => Ord1 (HashMap k) | |
Defined in Data.HashMap.Internal | |
(Eq k, Hashable k, Read k) => Read1 (HashMap k) | |
Defined in Data.HashMap.Internal | |
Show k => Show1 (HashMap k) | |
Hashable k => Hashable1 (HashMap k) | |
Defined in Data.HashMap.Internal | |
(Eq k, Hashable k) => IsList (HashMap k v) | |
(Eq k, Eq v) => Eq (HashMap k v) | Note that, in the presence of hash collisions, equal
In general, the lack of substitutivity can be observed with any function that depends on the key ordering, such as folds and traversals. |
(Data k, Data v, Eq k, Hashable k) => Data (HashMap k v) | |
Defined in Data.HashMap.Internal gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> HashMap k v -> c (HashMap k v) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (HashMap k v) # toConstr :: HashMap k v -> Constr # dataTypeOf :: HashMap k v -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (HashMap k v)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (HashMap k v)) # gmapT :: (forall b. Data b => b -> b) -> HashMap k v -> HashMap k v # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> HashMap k v -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> HashMap k v -> r # gmapQ :: (forall d. Data d => d -> u) -> HashMap k v -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> HashMap k v -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> HashMap k v -> m (HashMap k v) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> HashMap k v -> m (HashMap k v) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> HashMap k v -> m (HashMap k v) # | |
(Ord k, Ord v) => Ord (HashMap k v) | The ordering is total and consistent with the |
Defined in Data.HashMap.Internal | |
(Eq k, Hashable k, Read k, Read e) => Read (HashMap k e) | |
(Show k, Show v) => Show (HashMap k v) | |
(Eq k, Hashable k) => Semigroup (HashMap k v) | If a key occurs in both maps, the mapping from the first will be the mapping in the result. Examples
|
(Eq k, Hashable k) => Monoid (HashMap k v) | If a key occurs in both maps, the mapping from the first will be the mapping in the result. Examples
|
(Hashable k, Hashable v) => Hashable (HashMap k v) | |
Defined in Data.HashMap.Internal | |
(NFData k, NFData v) => NFData (HashMap k v) | |
Defined in Data.HashMap.Internal | |
(Eq k, Hashable k) => Ixed (HashMap k a) | |
Defined in Control.Lens.At | |
(Eq k, Hashable k) => At (HashMap k a) | |
(Hashable k, Eq k) => Wrapped (HashMap k a) | |
AsEmpty (HashMap k a) | |
Defined in Control.Lens.Empty | |
(t ~ HashMap k' a', Hashable k, Eq k) => Rewrapped (HashMap k a) t | Use |
Defined in Control.Lens.Wrapped | |
c ~ d => Each (HashMap c a) (HashMap d b) a b |
|
type Item (HashMap k v) | |
Defined in Data.HashMap.Internal | |
type Index (HashMap k a) | |
Defined in Control.Lens.At | |
type IxValue (HashMap k a) | |
Defined in Control.Lens.At | |
type Unwrapped (HashMap k a) | |
Defined in Control.Lens.Wrapped |