CSS
It's high time we added some CSS styles to our HTML markup.
We'll not deep-dive into the details about the styles itself, as this is not a tutorial on Web Design.
The stylesheet can be downloaded from here in its final shape.
Place the Site.css
stylesheet in the root directory of the project, and manually add following to the SuaveMusicStore.fsproj
, inside <ItemGroup>
element:
<Content Include="Site.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Note: Specifying
CopyToOutputDirectory
element withPreserveNewest
value makes sure the stylesheet is accessible after the program has been compiled.
In order to include the stylesheet in our HTML markup, let's add the following to our View
:
View.fs
5: 6: 7: 8: 9: 10: 11: 12: |
|
This enables us to output the link HTML element with href
attribute pointing to the CSS stylesheet.
The CSS depends on logo.png
asset, which can be downloaded from here.
Again, place the logo.png
in root directory, and add an entry to fsproj:
<Content Include="logo.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
A browser, when asked to include a CSS file, sends back a request to the server with the given url. In similar fashion, when the browser wants to render an image asset, it needs to GET it from the server.
If we have a look at our main WebPart
we'll notice that there's really no handler capable of serving this file.
That's why we need to add another alternative to our choose
WebPart
:
App.fs
23:
|
|
The pathRegex
WebPart
returns Some
if an incoming request specifies path matching the regular expression pattern.
If that's the case, the Files.browseHome
WebPart will be applied.
The given pattern matches every file with either .css
or .png
extension, which protects us from accessing other (e.g. binary or config) files.
Files.browseHome
is a WebPart
from Suave that serves static files from the root application directory.
Now you should be able to see the styles applied to our HTML markup.
Full name: SuaveMusicStore.Path.IntPath
type PrintfFormat<'Printer,'State,'Residue,'Result> =
new : value:string -> PrintfFormat<'Printer,'State,'Residue,'Result>
member Value : string
Full name: Microsoft.FSharp.Core.PrintfFormat<_,_,_,_>
--------------------
type PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple> =
inherit PrintfFormat<'Printer,'State,'Residue,'Result>
new : value:string -> PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple>
Full name: Microsoft.FSharp.Core.PrintfFormat<_,_,_,_,_>
--------------------
new : value:string -> PrintfFormat<'Printer,'State,'Residue,'Result>
--------------------
new : value:string -> PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple>
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
Full name: Microsoft.FSharp.Core.unit
Full name: SuaveMusicStore.Path.home
from SuaveMusicStore.Path
Full name: SuaveMusicStore.Path.Store.overview
Full name: SuaveMusicStore.Path.Store.browse
Full name: SuaveMusicStore.Path.Store.details
from Suave
Full name: SuaveMusicStore.View.cssLink
Full name: Suave.Html.link
Full name: SuaveMusicStore.View.index
Full name: Suave.Html.html
Full name: Suave.Html.head
Full name: Suave.Html.title
Full name: Suave.Html.body
Full name: Suave.Html.div
Full name: Suave.Html.tag
Full name: Suave.Html.a
from SuaveMusicStore
Full name: Suave.Html.htmlToString
from SuaveMusicStore
from Suave
from Suave
from Suave
from Suave
from Suave
Full name: SuaveMusicStore.App.browse
Full name: Suave.Http.request
Full name: Suave.Successful.OK
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
Full name: Suave.RequestErrors.BAD_REQUEST
Full name: SuaveMusicStore.App.webPart
Full name: Suave.WebPart.choose
Full name: Suave.Filters.path
from SuaveMusicStore
Full name: Suave.Filters.pathScan
Full name: SuaveMusicStore.Path.Store.details
Full name: Suave.Filters.pathRegex
from Suave
Full name: Suave.Files.browseHome
Full name: Suave.Web.startWebServer
Full name: Suave.Web.defaultConfig
Show code from this section on GitHub