Skip to content

Latest commit

 

History

History
115 lines (75 loc) · 5.23 KB

TUTORIAL.md

File metadata and controls

115 lines (75 loc) · 5.23 KB

THIS TUTORIAL IS STILL WORK IN PROGRESS

Welcome

Welcome curious stranger. You have wandered into tutorial which aims to help you grasp the Snap and Heist Haskell modules via building a simple dynamic website.

Prerequisites

Knowledge

Modules

Apart from the basic and standard modules, you will need these:

Take a look at the pastie.cabal for details

Tools

You only need a text editor or IDE of your choice, GHC and cabal (I would presonally recommend cabal-dev).

Design Decisions

In this littel project, we will be abiding the rules of what is usually called the MVC architecture. The reason is simple -- it makes your code more modular and thus hopefully easier to reason about and maintain.

Disclaimer: These design decisions are in no way related to the Snap & Heist itself, you do not have to follow them in your projects.

Model

Model should provide API to retrieve and store data (in our case in database).

Our model resides in the src/Model directory. It's job is:

  • to communicate with a database (i.e. writing and reading),
  • to present data in suitable form to the controller.

Controller

Controller is the place where the application logic resides.

Our controller resides in the src/Controller directory. It's job is:

  • to manipulate the data it got from the model and prepare them to be presented to the user (e.g. retrieve a post),
  • to convert the data it got from users to suitable form for the model (e.g. handle a form).

In Snap & Heist terms, this is the place where we implement most of our splices (ideally all of them).

View

View is the mediator between application and the user.

Our view resides in the resources/templates directory. It's job is:

  • to display the data from controller to the user,
  • to provide an input facilities (e.g. a HTML form).

In Snap & Heist terms, the view consists of the Heist templates where we call the controller's splices.

Down to Bussines

Setting up MongoDB server

It's really easy! Just download the binary for your system and fire up the mongod daemon, that's it, you are set to go.

Installing the Extensions

In this section we will install the extensions we use in snap-pastie.

Setting up the Heist Extension

Working file: Application.hs

One of the strengths of Snap is its modularity and Heist is a proof of that. Heist is just an extension, meaning you could use templating engine or your choice (if such thing crossed your mind, it probably will not ever again after you learn more about Heist) or none at all, yet it seamlessly blends with Snap.

Setting up the MongoDB Extension

Working file: Application.hs

The Snap.Extension.MongoDB is Snap extension utilizing Snap's extension interface. It's installed analogicaly to any other Snap's extension.

First, we import the module of the extension:

import           Snap.Extension.DB.MongoDB

Then we make it part of our Application's state along with Heist:

data ApplicationState = ApplicationState
    { templateState :: HeistState Application
    , databaseState :: MongoDBState
    }

instance HasMongoDBState ApplicationState where
    getMongoDBState     = databaseState
    setMongoDBState s a = a { databaseState = s }

And finally call the extension's initializer in the application's initializer:

applicationInitializer :: Initializer ApplicationState
applicationInitializer = do
    heist <- heistInitializer "resources/templates"
    database <- mongoDBInitializer (Host "127.0.0.1" $ PortNumber 27017) 1 "pastie"
    return $ ApplicationState heist database

database <- mongoDBInitializer (Host "127.0.0.1" $ PortNumber 27017) 1 "pastie"

That line tells the MongoDB extension, that the database server is hosted on 127.0.0.1 and listening on port 27017 (which is the standard one)

Making the Model