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
@PageContentType
facet 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:
@InitRender
params could incorrectly match for directory index pages.
v0.0.6
- New: Page uris and BedSheet routes are generated from the
@InitRender
method signature. - New: Directory uris may now serve welcome pages.
- Chg: Updated to use
BedSheet 1.2
. - Chg: Renamed project to
afPillow
(fromafBedSheetEfanExtra
). - Chg: Reanmed
EfanPageMeta
toRenderPageMeta
. - Chg: Renamed
PageRoute
toPageUri
.
v0.0.4
- New: Added
@PageRoute
facet that lets you specify a bespoke uri - New: Added
EfanPageMeta
which returns the active rendering page.
v0.0.2
- New: Preview Release