Safe Haskell | None |
---|---|
Language | Haskell2010 |
This module provides Context
s which are used to expand expressions in
templates and allow for arbitrary customisation.
Template
s define a small expression DSL which consists of strings,
identifiers and function application. There is no type system, every value is
a string and on the top level they get substituted verbatim into the page.
For example, you can build a context that contains
… <> functionField "concat" (const . concat) <> …
which will allow you to use the concat
identifier as a function that takes
arbitrarily many stings and concatenates them to a new string:
$partial(concat("templates/categories/", category))$
This will evaluate the category
field in the context, then prepend he path,
and include the referenced file as a template.
Synopsis
- data ContextField
- = EmptyField
- | StringField String
- | ListField (Context a) [Item a]
- newtype Context a = Context {}
- field :: String -> (Item a -> Compiler String) -> Context a
- boolField :: String -> (Item a -> Bool) -> Context a
- constField :: String -> String -> Context a
- listField :: String -> Context a -> Compiler [Item a] -> Context b
- listFieldWith :: String -> Context a -> (Item b -> Compiler [Item a]) -> Context b
- functionField :: String -> ([String] -> Item a -> Compiler String) -> Context a
- mapContext :: (String -> String) -> Context a -> Context a
- defaultContext :: Context String
- bodyField :: String -> Context String
- metadataField :: Context a
- urlField :: String -> Context a
- pathField :: String -> Context a
- titleField :: String -> Context a
- snippetField :: Context String
- dateField :: String -> String -> Context a
- dateFieldWith :: TimeLocale -> String -> String -> Context a
- getItemUTC :: MonadMetadata m => TimeLocale -> Identifier -> m UTCTime
- getItemModificationTime :: Identifier -> Compiler UTCTime
- modificationTimeField :: String -> String -> Context a
- modificationTimeFieldWith :: TimeLocale -> String -> String -> Context a
- teaserField :: String -> Snapshot -> Context String
- teaserFieldWithSeparator :: String -> String -> Snapshot -> Context String
- missingField :: Context a
Documentation
data ContextField Source #
Mostly for internal usage
EmptyField | |
StringField String | |
ListField (Context a) [Item a] |
The Context
monoid. Please note that the order in which you
compose the items is important. For example in
field "A" f1 <> field "A" f2
the first context will overwrite the second. This is especially
important when something is being composed with
metadataField
(or defaultContext
). If you want your context to be
overwritten by the metadata fields, compose it from the right:
metadataField
<> field "date" fDate
:: String | Key |
-> (Item a -> Compiler String) | Function that constructs a value based on the item (e.g. accessing metadata) |
-> Context a |
Constructs a new field for a Context
.
If the key matches, the compiler is run and its result is substituted in the
template.
If the compiler fails, the field will be considered non-existent
in an $if()$
macro or ultimately break the template application
(unless the key is found in another context when using <>
).
Use empty
or noResult
for intentional failures of fields used in
$if()$
, to distinguish them from exceptions thrown with fail
.
boolField :: String -> (Item a -> Bool) -> Context a Source #
Creates a field
to use with the $if()$
template macro.
Attempting to substitute the field into the template will cause an error.
listField :: String -> Context a -> Compiler [Item a] -> Context b Source #
Creates a list field to be consumed by a $for(…)$
expression.
The compiler returns multiple items which are rendered in the loop body
with the supplied context.
listFieldWith :: String -> Context a -> (Item b -> Compiler [Item a]) -> Context b Source #
Creates a list field like listField
, but supplies the current page
to the compiler.
Creates a variadic function field.
The function will be called with the dynamically evaluated string arguments from the template as well as the page that is currently rendered.
mapContext :: (String -> String) -> Context a -> Context a Source #
Transform the respective string results of all fields in a context. For example,
mapContext (++"c") (constField "x" "a" <> constField "y" "b")
is equivalent to
constField "x" "ac" <> constField "y" "bc"
defaultContext :: Context String Source #
A context that contains (in that order)
- A
$body$
field - Metadata fields
- A
$url$
urlField
- A
$path$
pathField
- A
$title$
titleField
bodyField :: String -> Context String Source #
Constructs a field
that contains the body of the item.
metadataField :: Context a Source #
Map any field to its metadata value, if present
titleField :: String -> Context a Source #
This title field
takes the basename of the underlying file by default
snippetField :: Context String Source #
A context that allows snippet inclusion. In processed file, use as:
... $snippet("path/to/snippet/")$ ...
The contents of the included file will not be interpolated like partial
does it.
:: String | Key in which the rendered date should be placed |
-> String | Format to use on the date |
-> Context a | Resulting context |
When the metadata has a field called published
in one of the
following formats then this function can render the date.
Mon, 06 Sep 2010 00:01:00 +0000
Mon, 06 Sep 2010 00:01:00 UTC
Mon, 06 Sep 2010 00:01:00
2010-09-06T00:01:00+0000
2010-09-06T00:01:00Z
2010-09-06T00:01:00
2010-09-06 00:01:00+0000
2010-09-06 00:01:00
September 06, 2010 00:01 AM
Following date-only formats are supported too (00:00:00
for time is
assumed)
2010-09-06
September 06, 2010
Alternatively, when the metadata has a field called path
in a
folder/yyyy-mm-dd-title.extension
format (the convention for pages)
and no published
metadata field set, this function can render
the date. This pattern matches the file name or directory names
that begins with yyyy-mm-dd
. For example:
folder/yyyy-mm-dd-titledist/main.extension
.
In case of multiple matches, the rightmost one is used.
As another alternative, if none of the above matches, and the file has a
path which contains nested directories specifying a date, then that date
will be used. In other words, if the path is of the form
**/yyyymmdd/main.extension
.
As above, in case of multiple matches, the rightmost one is used.
:: TimeLocale | Output time locale |
-> String | Destination key |
-> String | Format to use on the date |
-> Context a | Resulting context |
This is an extended version of dateField
that allows you to
specify a time locale that is used for outputting the date. For more
details, see dateField
and formatTime
.
:: MonadMetadata m | |
=> TimeLocale | Output time locale |
-> Identifier | Input page |
-> m UTCTime | Parsed UTCTime |
Parser to try to extract and parse the time from the published
field or from the filename. See dateField
for more information.
Exported for user convenience.
getItemModificationTime :: Identifier -> Compiler UTCTime Source #
Get the time on which the actual file was last modified. This only works if there actually is an underlying file, of couse.
modificationTimeField Source #
Creates a field with the last modification date of the underlying item.
modificationTimeFieldWith Source #
:: TimeLocale | Time output locale |
-> String | Key |
-> String | Format |
-> Context a | Resulting context |
Creates a field with the last modification date of the underlying item
in a custom localisation format (see formatTime
).
A context with "teaser" key which contain a teaser of the item. The item is loaded from the given snapshot (which should be saved in the user code before any templates are applied).
teaserFieldWithSeparator Source #
:: String | Separator to use |
-> String | Key to use |
-> Snapshot | Snapshot to load |
-> Context String | Resulting context |
A context with "teaser" key which contain a teaser of the item, defined as the snapshot content before the teaser separator. The item is loaded from the given snapshot (which should be saved in the user code before any templates are applied).
missingField :: Context a Source #
Constantly reports any field as missing. Mostly for internal usage, it is the last choice in every context used in a template application.