Copyright | (c) 2014 Ertugrul Soeylemez |
---|---|
License | BSD3 |
Maintainer | Ertugrul Soeylemez <ertesx@gmx.de> |
Safe Haskell | None |
Language | Haskell2010 |
This module provides the functionality to render web pages. The following is the process to construct and then render a web page:
- Construction: Use a writer monad to construct a
Widget
, which represents a web page component and is usually constructed from multiple smaller components. - Rendering: Use one of the rendering functions to render a
widget to a
Page
, which represents a rendered web page, but still abstracts over the exact set of documents (everything inline or a set of separate documents for markup, script and style). - Realisation: Realise the page as a set of documents that you
can deliver to the client, for example by using
realiseInline
.
The motivation for rendering to separate documents is that most web
pages consist of dynamic markup, but the stylesheet and script are
mostly static. The way Page
works you can have widgets with
batteries included and still render to separate documents to utilise
the client's cache better.
Helper functions for doing that are defined in this module, but framework-specific support is necessary to make this work.
Rendering pages
Rendered pages. This type supports realising a page as multiple documents like an HTML document, a separate script and a separate stylesheet, as explained above.
If you're running a low-traffic site and don't want to afford the
complexity, then you can just include the stylesheets and scripts
inline by using the realiseInline
function. Except for external
script and style URLs this will give you a self-contained document
that you can deliver to the client.
The pageHtml
field is the function that takes the markup for the
script and the style respectively and returns a builder that you can
send as text/html
to the client. The other two fields are the
rendered script and stylesheet. The markup is UTF-8-encoded, which
you should indicate in the content-type
header, if you deliver via
HTTP, although a meta
element is included as a fallback.
This is the most general rendering function for widgets. The title renderer receives the title chunks from outermost to innermost.
If you use type-safe routing and/or a sectioned or otherwise
non-Html
body type, you should first apply the necessary
transformations to perform the routing and/or flattening or
conversion of the body.
Note that Widget
is a family of applicative functors. There are
also predefined functions to assist you with this transformation.
See the Web.Page.Route module and the mapLinksA
, mapLinksM
and
flattenBody
functions.
titleMajor :: Text -> [Text] -> Text Source
Intercalate the given title chunks using the given separator,
highest level title first. For most web sites titleMinor
is
preferable.
>>>
titleMajor " - " ["site", "department", "page"]
"site - department - page"
titleMinor :: Text -> [Text] -> Text Source
Intercalate the given title chunks using the given separator,
lowest level title first. This is much more common on web sites than
titleMajor
, because it's usually more convenient for the user to
have the page title in the leftmost position (think about browser tab
captions and title bars).
>>>
titleMinor " - " ["site", "department", "page"]
"page - department - site"
Realising pages
realiseInline :: Page -> Builder Source
Realise the given page as a single self-contained document,
including the script and stylesheet inline. The resulting string is
UTF-8-encoded and contains a meta
element to indicate that. Read
the documentation of Page
for details.