PillowUser Guide
Overview
Pillow - Something for your web app to get its teeth into!
Pillow is a library for integrating efanXtra components with the BedSheet web framework. It automatically routes web requests to pages and returns the rendered response.
Install
Install afPillow with the Fantom Respository Manager:
C:\> fanr install -r http://repo.status302.com/fanr/ afPillow
To use in a Fantom project, add a dependency to its build.fan:
depends = ["sys 1.0", ..., "afPillow 0+"]
Quick Start
Example.efan:
Hello Mum! I'm <%= age %> years old!
Example.fan:
using afIoc
using afEfanXtra
using afPillow
// ---- The only class you need! ----
const mixin Example : Page {
  abstract Int age
  @InitRender
  Void initRender(Int age) {
    this.age = age
  }
}
// ---- Standard BedSheet Support Classes ----
class Main {
  Int main() {
    afBedSheet::Main().main([AppModule#.qname, "8069"])
  }
}
// SubModule only needed when running from a script
@SubModule { modules=[EfanXtraModule#, PillowModule#] }
class AppModule {
   // Contribution needed when running from a script
   @Contribute { serviceType=EfanTemplateDirectories# }
   static Void contributeEfanDirs(OrderedConfig config) {
      // Look for Example.efan in the same dir as this file
      config.add(`./`)
   }
}
Run the Example.fan script from the command line:
C:\> fan Example.fan Efan Library: 'app' has 1 page(s): Example : /example
Then point your browser at http://localhost:8069/example/42:
Hello Mum! I'm 42 years old!
Usage
To create a web page, define a const mixin that extends Page. Example:
using afPillow
const mixin Admin : Page {
  ...
}
Pages are efanXtra components and behave in exactly the same way.
Pillow will automatically route uris with your page name, to your page. Camel casing class names results in a / delimiter. Examples:
`/admin` --> Admin.fan `/admin/secret` --> AdminSecret.fan
Or you can use the @PageUri facet to define an explicit URI.
As seen in the Quick Start example, requests are automatically mapped to the @InitRender methods of your Pages, with uri segments mapped to @InitRender parameters. If the @InitRender method returns a BedSheet response, page rendering is aborted and the response object is processed instead. Example:
using afBedSheet
using afPillow
const mixin Example : Page {
  @InitRender
  Obj? initRender(Int age) {
    if (age > 69)
      return Redirect.movedTemporarily(`/too-old`)
    return null
  }
}
Welcome Pages
Pillow supports the routing of welcome pages, also known as directory pages.
If Pillow recieves a directory uri (a uri that ends in /slash/) then it renders a welcome page, which defaults to Index. Examples:
`/` --> Index.fan `/admin/` --> AdminIndex.fan
More can be read about directory urls in the article: Should Your URLs Point to the Directory or the Index Page?
Content Type
Page template files should use a double extension in their name, for example,
IndexPage.xhtml.slim
The outer extension denotes the type of templating to use, Slim in our example. The innter extension is used to find the Content-Type that is sent in the HTTP response header. In our example, the Content-Type would be set to  application/xhtml+xml.
If a double extension is not used, or not know, then the default content type, as defined by the config value, is used.
Use the @PageContentType facet to explicitly set the content type.
Release Notes
v0.0.8
- New: Use the @PageContentTypefacet to explicitly define the content type for your page.
- New: Use a double extension (e.g. indexPage.xhtml.slim) to set the content type for the page.
- Bug: @InitRenderparams could incorrectly match for directory index pages.
v0.0.6
- New: Page uris and BedSheet routes are generated from the @InitRendermethod signature.
- New: Directory uris may now serve welcome pages.
- Chg: Updated to use BedSheet 1.2.
- Chg: Renamed project to afPillow(fromafBedSheetEfanExtra).
- Chg: Reanmed EfanPageMetatoRenderPageMeta.
- Chg: Renamed PageRoutetoPageUri.
v0.0.4
- New: Added @PageRoutefacet that lets you specify a bespoke uri
- New: Added EfanPageMetawhich returns the active rendering page.
v0.0.2
- New: Preview Release