yesod-static-1.2.2: Static file serving subsite for Yesod Web Framework.

Safe HaskellNone




A subsite which serves static content which is embedded at compile time.

At compile time, you supply a list of files, directories, processing functions (like javascript minification), and even custom content generators. You can also specify the specific relative locations within the static subsite where these resources should appear. The mkEmbeddedStatic function then computes the resources and embeds them directly into the executable at compile time, so that the original files do not need to be distributed along with the executable. The content is also compressed and hashed at compile time, so that during runtime the compressed content can be sent directly on the wire with the appropriate HTTP header. The precomputed hash is used for an ETag so the client does not redownload the content multiple times. There is also a development mode which does not embed the contents but recomputes it on every request. A simple example using an embedded static subsite is static-embed.hs.

To add this to a scaffolded project, replace the code in Settings/StaticFiles.hs with a call to mkEmbeddedStatic with the list of all your generators, use the type EmbeddedStatic in your site datatype for getStatic, update the route for /static to use the type EmbeddedStatic, use embedStaticContent for addStaticContent in Foundation.hs, use the routes generated by mkEmbeddedStatic and exported by Settings/StaticFiles.hs to link to your static content, and finally update Application.hs use the variable binding created by mkEmbeddedStatic which contains the created EmbeddedStatic.

It is recommended that you serve static resources from a separate domain to save time on transmitting cookies. You can use urlRenderOverride to do so, by redirecting routes to this subsite to a different domain (but the same path) and then pointing the alternative domain to this server. In addition, you might consider using a reverse proxy like varnish or squid to cache the static content, but the embedded content in this subsite is cached and served directly from memory so is already quite fast.



embeddedResourceR :: [Text] -> [(Text, Text)] -> Route EmbeddedStaticSource

Construct a route to an embedded resource.



:: Bool


-> String

variable name for the created EmbeddedStatic

-> [Generator]

the generators (see Yesod.EmbeddedStatic.Generators)

-> Q [Dec] 

Creates an EmbeddedStatic by running, at compile time, a list of generators. Each generator produces a list of entries to embed into the executable.

This template haskell splice creates a variable binding holding the resulting EmbeddedStatic and in addition creates variable bindings for all the routes produced by the generators. For example, if a directory called static has the following contents:

  • js/jquery.js
  • css/bootstrap.css
  • img/logo.png

then a call to

 #define DEV_BOOL True
 #define DEV_BOOL False
 mkEmbeddedStatic DEV_BOOL "myStatic" [embedDir "static"]

will produce variables

 myStatic :: EmbeddedStatic
 js_jquery_js :: Route EmbeddedStatic
 css_bootstrap_css :: Route EmbeddedStatic
 img_logo_png :: Route EmbeddedStatic



:: Yesod site 
=> (site -> EmbeddedStatic)

How to retrieve the embedded static subsite from your site

-> (Route EmbeddedStatic -> Route site)

how to convert an embedded static route

-> (ByteString -> Either a ByteString)

javascript minifier

-> AddStaticContent site 

Use this for addStaticContent to have the widget static content be served by the embedded static subsite. For example,

 import Yesod
 import Yesod.EmbeddedStatic
 import Text.Jasmine (minifym)

 data MySite = { ..., getStatic :: EmbeddedStatic, ... }

 mkYesod "MySite" [parseRoutes|
 /static StaticR EmbeddedStatic getStatic

 instance Yesod MySite where
     addStaticContent = embedStaticContent getStatic StaticR mini
         where mini = if development then Right else minifym