Using Sitelet.Infer allows you to do exactly that. Here is an example with three action schemes with zero, one and two parameters respectively:

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
open IntelliFactory.WebSharper.Sitelets

type Action =
    | Index
    | Stats of username: string
    | Article of id: int * slug: string

type MyWebsite() =
    interface IWebsite<Action> with
        member this.Sitelet =
            Sitelet.Infer <| function
                | Index ->
                    // Content of the index page
                    Content.PageContent <| fun ctx ->
                        { Page.Default with
                            Body = [Text "Index page"] }
                | Stats username ->
                    // Content of the stats page, which depends on the username
                    Content.PageContent <| fun ctx ->
                        { Page.Default with
                            Body = [Text ("Stats for " + username)] }
                | Article (id, slug) ->
                    // Content of the article page, which depends on id and slug
                    Content.PageContent <| fun ctx ->
                        { Page.Default with
                            Body = [Text (sprintf "Article id %i, slug %s" id slug)] }

        member this.Actions = []

[<assembly: WebsiteAttribute(typeof<MyWebsite>)>]
do ()

The above website has urls such as:

1
2
3
/Index
/Stats/my_username
/Article/142/some-article-slug

They get automatically parsed by Sitelet.Infer into the corresponding Action value and passed to the function it receives.

By on 9/5/2014 6:16 AM ()

I'm playing around a bit with the Sitelet module.

It's worth noting that Sitelet.Infer doesn't by itself handle a request to the root url.So you need to use Sitelet.Sum? Building off your example, something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
type MyWebsite() =
    // Content of the index page
    let IndexContent = Content.PageContent <| fun ctx ->
        { Page.Default with
            Body = [Text "Index page"] }
    interface IWebsite<Action> with
        member this.Sitelet =
            Sitelet.Sum [
                Sitelet.Content "/" <| IndexContent 
                Sitelet.Infer <| function
                    | Index -> IndexContent 
                    | Stats username ->
                        // Content of the stats page, which depends on the username
                        Content.PageContent <| fun ctx ->
                            { Page.Default with
                                Body = [Text ("Stats for " + username)] }
                    | Article (id, slug) ->
                        // Content of the article page, which depends on id and slug
                        Content.PageContent <| fun ctx ->
                            { Page.Default with
                               Body = [Text (sprintf "Article id %i, slug %s" id slug)] }
            ]
By on 9/5/2014 8:22 PM ()

Sitelet.Sum is one way to do it, yes.

Another way is to use [<CompiledName "">]. The attribute CompiledName can be added to a case of your action union to change the corresponding url string, like this:

1
2
3
4
type Action =
    | [<CompiledName "">] Index
    | [<CompiledName "stats">] Stats of string
    | Article of int * string

If you use Sitelet.Infer with the above action type, then the following URLs are parsed:

1
2
3
/                  --> Index
/stats/xxx         --> Stats "xxx"
/Article/123/xxx   --> Article (123, "xxx")

If you want both / and /Index to point to Index, then you'll need Sitelet.Sum.

By on 9/6/2014 8:41 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper