Safe Haskell | None |
---|---|
Language | Haskell98 |
Utility functions for using Fay from a Yesod application.
This module is intended to be used from your Yesod application, not from your Fay programs.
We assume a specific file structure, namely that there is a fay
folder
containing client-side code, and fay-shared
containing code to be used by
both the client and server.
The Fay.Yesod
module (part of this package) is
required by both client and server code. However, since Fay does not
currently have package management support, we use a bit of a hack: the TH
calls in this package will automatically create the necessary
fay/Fay/Yesod.hs
file. Ultimately, we will use a more elegant
solution.
In the future, if this package proves popular enough, Fay support will likely be built into the scaffolding. In the meantime, you must manually integrate it. In order to take advantage of this module, you should modify your Yesod application as follows:
- Modify your
cabal
file to include thefay-shared
folder when compiling. This can be done by adding ahs-source-dirs: ., fay-shared
line to your library section. - Create the module
SharedTypes
infay-shared
and create aCommand
datatype. For an example of what this file should look like, see https://github.com/snoyberg/yesod-fay/blob/master/sample/fay-shared/SharedTypes.hs. - Add the function
fayFile
to yourImport
module. See https://github.com/snoyberg/yesod-fay/blob/master/sample/Import.hs for an example. - Add a new route at for the Fay subsite. Generally, it will look like
/fay-command FaySiteR FaySite getFaySite
. - Import the
SharedTypes
andYesod.Fay
modules into yourFoundation.hs
module. Add an instance ofYesodFay
for your application. You should set theYesodFayCommand
associated type to theCommand
datatype you created. (You may also need to add aYesodJquery
instance.) Note that this instance must appear after yourparseRoutes
. Set the methodfayRoute
toFaySiteR
(or whatever you called the subsite route), and implementyesodFayCommand
. It will generally look something likeyesodFayCommand render command = case command of { ... }
. - In order to use Fay, add
$(fayFile "MyModule")
to a widget, and then write the correspondingfay/MyModule.hs
file. For an example, see https://github.com/snoyberg/yesod-fay/blob/master/sample/fay/Home.hs.
- class YesodJquery master => YesodFay master where
- yesodFayCommand :: CommandHandler master
- fayRoute :: Route FaySite -> Route master
- fayEncode :: Data a => master -> a -> Maybe Value
- data YesodFaySettings = YesodFaySettings {
- yfsModuleName :: String
- yfsSeparateRuntime :: Maybe (FilePath, Exp)
- yfsPostProcess :: String -> IO String
- yfsExternal :: Maybe (FilePath, Exp)
- yfsRequireJQuery :: Bool
- yfsPackages :: [String]
- yfsTypecheckDevel :: Bool
- yesodFaySettings :: String -> YesodFaySettings
- fayFileProd :: YesodFaySettings -> Q Exp
- fayFileReload :: YesodFaySettings -> Q Exp
- fayFileProdWithConfig :: (Config -> Config) -> YesodFaySettings -> Q Exp
- fayFileReloadWithConfig :: Name -> YesodFaySettings -> Q Exp
- type FayFile = String -> Q Exp
- type CommandHandler master = forall s. (forall a. Data a => Returns a -> a -> HandlerT master IO s) -> Value -> HandlerT master IO s
- data Returns a
- data FaySite
- getFaySite :: a -> FaySite
- data family Route a
- class YesodJquery a where
- urlJqueryJs :: a -> Either (Route a) Text
- urlJqueryUiJs :: a -> Either (Route a) Text
- urlJqueryUiCss :: a -> Either (Route a) Text
- urlJqueryUiDateTimePicker :: a -> Either (Route a) Text
Typeclass
class YesodJquery master => YesodFay master where Source
Type class for applications using Fay.
We depend on YesodJquery
since the generated client-side code uses jQuery
for making Ajax calls. We have an associated type stating the command
datatype. Since this datatype must be used by both the client and server,
you should place its definition in the fay-shared
folder.
yesodFayCommand :: CommandHandler master Source
User-defined function specifying how to respond to commands. Using the above datatype, this might look like:
yesodFayCommand render command = case command of GetFib index r = render r $ fibs !! index
fayRoute :: Route FaySite -> Route master Source
Where in the routing tree our Fay subsite is located. This is
generally named FaySiteR
, e.g.:
mkYesod "YourSite" [parseRoutes ... /fay-command FaySiteR FaySite getFaySite |] instance YesodFay YourSite where fayRoute = FaySiteR
fayEncode :: Data a => master -> a -> Maybe Value Source
User-defined function specifying how to encode data as json for fay.
Most users won't need to define this, the default is const showToFay
.
Custom definitions will usually be in terms of encodeFay
.
data YesodFaySettings Source
A setttings data type for indicating whether the generated Javascript should contain a copy of the Fay runtime or not.
YesodFaySettings | |
|
Include Fay programs
fayFileProd :: YesodFaySettings -> Q Exp Source
Does a full compile of the Fay code via GHC for type checking, and then embeds the Fay-generated Javascript as a static string. File changes during runtime will not be reflected.
fayFileReload :: YesodFaySettings -> Q Exp Source
Performs no type checking on the Fay code. Each time the widget is requested, the Fay code will be compiled from scratch to Javascript.
fayFileProdWithConfig :: (Config -> Config) -> YesodFaySettings -> Q Exp Source
Like fayFileProd
, but also takes a function so that the fay
configuration can be modified.
Since 0.6.1
fayFileReloadWithConfig :: Name -> YesodFaySettings -> Q Exp Source
Like fayFileReload
, but also takes the name of a function used
to modify the fay configuration can be modified. The type of this
function is expected to be (Config -> Config)
.
Since 0.6.1
type FayFile = String -> Q Exp Source
A function that takes a String giving the Fay module name, and returns an
TH splice that generates a Widget
.
Commands
type CommandHandler master = forall s. (forall a. Data a => Returns a -> a -> HandlerT master IO s) -> Value -> HandlerT master IO s Source
A function provided by the developer describing how to answer individual commands from client-side code.
Due to restrictions of the type system in Fay, we use a relatively simple
approach for encoding the return type. In order to specify this, an extra
parameter- Returns
- is passed around, with a phantom type variable stating
the expected return type.
The first argument to your function is the "respond" function: it takes
the extra Returns
parameter as well as the actual value to be returned,
and produces the expected result.
A proxy type for specifying what type a command should return. The final
field for each data constructor in a command datatype should be Returns
.
Subsite
The Fay subsite.
RenderRoute FaySite | |
ParseRoute FaySite | |
RouteAttrs FaySite | |
YesodFay master => YesodSubDispatch FaySite (HandlerT master IO) | |
Eq (Route FaySite) | |
Read (Route FaySite) | |
Show (Route FaySite) | |
data Route FaySite = FayCommandR |
getFaySite :: a -> FaySite Source
To be used from your routing declarations.
data family Route a
The type-safe URLs associated with a site argument.
RedirectUrl master (Route master) | |
((~) * key Text, (~) * val Text) => RedirectUrl master (Route master, [(key, val)]) | |
((~) * key Text, (~) * val Text) => RedirectUrl master (Route master, Map key val) | |
Eq (Route LiteApp) | |
Eq (Route WaiSubsite) | |
Eq (Route Static) | |
Eq (Route FaySite) | |
Ord (Route LiteApp) | |
Ord (Route WaiSubsite) | |
Read (Route LiteApp) | |
Read (Route WaiSubsite) | |
Read (Route Static) | |
Read (Route FaySite) | |
Show (Route LiteApp) | |
Show (Route WaiSubsite) | |
Show (Route Static) | |
Show (Route FaySite) | |
data Route LiteApp = LiteAppRoute [Text] | |
data Route WaiSubsite = WaiSubsiteRoute [Text] [(Text, Text)] | |
data Route Static = StaticRoute [Text] [(Text, Text)] | |
data Route FaySite = FayCommandR |
Reexports
class YesodJquery a where
Nothing
urlJqueryJs :: a -> Either (Route a) Text
The jQuery Javascript file. Note that in upgrades to this library, the version of jQuery referenced, or where it is downloaded from, may be changed without warning. If you are relying on a specific version of jQuery, you should give an explicit URL instead of relying on the default value.
Currently, the default value is jQuery 1.7 from Google's CDN.
urlJqueryUiJs :: a -> Either (Route a) Text
The jQuery UI 1.8 Javascript file.
urlJqueryUiCss :: a -> Either (Route a) Text
The jQuery UI 1.8 CSS file; defaults to cupertino theme.
urlJqueryUiDateTimePicker :: a -> Either (Route a) Text
jQuery UI time picker add-on.