comment
We are happy to announce the release of Bolero version 0.14. Bolero is a library that enables writing full-stack applications in F#, whose client side runs in WebAssembly using Blazor.
This release requires the .NET Core SDK version 3.1.300 or newer, which you can download here for Windows, OSX or Linux.
Install the latest project template with:
1
dotnet new -i Bolero.Templates::0.14.13
Changes
#135 Inferred router performs URL encoding/decoding on
string
-typed parameters.1 2 3 4 5 6 7
type Page = | [<EndPoint "/article/{slug}">] Article of slug: string let router = Router.infer SetPage (fun model -> model.page) router.Link (Article "Déjà-vu") = "/article/D%C3%A9j%C3%A0-vu"
#151 Accept either a relative or absolute path in custom router's
getRoute
.#155 Add function
fragment
to create a BoleroNode
from a BlazorRenderFragment
.This enables creating components that take fragments as parameters:
1 2 3 4 5 6 7 8 9 10 11 12 13
type Input() = inherit Component() [<Parameter>] member val Label = Unchecked.defaultof<RenderFragment> with get, set override this.Render() = label [] [ fragment this.Label input [] ] let myInput = comp<Input> [attr.fragment "Label" (div [] [text "My input"])] []
In particular, a
RenderFragment
parameter namedChildContent
defines the children of the component, ie. the content passed as second argument tocomp
.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
type Panel() = inherit Component() [<Parameter>] member val ChildContent = Unchecked.defaultof<RenderFragment> with get, set [<Parameter>] member val Title = "" with get, set override this.Render() = div [attr.classes ["panel"]] [ h1 [attr.classes ["panel-title"]] [ text this.Title ] div [attr.classes ["panel-body"]] [ fragment this.ChildContent ] ] let myPanel = comp<Panel> ["Title" => "Welcome to Bolero"] [ text "Let's learn about " a [attr.href "https://fsbolero.io"] [text "Bolero"] text "!" ]
#159 Breaking change: Remove the module
Bolero.Json
, and use System.Text.Json together with FSharp.SystemTextJson instead for remoting.Remoting serialization can be customized by passing an additional argument
configureSerialization: JsonSerializerOptions -> unit
toservices.AddRemoting()
in both the server-side and client-side startup functions.Client-side:
1 2 3 4 5 6 7 8 9 10 11 12
open System.Text.Json.Serialization [<EntryPoint>] let Main args = let builder = WebAssemblyHostBuilder.CreateDefault(args) builder.Services.AddRemoting(builder.HostEnvironment, fun serializerOptions -> JsonFSharpConverter(JsonUnionEncoding.ThothLike) |> serializerOptions.Converters.Add ) |> ignore // ...
Server-side:
1 2 3 4 5 6 7 8 9 10 11
open System.Text.Json.Serialization type Startup() = member this.ConfigureServices(services: IServiceCollection) = services.AddRemoting<MyRemoteService>(fun serializerOptions -> JsonFSharpConverter(JsonUnionEncoding.ThothLike) |> serializerOptions.Converters.Add ) |> ignore // ...
Happy coding!