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 (from afBedSheetEfanExtra).
  • Chg: Reanmed EfanPageMeta to RenderPageMeta.
  • Chg: Renamed PageRoute to PageUri.

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