Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
dustinmoris committed Dec 22, 2017
2 parents f2a36e4 + 246cdd2 commit 57d2b6f
Show file tree
Hide file tree
Showing 14 changed files with 331 additions and 62 deletions.
22 changes: 14 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ The old NuGet package has been unlisted and will no longer receive any updates.
- [html](#html)
- [renderHtml](#renderhtml)
- [redirectTo](#redirectto)
- [portRoute](#portroute)
- [routePorts](#routeports)
- [warbler](#warbler)
- [StatusCode HttpHandlers](#statuscode-httphandlers)
- [Intermediate](#intermediate)
Expand Down Expand Up @@ -442,17 +442,19 @@ The following format placeholders are currently supported:
- `%i` for int32
- `%d` for int64 (this is custom to Giraffe)
- `%f` for float/double
- `%O` for Guid

#### Example:

```fsharp
let app =
choose [
route "/foo" >=> text "Foo"
routef "/bar/%s/%i" (fun (name, age) ->
routef "/bar/%s/%i/%O" (fun (name, age, id) ->
// name is of type string
// age is of type int
text (sprintf "Name: %s, Age: %i" name age))
// id is of type Guid
text (sprintf "Name: %s, Age: %i, Id: %O" name age id))
]
```

Expand Down Expand Up @@ -847,6 +849,7 @@ Create a function that accepts a model and returns an `XmlNode`:

```fsharp
open Giraffe.GiraffeViewEngine
open Giraffe.GiraffeViewEngine.Attributes
let model = { Name = "John Doe" }
Expand All @@ -863,8 +866,9 @@ let partial () =
let personView model =
[
div [] [
h3 [] (sprintf "Hello, %s" model.Name |> encodedText)
div [_class "container"] [
h3 [_title "Some title attribute"] (sprintf "Hello, %s" model.Name |> encodedText)
a [_href "https://github.com/giraffe-fsharp/Giraffe"] [encodedText "Github"]
]
div [] [partial()]
] |> layout
Expand All @@ -875,6 +879,8 @@ let app =
]
```

Notice that attributes (from `Giraffe.GiraffeViewEngine.Attributes`) are prefixed with an underscore (_) to prevent naming collisions.

### redirectTo

`redirectTo` uses a 302 or 301 (when permanent) HTTP response code to redirect the client to the specified location. It takes in two parameters, a boolean flag denoting whether the redirect should be permanent or not and the location to redirect to.
Expand All @@ -890,9 +896,9 @@ let app =
]
```

### portRoute
### routePorts

If your web server is listening to multiple ports through `WebHost.UseUrls` then you can use the `portRoute` HttpHandler to easily filter incoming requests based on their port by providing a list of port number and HttpHandler (`(int * HttpHandler) list`).
If your web server is listening to multiple ports through `WebHost.UseUrls` then you can use the `routePorts` HttpHandler to easily filter incoming requests based on their port by providing a list of port number and HttpHandler (`(int * HttpHandler) list`).

#### Example
```fsharp
Expand All @@ -911,7 +917,7 @@ let app9002 =
]
]
let app = portRoute [
let app = routePorts [
(9001, app9001)
(9002, app9002)
]
Expand Down
17 changes: 17 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
Release Notes
=============

## 0.1.0-beta 700

#### Breaking changes

- Renamed `portRoute` to `routePorts` to be more consistent with other routing functions (`route`, `routef`, `routeStartsWith`, etc.)

#### New features

- `routef` and `routeCif` both support `%O` for matching `System.Guid` values now
- Added HTML attributes helper functions to the `GiraffeViewEngine`.

Example:

```fsharp
let html = p [ _class "someCssClass"; _id "greetingsText" ] [ encodedText "Hello World" ]
```

## 0.1.0-beta-600

#### Breaking changes
Expand Down
26 changes: 13 additions & 13 deletions samples/IdentityApp/IdentityApp/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -38,50 +38,50 @@ let masterPage (pageTitle : string) (content : XmlNode list) =
let indexPage =
[
p [] [
a [ attr "href" "/register" ] [ rawText "Register" ]
a [ _href "/register" ] [ rawText "Register" ]
]
p [] [
a [ attr "href" "/user" ] [ rawText "User page" ]
a [ _href "/user" ] [ rawText "User page" ]
]
] |> masterPage "Home"

let registerPage =
[
form [ attr "action" "/register"; attr "method" "POST" ] [
form [ _action "/register"; _method "POST" ] [
div [] [
label [] [ rawText "Email:" ]
input [ attr "name" "Email"; attr "type" "text" ]
input [ _name "Email"; _type "text" ]
]
div [] [
label [] [ rawText "User name:" ]
input [ attr "name" "UserName"; attr "type" "text" ]
input [ _name "UserName"; _type "text" ]
]
div [] [
label [] [ rawText "Password:" ]
input [ attr "name" "Password"; attr "type" "password" ]
input [ _name "Password"; _type "password" ]
]
input [ attr "type" "submit" ]
input [ _type "submit" ]
]
] |> masterPage "Register"

let loginPage (loginFailed : bool) =
[
if loginFailed then yield p [ attr "style" "color: Red;" ] [ rawText "Login failed." ]
if loginFailed then yield p [ _style "color: Red;" ] [ rawText "Login failed." ]

yield form [ attr "action" "/login"; attr "method" "POST" ] [
yield form [ _action "/login"; _method "POST" ] [
div [] [
label [] [ rawText "User name:" ]
input [ attr "name" "UserName"; attr "type" "text" ]
input [ _name "UserName"; _type "text" ]
]
div [] [
label [] [ rawText "Password:" ]
input [ attr "name" "Password"; attr "type" "password" ]
input [ _name "Password"; _type "password" ]
]
input [ attr "type" "submit" ]
input [ _type "submit" ]
]
yield p [] [
rawText "Don't have an account yet?"
a [ attr "href" "/register" ] [ rawText "Go to registration" ]
a [ _href "/register" ] [ rawText "Go to registration" ]
]
] |> masterPage "Login"

Expand Down
2 changes: 2 additions & 0 deletions samples/SampleApp/SampleApp.Tests/Program.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module Program
let [<EntryPoint>] main _ = 0
1 change: 1 addition & 0 deletions samples/SampleApp/SampleApp.Tests/SampleApp.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

<ItemGroup>
<Compile Include="Tests.fs" />
<Compile Include="Program.fs" />
</ItemGroup>

</Project>
5 changes: 3 additions & 2 deletions samples/SampleApp/SampleApp/HtmlViews.fs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ let partial () =

let personView (model : Person) =
[
div [] [
h3 [] [ sprintf "Hello, %s" model.Name |> encodedText ]
div [_class "container"] [
h3 [_title "Some title attribute"] [ sprintf "Hello, %s" model.Name |> encodedText ]
a [_href "https://github.com/giraffe-fsharp/Giraffe"] [encodedText "Github"]
]
div [] [partial()]
] |> layout
7 changes: 6 additions & 1 deletion src/Giraffe/FormatExpressions.fs
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
module Giraffe.FormatExpressions

open System
open System.Text.RegularExpressions
open System.Net
open Microsoft.FSharp.Reflection
open FSharp.Core

let formatStringMap =
let guidFormatStr =
"(([0-9A-Fa-f]{8}\-[0-9A-Fa-f]{4}\-[0-9A-Fa-f]{4}\-[0-9A-Fa-f]{4}\-[0-9A-Fa-f]{12})|([0-9A-Fa-f]{32}))"

dict [
// Char Regex Parser
// ----------------------------------------------------------
// -------------------------------------------------------------
'b', ("(?i:(true|false)){1}", bool.Parse >> box) // bool
'c', ("(.{1})", char >> box) // char
's', ("(.+)", WebUtility.UrlDecode >> box) // string
'i', ("(-?\d+)", int32 >> box) // int
'd', ("(-?\d+)", int64 >> box) // int64
'f', ("(-?\d+\.{1}\d+)", float >> box) // float
'O', (guidFormatStr, Guid >> box) // Guid
]

let convertToRegexPatternAndFormatChars (formatString : string) =
Expand Down
2 changes: 1 addition & 1 deletion src/Giraffe/Giraffe.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<AssemblyName>Giraffe</AssemblyName>
<Version>0.1.0-beta-600</Version>
<Version>0.1.0-beta-700</Version>
<Description>A native functional ASP.NET Core web framework for F# developers.</Description>
<Copyright>Copyright 2017 Dustin Moris Gorski</Copyright>
<NeutralLanguage>en-GB</NeutralLanguage>
Expand Down
111 changes: 111 additions & 0 deletions src/Giraffe/GiraffeViewEngine.fs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,117 @@ let menu = tag "menu"
let menuitem = voidTag "menuitem"
let summary = tag "summary"

/// ---------------------------
/// Default HTML attributes
/// ---------------------------
[<AutoOpen>]
module Attributes =
// https://www.w3.org/TR/html5/index.html#attributes-1
let _abbr = attr "abbr"
let _accept = attr "accept"
let _acceptCharset = attr "accept-charset"
let _accesskey = attr "accesskey"
let _action = attr "action"
let _alt = attr "alt"
let _autocomplete = attr "autocomplete"
let _border = attr "border"
let _challenge = attr "challenge"
let _charset = attr "charset"
let _cite = attr "cite"
let _class = attr "class"
let _cols = attr "cols"
let _colspan = attr "colspan"
let _content = attr "content"
let _contenteditable = attr "contenteditable"
let _coords = attr "coords"
let _crossorigin = attr "crossorigin"
let _data = attr "data"
let _datetime = attr "datetime"
let _dir = attr "dir"
let _dirname = attr "dirname"
let _download = attr "download"
let _enctype = attr "enctype"
let _for = attr "for"
let _form = attr "form"
let _formaction = attr "formaction"
let _formenctype = attr "formenctype"
let _formmethod = attr "formmethod"
let _formtarget = attr "formtarget"
let _headers = attr "headers"
let _height = attr "height"
let _high = attr "high"
let _href = attr "href"
let _hreflang = attr "hreflang"
let _httpEquiv = attr "http-equiv"
let _id = attr "id"
let _keytype = attr "keytype"
let _kind = attr "kind"
let _label = attr "label"
let _lang = attr "lang"
let _list = attr "list"
let _low = attr "low"
let _manifest = attr "manifest"
let _max = attr "max"
let _maxlength = attr "maxlength"
let _media = attr "media"
let _mediagroup = attr "mediagroup"
let _method = attr "method"
let _min = attr "min"
let _minlength = attr "minlength"
let _name = attr "name"
let _optimum = attr "optimum"
let _pattern = attr "pattern"
let _placeholder = attr "placeholder"
let _poster = attr "poster"
let _preload = attr "preload"
let _rel = attr "rel"
let _rows = attr "rows"
let _rowspan = attr "rowspan"
let _sandbox = attr "sandbox"
let _spellcheck = attr "spellcheck"
let _scope = attr "scope"
let _shape = attr "shape"
let _size = attr "size"
let _sizes = attr "sizes"
let _span = attr "span"
let _src = attr "src"
let _srcdoc = attr "srcdoc"
let _srclang = attr "srclang"
let _start = attr "start"
let _step = attr "step"
let _style = attr "style"
let _tabindex = attr "tabindex"
let _target = attr "target"
let _title = attr "title"
let _translate = attr "translate"
let _type = attr "type"
let _usemap = attr "usemap"
let _value = attr "value"
let _width = attr "width"
let _wrap = attr "wrap"

let _async = flag "async"
let _autofocus = flag "autofocus"
let _autoplay = flag "autoplay"
let _checked = flag "checked"
let _controls = flag "controls"
let _default = flag "default"
let _defer = flag "defer"
let _disabled = flag "disabled"
let _formnovalidate = flag "formnovalidate"
let _hidden = flag "hidden"
let _ismap = flag "ismap"
let _loop = flag "loop"
let _multiple = flag "multiple"
let _muted = flag "muted"
let _novalidate = flag "novalidate"
let _readonly = flag "readonly"
let _required = flag "required"
let _reversed = flag "reversed"
let _selected = flag "selected"
let _typemustmatch = flag "typemustmatch"

/// ---------------------------
/// Render XML string
/// ---------------------------
Expand Down
6 changes: 4 additions & 2 deletions src/Giraffe/HttpHandlers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ let route (path : string) : HttpHandler =
/// %i -> int
/// %d -> int64
/// %f -> float/double
/// %O -> Guid
let routef (path : PrintfFormat<_,_,_,_, 'T>) (routeHandler : 'T -> HttpHandler) : HttpHandler =
validateFormat path
fun (next : HttpFunc) (ctx : HttpContext) ->
Expand All @@ -230,6 +231,7 @@ let routeCi (path : string) : HttpHandler =
/// %i -> int
/// %d -> int64
/// %f -> float/double
/// %O -> Guid
let routeCif (path : PrintfFormat<_,_,_,_, 'T>) (routeHandler : 'T -> HttpHandler) : HttpHandler =
validateFormat path
fun (next : HttpFunc) (ctx : HttpContext) ->
Expand Down Expand Up @@ -439,9 +441,9 @@ let redirectTo (permanent : bool) (location : string) : HttpHandler =
Task.FromResult (Some ctx)

/// Filters an incoming HTTP request based on the port.
let portRoute (fns : (int * HttpHandler) list) : HttpHandler =
let routePorts (fns : (int * HttpHandler) list) : HttpHandler =
fun next ->
let portMap = Dictionary<_,_>(fns.Length)
let portMap = Dictionary<_, _>(fns.Length)
fns |> List.iter (fun (p, h) -> portMap.Add(p, h next))
fun (ctx : HttpContext) ->
let port = ctx.Request.Host.Port
Expand Down
Loading

0 comments on commit 57d2b6f

Please sign in to comment.