5 people like it.
Like the snippet!
DotLiquid integration with Suave
Example of integrating DotLiquid with a simple Suave server. The snippet automatically registers all public members of a record as members that can be accessed by DotLiquid templates.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
|
let parseTemplate<'T> template =
let rec registerTypeTree ty =
if FSharpType.IsRecord ty then
let fields = FSharpType.GetRecordFields(ty)
Template.RegisterSafeType(ty, [| for f in fields -> f.Name |])
for f in fields do registerTypeTree f.PropertyType
elif ty.IsGenericType &&
( let t = ty.GetGenericTypeDefinition()
in t = typedefof<seq<_>> || t = typedefof<list<_>> ) then
() //registerTypeTree (ty.GetGenericArguments().[0])
registerTypeTree (ty.GetGenericArguments().[0])
else () (* printfn "%s" ty.FullName *)
registerTypeTree typeof<'T>
let t = Template.Parse(template)
fun k (v:'T) -> t.Render(Hash.FromDictionary(dict [k, box v]))
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
|
type Task =
{ What : string }
type Person =
{ Name : string
Tasks : seq<Task> }
let t = parseTemplate<Person> """<p>{{ user.Name }} has to do:</p>
<ul>
{% for item in user.Tasks -%}
<li>{{ item.What }}</li>
{% endfor -%}
</ul>
"""
let app = OK (t "user" {Name="Tomas"; Tasks = [ {What="sleep"}; {What="eat"} ]})
|
val parseTemplate : template:string -> (string -> 'T -> string)
Full name: Script.parseTemplate
val template : string
val registerTypeTree : (Type -> unit)
val ty : Type
type FSharpType =
static member GetExceptionFields : exceptionType:Type * ?bindingFlags:BindingFlags -> PropertyInfo []
static member GetFunctionElements : functionType:Type -> Type * Type
static member GetRecordFields : recordType:Type * ?bindingFlags:BindingFlags -> PropertyInfo []
static member GetTupleElements : tupleType:Type -> Type []
static member GetUnionCases : unionType:Type * ?bindingFlags:BindingFlags -> UnionCaseInfo []
static member IsExceptionRepresentation : exceptionType:Type * ?bindingFlags:BindingFlags -> bool
static member IsFunction : typ:Type -> bool
static member IsModule : typ:Type -> bool
static member IsRecord : typ:Type * ?bindingFlags:BindingFlags -> bool
static member IsTuple : typ:Type -> bool
...
Full name: Microsoft.FSharp.Reflection.FSharpType
static member FSharpType.IsRecord : typ:Type * ?allowAccessToPrivateRepresentation:bool -> bool
static member FSharpType.IsRecord : typ:Type * ?bindingFlags:Reflection.BindingFlags -> bool
val fields : Reflection.PropertyInfo []
static member FSharpType.GetRecordFields : recordType:Type * ?allowAccessToPrivateRepresentation:bool -> Reflection.PropertyInfo []
static member FSharpType.GetRecordFields : recordType:Type * ?bindingFlags:Reflection.BindingFlags -> Reflection.PropertyInfo []
type Template =
member Assigns : Hash
member Errors : List<Exception>
member InstanceAssigns : Hash
member Registers : Hash
member Render : unit -> string + 4 overloads
member Root : Document with get, set
static val NamingConvention : INamingConvention
static member FileSystem : IFileSystem with get, set
static member GetSafeTypeTransformer : type:Type -> Func<obj, obj>
static member GetTagType : name:string -> Type
...
Full name: DotLiquid.Template
Template.RegisterSafeType(type: Type, func: Func<obj,obj>) : unit
Template.RegisterSafeType(type: Type, allowedMembers: string []) : unit
Template.RegisterSafeType(type: Type, allowedMembers: string [], func: Func<obj,obj>) : unit
val f : Reflection.PropertyInfo
property Reflection.MemberInfo.Name: string
property Reflection.PropertyInfo.PropertyType: Type
property Type.IsGenericType: bool
val t : Type
Type.GetGenericTypeDefinition() : Type
val typedefof<'T> : Type
Full name: Microsoft.FSharp.Core.Operators.typedefof
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq
--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
Type.GetGenericArguments() : Type []
val typeof<'T> : Type
Full name: Microsoft.FSharp.Core.Operators.typeof
val t : Template
Template.Parse(source: string) : Template
val k : string
val v : 'T
Template.Render() : string
Template.Render(parameters: RenderParameters) : string
Template.Render(localVariables: Hash) : string
Template.Render(stream: Stream, parameters: RenderParameters) : unit
Template.Render(result: TextWriter, parameters: RenderParameters) : unit
Multiple items
type Hash =
new : unit -> Hash + 2 overloads
member Add : item:KeyValuePair<string, obj> -> unit + 2 overloads
member Clear : unit -> unit
member Contains : key:obj -> bool + 1 overload
member ContainsKey : key:string -> bool
member CopyTo : array:KeyValuePair<string, obj>[] * arrayIndex:int -> unit + 1 overload
member Count : int
member Get<'T> : key:string -> 'T
member GetEnumerator : unit -> IEnumerator<KeyValuePair<string, obj>>
member IsFixedSize : bool
...
Full name: DotLiquid.Hash
--------------------
Hash() : unit
Hash(defaultValue: obj) : unit
Hash(lambda: Func<Hash,string,obj>) : unit
Hash.FromDictionary(dictionary: Collections.Generic.IDictionary<string,obj>) : Hash
val dict : keyValuePairs:seq<'Key * 'Value> -> Collections.Generic.IDictionary<'Key,'Value> (requires equality)
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.dict
val box : value:'T -> obj
Full name: Microsoft.FSharp.Core.Operators.box
type Task =
{What: string;}
Full name: Script.Task
Task.What: string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
type Person =
{Name: string;
Tasks: seq<Task>;}
Full name: Script.Person
Person.Name: string
Person.Tasks: seq<Task>
val t : (string -> Person -> string)
Full name: Script.t
val app : obj
Full name: Script.app
More information