This is part 2 of a series where we develop a file hosting web application. In the previous entry everything was contained within a single source file, but the final application will be too large for this. We will also want the flexibility of separating the web content from the service itself. # Branching Out Let's start by splitting our source code into separate files. Our final application will have 3 routes and 2 pages. It will be natural to place the program logic for handling these in their own source files. Our directory structure will look as follows: ``` Main.hs Foundation.hs Dispatch.hs Handler/Home.hs config/routes templates/home.hamlet ``` All of the markup we create will go into the "templates" folder. The "Handler" folder will contain a single file for each of our 3 routes. Our application will need to perform a few initializations as it starts, and these will go in "Main.hs". The "Foundation.hs" module will house a few data structures and functions to keep track of uploaded files. ## Separate Markup from Source Code I want us to be in the position where we can make changes to web content without touching any source code. Each page will have its own templates for HTML, CSS, and JavaScript. We'll group these together by giving them the same name, but ending with different file extensions. There are helper functions in the Yesod.Default.Util module that will know how to load and combine them correctly. Place your templates in a folder named "templates". ``` active haskell web {-# START_FILE Main.hs #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} module Main where {-hi-}import Data.Default{-/hi-} import Yesod {-hi-}import Yesod.Default.Util{-/hi-} data App = App instance Yesod App -- mkYesod "App" [parseRoutes| -- / HomeR GET -- |] {-hi-}mkYesod "App" $(parseRoutesFile "config/routes"){-/hi-} getHomeR :: Handler Html getHomeR = defaultLayout $ do let filenames = ["readme.txt", "report.pdf", "music.wav"] :: [String] setTitle "File Processor" -- toWidget [whamlet| --

Previously submitted files -- $if null filenames --

No files have been uploaded yet. -- $else --