2 people like it.
Like the snippet!
Generate template definition
Instead of writing template instanciation by hand, this generate a Templates.fs file with all templates given a directory tree containing .html files.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
|
#r "./packages/FSharp.Management/lib/net40/FSharp.Management.dll"
#r @"./packages/FSharp.Core.Fluent-4.0\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1/FSharp.Core.Fluent-4.0.dll"
open System
open System.Linq
open FSharp.Core.Fluent.SeqExtensions
open FSharp.Management
open System.IO
let [<Literal>] solutionFolder = __SOURCE_DIRECTORY__ + "/./"
type fs = FileSystem< solutionFolder >
type templatesFolder = fs.WebApplication.Views
let rec getAllDescendants(directory: DirectoryInfo) =
seq {
let items = directory.GetFileSystemInfos()
let subDirectories = items.OfType<DirectoryInfo>()
yield! items
for subdir in subDirectories do
yield! getAllDescendants(subdir)
}
let getDirectoryDescendants(directory: DirectoryInfo) = getAllDescendants(directory).OfType<DirectoryInfo>()
let getFilesDescendants(directory: DirectoryInfo) = getAllDescendants(directory).OfType<FileInfo>()
let getNamespaceForFolder (folder: DirectoryInfo) =
let templatesFolderPath = ((new DirectoryInfo(templatesFolder.Path)).FullName)
let folderFullName = folder.FullName
if folderFullName.StartsWith(templatesFolderPath) then
let splits =
folderFullName.Substring(templatesFolderPath.Length).Split([|Path.DirectorySeparatorChar|], StringSplitOptions.RemoveEmptyEntries)
printfn "%A" splits
splits
else
[||]
let generate (baseFolder: DirectoryInfo) (baseNamespace: string array) (filename:string) =
let titleCase = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase
use underlying = new StreamWriter(filename)
use writer = new System.CodeDom.Compiler.IndentedTextWriter(underlying)
let write, indent, deindent =
(fun (t:string) -> writer.WriteLine(t))
, (fun () -> writer.Indent <- 1 + writer.Indent)
, (fun () -> writer.Indent <- -1 + writer.Indent)
let writef format = FSharp.Core.Printf.kprintf write format
let files =
getFilesDescendants baseFolder
|> Seq.groupBy (fun f -> f.Directory)
|> Seq.map (fun (d, files) -> getNamespaceForFolder d, files |> Seq.map (fun f -> f,f.Name) |> Seq.toArray)
|> Seq.toArray
|> Array.groupBy fst
|> Array.map (fun (g, files) -> g, files |> Array.map snd |> Array.concat)
for (ns, files) in files do
let ns =
Seq.concat [baseNamespace;ns]
|> Seq.map titleCase
|> String.concat "."
writef "namespace %s" ns
indent()
write "open WebSharper.UI.Next.Templating"
for (f, n) in files do
let n =
let splits = n.Split('.')
splits
|> Seq.truncate (splits.Length - 1)
|> Seq.map titleCase
|> String.concat ""
writef @"type %s = Template< @""%s"" >" n f.FullName
deindent()
underlying.Flush()
writer.Dispose()
let folder = DirectoryInfo(templatesFolder.Path)
generate folder [|"Templates"|] (fs.WebApplication.Code.``Templates.fs``)
|
namespace System
namespace System.Linq
Multiple items
namespace FSharp
--------------------
namespace Microsoft.FSharp
Multiple items
namespace FSharp.Core
--------------------
namespace Microsoft.FSharp.Core
namespace FSharp.Core.Fluent
module SeqExtensions
from FSharp.Core.Fluent
namespace FSharp.Management
namespace System.IO
Multiple items
type LiteralAttribute =
inherit Attribute
new : unit -> LiteralAttribute
Full name: Microsoft.FSharp.Core.LiteralAttribute
--------------------
new : unit -> LiteralAttribute
val solutionFolder : string
Full name: Script.solutionFolder
type fs = FileSystem<...>
Full name: Script.fs
type FileSystem
Full name: FSharp.Management.FileSystem
type templatesFolder = obj
Full name: Script.templatesFolder
val getAllDescendants : directory:DirectoryInfo -> seq<FileSystemInfo>
Full name: Script.getAllDescendants
val directory : DirectoryInfo
Multiple items
type DirectoryInfo =
inherit FileSystemInfo
new : path:string -> DirectoryInfo
member Create : unit -> unit + 1 overload
member CreateSubdirectory : path:string -> DirectoryInfo + 1 overload
member Delete : unit -> unit + 1 overload
member EnumerateDirectories : unit -> IEnumerable<DirectoryInfo> + 2 overloads
member EnumerateFileSystemInfos : unit -> IEnumerable<FileSystemInfo> + 2 overloads
member EnumerateFiles : unit -> IEnumerable<FileInfo> + 2 overloads
member Exists : bool
member GetAccessControl : unit -> DirectorySecurity + 1 overload
member GetDirectories : unit -> DirectoryInfo[] + 2 overloads
...
Full name: System.IO.DirectoryInfo
--------------------
DirectoryInfo(path: string) : unit
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<_>
val items : FileSystemInfo []
DirectoryInfo.GetFileSystemInfos() : FileSystemInfo []
DirectoryInfo.GetFileSystemInfos(searchPattern: string) : FileSystemInfo []
DirectoryInfo.GetFileSystemInfos(searchPattern: string, searchOption: SearchOption) : FileSystemInfo []
val subDirectories : Collections.Generic.IEnumerable<DirectoryInfo>
(extension) Collections.IEnumerable.OfType<'TResult>() : Collections.Generic.IEnumerable<'TResult>
val subdir : DirectoryInfo
val getDirectoryDescendants : directory:DirectoryInfo -> Collections.Generic.IEnumerable<DirectoryInfo>
Full name: Script.getDirectoryDescendants
val getFilesDescendants : directory:DirectoryInfo -> Collections.Generic.IEnumerable<FileInfo>
Full name: Script.getFilesDescendants
Multiple items
type FileInfo =
inherit FileSystemInfo
new : fileName:string -> FileInfo
member AppendText : unit -> StreamWriter
member CopyTo : destFileName:string -> FileInfo + 1 overload
member Create : unit -> FileStream
member CreateText : unit -> StreamWriter
member Decrypt : unit -> unit
member Delete : unit -> unit
member Directory : DirectoryInfo
member DirectoryName : string
member Encrypt : unit -> unit
...
Full name: System.IO.FileInfo
--------------------
FileInfo(fileName: string) : unit
val getNamespaceForFolder : folder:DirectoryInfo -> string []
Full name: Script.getNamespaceForFolder
val folder : DirectoryInfo
val templatesFolderPath : string
type Path =
static val DirectorySeparatorChar : char
static val AltDirectorySeparatorChar : char
static val VolumeSeparatorChar : char
static val InvalidPathChars : char[]
static val PathSeparator : char
static member ChangeExtension : path:string * extension:string -> string
static member Combine : [<ParamArray>] paths:string[] -> string + 3 overloads
static member GetDirectoryName : path:string -> string
static member GetExtension : path:string -> string
static member GetFileName : path:string -> string
...
Full name: System.IO.Path
val folderFullName : string
property FileSystemInfo.FullName: string
String.StartsWith(value: string) : bool
String.StartsWith(value: string, comparisonType: StringComparison) : bool
String.StartsWith(value: string, ignoreCase: bool, culture: Globalization.CultureInfo) : bool
val splits : string []
String.Substring(startIndex: int) : string
String.Substring(startIndex: int, length: int) : string
property String.Length: int
field Path.DirectorySeparatorChar
type StringSplitOptions =
| None = 0
| RemoveEmptyEntries = 1
Full name: System.StringSplitOptions
field StringSplitOptions.RemoveEmptyEntries = 1
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val generate : baseFolder:DirectoryInfo -> baseNamespace:string array -> filename:string -> unit
Full name: Script.generate
val baseFolder : DirectoryInfo
val baseNamespace : string array
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
type 'T array = 'T []
Full name: Microsoft.FSharp.Core.array<_>
val filename : string
val titleCase : (string -> string)
namespace System.Globalization
Multiple items
type CultureInfo =
new : name:string -> CultureInfo + 3 overloads
member Calendar : Calendar
member ClearCachedData : unit -> unit
member Clone : unit -> obj
member CompareInfo : CompareInfo
member CultureTypes : CultureTypes
member DateTimeFormat : DateTimeFormatInfo with get, set
member DisplayName : string
member EnglishName : string
member Equals : value:obj -> bool
...
Full name: System.Globalization.CultureInfo
--------------------
Globalization.CultureInfo(name: string) : unit
Globalization.CultureInfo(culture: int) : unit
Globalization.CultureInfo(name: string, useUserOverride: bool) : unit
Globalization.CultureInfo(culture: int, useUserOverride: bool) : unit
property Globalization.CultureInfo.CurrentCulture: Globalization.CultureInfo
property Globalization.CultureInfo.TextInfo: Globalization.TextInfo
Globalization.TextInfo.ToTitleCase(str: string) : string
val underlying : StreamWriter
Multiple items
type StreamWriter =
inherit TextWriter
new : stream:Stream -> StreamWriter + 6 overloads
member AutoFlush : bool with get, set
member BaseStream : Stream
member Close : unit -> unit
member Encoding : Encoding
member Flush : unit -> unit
member Write : value:char -> unit + 3 overloads
static val Null : StreamWriter
Full name: System.IO.StreamWriter
--------------------
StreamWriter(stream: Stream) : unit
StreamWriter(path: string) : unit
StreamWriter(stream: Stream, encoding: Text.Encoding) : unit
StreamWriter(path: string, append: bool) : unit
StreamWriter(stream: Stream, encoding: Text.Encoding, bufferSize: int) : unit
StreamWriter(path: string, append: bool, encoding: Text.Encoding) : unit
StreamWriter(path: string, append: bool, encoding: Text.Encoding, bufferSize: int) : unit
val writer : CodeDom.Compiler.IndentedTextWriter
namespace System.CodeDom
namespace System.CodeDom.Compiler
Multiple items
type IndentedTextWriter =
inherit TextWriter
new : writer:TextWriter -> IndentedTextWriter + 1 overload
member Close : unit -> unit
member Encoding : Encoding
member Flush : unit -> unit
member Indent : int with get, set
member InnerWriter : TextWriter
member NewLine : string with get, set
member Write : s:string -> unit + 12 overloads
member WriteLine : unit -> unit + 14 overloads
member WriteLineNoTabs : s:string -> unit
...
Full name: System.CodeDom.Compiler.IndentedTextWriter
--------------------
CodeDom.Compiler.IndentedTextWriter(writer: TextWriter) : unit
CodeDom.Compiler.IndentedTextWriter(writer: TextWriter, tabString: string) : unit
val write : (string -> unit)
val indent : (unit -> unit)
val deindent : (unit -> unit)
val t : string
CodeDom.Compiler.IndentedTextWriter.WriteLine() : unit
(+0 other overloads)
TextWriter.WriteLine(value: decimal) : unit
(+0 other overloads)
TextWriter.WriteLine(value: uint64) : unit
(+0 other overloads)
CodeDom.Compiler.IndentedTextWriter.WriteLine(value: uint32) : unit
(+0 other overloads)
CodeDom.Compiler.IndentedTextWriter.WriteLine(value: obj) : unit
(+0 other overloads)
CodeDom.Compiler.IndentedTextWriter.WriteLine(value: int64) : unit
(+0 other overloads)
CodeDom.Compiler.IndentedTextWriter.WriteLine(value: int) : unit
(+0 other overloads)
CodeDom.Compiler.IndentedTextWriter.WriteLine(value: float32) : unit
(+0 other overloads)
CodeDom.Compiler.IndentedTextWriter.WriteLine(value: float) : unit
(+0 other overloads)
CodeDom.Compiler.IndentedTextWriter.WriteLine(buffer: char []) : unit
(+0 other overloads)
property CodeDom.Compiler.IndentedTextWriter.Indent: int
val writef : (Printf.StringFormat<'a,unit> -> 'a)
val format : Printf.StringFormat<'a,unit>
module Printf
from Microsoft.FSharp.Core
val kprintf : continutation:(string -> 'Result) -> format:Printf.StringFormat<'T,'Result> -> 'T
Full name: Microsoft.FSharp.Core.Printf.kprintf
val files : (string [] * (FileInfo * string) []) []
module Seq
from Microsoft.FSharp.Collections
val groupBy : projection:('T -> 'Key) -> source:seq<'T> -> seq<'Key * seq<'T>> (requires equality)
Full name: Microsoft.FSharp.Collections.Seq.groupBy
val f : FileInfo
property FileInfo.Directory: DirectoryInfo
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>
Full name: Microsoft.FSharp.Collections.Seq.map
val d : DirectoryInfo
val files : seq<FileInfo>
property FileInfo.Name: string
val toArray : source:seq<'T> -> 'T []
Full name: Microsoft.FSharp.Collections.Seq.toArray
type Array =
member Clone : unit -> obj
member CopyTo : array:Array * index:int -> unit + 1 overload
member GetEnumerator : unit -> IEnumerator
member GetLength : dimension:int -> int
member GetLongLength : dimension:int -> int64
member GetLowerBound : dimension:int -> int
member GetUpperBound : dimension:int -> int
member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
member Initialize : unit -> unit
member IsFixedSize : bool
...
Full name: System.Array
val groupBy : projection:('T -> 'Key) -> array:'T [] -> ('Key * 'T []) [] (requires equality)
Full name: Microsoft.FSharp.Collections.Array.groupBy
val fst : tuple:('T1 * 'T2) -> 'T1
Full name: Microsoft.FSharp.Core.Operators.fst
val map : mapping:('T -> 'U) -> array:'T [] -> 'U []
Full name: Microsoft.FSharp.Collections.Array.map
val g : string []
val snd : tuple:('T1 * 'T2) -> 'T2
Full name: Microsoft.FSharp.Core.Operators.snd
val concat : arrays:seq<'T []> -> 'T []
Full name: Microsoft.FSharp.Collections.Array.concat
val ns : string []
val files : (FileInfo * string) []
val ns : string
val concat : sources:seq<#seq<'T>> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.concat
Multiple items
type String =
new : value:char -> string + 7 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 2 overloads
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
member GetHashCode : unit -> int
...
Full name: System.String
--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : unit
val concat : sep:string -> strings:seq<string> -> string
Full name: Microsoft.FSharp.Core.String.concat
val n : string
String.Split([<ParamArray>] separator: char []) : string []
String.Split(separator: string [], options: StringSplitOptions) : string []
String.Split(separator: char [], options: StringSplitOptions) : string []
String.Split(separator: char [], count: int) : string []
String.Split(separator: string [], count: int, options: StringSplitOptions) : string []
String.Split(separator: char [], count: int, options: StringSplitOptions) : string []
val truncate : count:int -> source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.truncate
property Array.Length: int
StreamWriter.Flush() : unit
TextWriter.Dispose() : unit
val folder : DirectoryInfo
Full name: Script.folder
More information